Exercise: Enumeration and privilege escalation on Traverxec

An nmap scan shows that ports 22 and 80 are open:

22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u1 
    (protocol 2.0)

80/tcp open http nostromo 1.9.6
|_http-favicon: Unknown favicon MD5: 
    FED84E16B6CCFE88EE7FFAAE5DFEFD34
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-server-header: nostromo 1.9.6
|_http-title: TRAVERXEC
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

The web server is Nostromo version 1.9.6. Looking at the exploit database we find a number of potential vulnerabilities with this version. Before looking at the exploits however, we should look at the website itself.

Going to the home page, we find a site of David White who is a web designer.

Home page of Traverexec

Looking at the web page, there is little functionality enabled and so we can go back to the vulnerabilities of the webserver Nostromo. If we do a searchsploit of nostromo, we find the following:

The vulnerability is CVE-2019-16278 and is an unauthenticated remote code execution exploit due to the website allowing path traversal. If we look at the Python code by making a local copy of the file:

The key part of the code that runs the exploit is the method cve:

In this method, the script is doing an HTTP POST to a path that is "/.%0d./.%0d./.%0d./.%0d./bin/sh". The Nostromo code checks for paths in the URL but because of the addition of the carriage return character %0d, it does not think that this is a path. The %0d is removed by a later function making the path "/../../../../bin/sh" and this is then executed with the body of the POST as the argument.

We can use this script to run the same bash reverse shell we ran in Traceback after setting up a netcat listener (note that you may have to change the code slightly to get it to run with Python 3, encoding the payload: soc.send(payload.encode()):

We then get a reverse sehll on the box:

Now that we are on the box, we can run LinPEAS by getting it using our local Python web server. The machine is running Debian Buster and there are two users with login, root and david. The key thing LinPEAS finds is a password hash that is stored in a .htpasswd file:

We can try and crack the hash with John The Ripper. John detects that the hash is md5crypt and cracks the password as Nowonly4me:

If we go into the /var/Nostromo/conf directory, we can see that there is a configuration file for Nostromo nhttpd.conf, which when we examine, has declared support for home directories:

This allows support for people running personal web pages which are of the URL format http://traverexec.htb/~user/. We know that there are two users, root and david. For root, we get a 404 but for david we get a page shown here:

Home page of user david at http://traverexec.htb/~david/

When we try and list the contents of /home/david, we get Permission denied as we have execute but not read permission:

From the Nostromo configuration file, we know that the web page for a home directory is in the directory public_www so we can enter that directory and list the contents:

Looking at the directory ./protected-file-area we find an .htaccess file and a file called backup-ssh-identity-files.tgz

Looking at the .htaccess file, we get the contents

The .htaccess file is a simple way of restricting access to a directory and require basic authentication of a user on the box. When we try and go to the URL http://traverexec.htb/~david/protected-file-area/ we get presented with the dialog box and can use the david as the username and Nowonly4me as the password.

Basic authentication dialog box when navigating to http://traverexec.htb/~david/protected-file-area

Once we get through the dialog, we get the contents of the directory listed. We can download the file by right clicking and saving the link.

Contents of http://traverexec.htb/~david/protected-file-area

The file is in a compressed tar format and we can expand the contents using:

Going into the directory ./home/david/.ssh and looking at the id_rsa key file, we see that it is encrypted

And sure enough, when we try and use it to SSH using the user david, we get prompted for a password. The password we used for the web page doesn't work however. Nor does it work when using it as david's actual login password. We can try and crack the id_rsa key by using ssh2john.py which will extract a password hash from the SSH key in a format that John understands:

Again, we can then crack this with John The Ripper:

When we try and SSH now and use the password hunter, we get in!

As a starting point of our enumeration, it is always a good idea to start with the home directory and if we list david's directory, we get

The .bash_history is a symbolically linked file to /dev/null which is a special file that discards any content written to it. This is done on Hack The Box so that there is no persistent history of the user's commands. There is the the .ssh directory and the public_www directory we have already looked at but there is a new directory ./bin. The directory has two files; server-stats.head and server-stats.sh with the following content:

The interesting part of this is the sudo command running the program journalctl. This is a program that interacts with journald a daemon (service) that manages the journals (logs) generated by systemd on a Linux system. The script is displaying the contents of server-stats.head, then doing the "uptime" command which shows the current time, how long the system has been running and the number of users logged onto the system. The ss command will list the open sockets connected to the web server on port 80 and then count the number of lines in the output using wc -l. Finally, the sudo command is running journalctl which is listing the last 5 entries of the logs for the web server nostromo.service.

Since we can run journalctl using sudo, we can look at GTFObins and find that journalctl uses less when the content is longer than a single page. Less is a program on Linux that will break content into pages and allows vi commands to search for content as well as dropping into an interactive shell with !/bin/sh command. Journalctl does not drop the sudo privileges when running less and so it is possible to drop to an elevated shell very simply by running:

Last updated

Was this helpful?