June 21, 2026
From Hydra to RCE: Breaking Down TryHackMe’s Support Machine
❤️بِسْمِ اللهِ والصَّلَاةُ وَالسَّلَامُ عَلَى رَسُولِ اللهِ
Ahmed Hamed
8 min read
❤️بِسْمِ اللهِ والصَّلَاةُ وَالسَّلَامُ عَلَى رَسُولِ اللهِ
Introduction & Overview:
Welcome, fellow hackers! Today, we are going to dive deep into a very interesting Medium-rated web challenge on TryHackMe called Support.
The description given by the platform sets a realistic scenario for an internal corporate tool:
"A new internal Support Operations Platform has been deployed to assist IT and helpdesk teams. The application handles user management, internal APIs, and system-level operations. However, security was not the primary focus during development. Several features rely on user-controlled input and weak trust boundaries. Can you pentest the platform and escalate your access to achieve RCE on the server?"
Our mission is to start from zero (unauthenticated) and walk through a chain of vulnerabilities: Brute Force -> Cookie Tampering (Insecure Deserialization/Logic Bug) -> IDOR -> LFI -> and finally, a clever WAF/Whitelist Bypass to get Command Injection (RCE).
Grab your coffee ☕, and let's start the journey!
Phase 1: Reconnaissance & Enumeration:
Every successful intrusion starts with gathering data. We started by firing up our trusted Nmap scanner from our Parrot OS terminal to see what ports are listening on the target IP (10.114.141.119).
nmap -sC -sV 10.114.141.119nmap -sC -sV 10.114.141.119Nmap Result Analysis:
The scan finished quickly and revealed two open ports:
- Port 22/tcp: Running OpenSSH 9.6p1 (Ubuntu).
- Port 80/tcp: Running an Apache web server 2.4.58.
Since port 80 is active, we immediately opened our browser to inspect the website, but we also started a directory brute-forcing tool called Gobuster to uncover hidden files or folders that aren't linked on the main page.
gobuster dir -u http://10.114.141.119/ -w /usr/share/wordlists/dirb/common.txt -x php,txt,htmlgobuster dir -u http://10.114.141.119/ -w /usr/share/wordlists/dirb/common.txt -x php,txt,htmlGobuster Result Analysis:
Gobuster found some extremely interesting endpoints:
/index.php(Status 200) - The main login portal./dashboard.php(Status 302) - Redirects us because we aren't logged in./config.php(Status 200) - Returns a blank page (size 0), meaning it's a backend script./api.php(Status 302) - Redirects to index.
Phase 2: Initial Access (The Hydra Approach)
When we browse to the root page, we are greeted with an Employee Authentication portal titled Support Operations Panel. The page asks for a Corporate Email and a Password.
Right at the bottom, there is a small hint left by the developers: Problems signing in? Contact IT Operations @ help@support.thm.
Bingo! We have a valid target email: help@support.thm. Since we don't have a password, it's time to perform a dictionary attack using Hydra and the famous rockyou.txt wordlist.
We captured the login request structure and formed our Hydra command:
hydra -l help@support.thm -P /usr/share/wordlists/rockyou.txt 10.114.141.119 http-post-form "/:email=^USER^&password=^PASS^:Invalid credentials" -V -fhydra -l help@support.thm -P /usr/share/wordlists/rockyou.txt 10.114.141.119 http-post-form "/:email=^USER^&password=^PASS^:Invalid credentials" -V -f
After testing a few common words, Hydra successfully found the valid password match:
- Email:
help@support.thm - Password:
snoopy
Phase 3: Privilege Escalation via Cookie Tampering
We used our newly found credentials (help@support.thm:snoopy) to log into the portal. The application authenticated us successfully, but we realized that our privileges were very limited. We were logged in as a basic Helpdesk User, and all we could see was a simple message saying "Ticket management system".
As security researchers, the first thing we do after logging into an app is intercept the traffic using Burp Suite and examine the Cookies.
When looking at our session request, we noticed a very peculiar cookie named: isITUser. The value of this cookie was a long 32-character hexadecimal string: 68934a3e9455fa72420237eb05902327.
This string format looks exactly like an MD5 Hash. Let's try to crack it using an online database like CrackStation.
The hash decrypted perfectly into the string: false. Ah! The developer made a huge logical flaw here. The application checks if the user belongs to the IT/Admin team by looking at the isITUser cookie. If the MD5 hash equals "false", you are treated as a regular user.
So, what happens if we change it to true? Let's use CyberChef to generate the MD5 hash for the word true.
- Input:
true - MD5 Output:
b326b5062b2f0e69046810717534cb09
Now, we go back to Burp Suite Repeater, replace the old cookie value with our new true MD5 hash, and send the request.
Boom! The web page changed completely. A new green container appeared on the screen: IT Admin Panel with a button named View API. We just bypassed the authorization barrier!
Phase 4: API Exploitation & IDOR
Clicking on the View API button redirects us to /api.php. However, trying to access /api.php directly in the browser gives us an "Access Denied" message because it expects specific parameters or proper routing context through the dashboard.
Let's look closely at how the application handles the API requests inside Burp Suite. When the dashboard queries the API, it calls the endpoint with our current user profile path, showing: GET /api.php/user/2 (or via parameters).
When we send this request for our own account ID, the API returns a JSON response containing our account metadata:
{
"email": "help@support.thm",
"2FA": false,
"admin": false
}{
"email": "help@support.thm",
"2FA": false,
"admin": false
}
This endpoint looks vulnerable to IDOR (Insecure Direct Object Reference). The application does not check if the logged-in user actually owns or is allowed to view other IDs. It just blindly takes the ID from the input and fetches the data.
Since our account ID was 2 or 3, let's change the parameter to look for the absolute administrator account, which is traditionally assigned to ID 1.
We changed the request endpoint to: GET /api.php?id=1
Success! The API responded with the highly sensitive details of the administrator account:
- Email:
specialadmin@support.thm - Admin Status:
true
Now we have our primary target email for the full Admin escalation!
Phase 5: Local File Inclusion (LFI) & Code Analysis
Now that we have the administrator's email (specialadmin@support.thm), we need their password. Going back to our initial enumeration, remember that the footer contained a Theme Selector that passes values to a parameter named ?skin=.
This design pattern is a classic indicator of a potential Local File Inclusion (LFI) vulnerability. Developers often take the input from such parameters and pass it directly into functions like PHP's include() without proper sanitization.
Let's test this by trying to read the source code of the current application files. Our first target is to inspect index.php to understand how the login authentication logic works behind the scenes.
If we try to inject a path directly like ?skin=index.php, it might fail if the server adds extensions automatically. By trying a few variations, we discovered that dropping the extension works perfectly because the backend automatically appends .php to our input!
URL: http://10.114.141.119/dashboard.php?skin=../indexURL: http://10.114.141.119/dashboard.php?skin=../index
Analyzing index.php:
Looking closely at the extracted source code of index.php, we can see two critical pieces of information:
- It includes a database configuration file located outside the web root at
/var/www/db.php. - It loops through a
$usersarray and checks credentials directly against plaintext parameters.
Let's look for a configuration file within the current directory first to see if there are any global variables or master keys defined. We tried accessing ../config:
URL: http://10.114.141.119/dashboard.php?skin=../configURL: http://10.114.141.119/dashboard.php?skin=../config
Bingo! config.php exposed a highly interesting variable:
$MASTER_PASSWORD = 'support@110';$MASTER_PASSWORD = 'support@110';Phase 6: Extracting the Database Schema
With the master password support@110 in hand, we still need to verify how it maps to the administrator account. According to the index.php source code we found earlier, user details are stored in /var/www/db.php.
Let's try to leverage our LFI vulnerability to read /var/www/db.php. Since the application automatically appends .php, we can use path traversal relative to the web directory (/var/www/html/):
URL: http://10.114.141.119/dashboard.php?skin=../../../../var/www/dbURL: http://10.114.141.119/dashboard.php?skin=../../../../var/www/db(Note: If the application strictly enforces paths or wraps them tightly, we can also use the kinky PHP filter trick php://filter/convert.base64-encode/resource=../db to dump it as Base64, but a clean traversal path does the job beautifully here!)
Let's look at what the backend database code actually contains.
Great, now that we have the password, let's log into the admin account.
:NOTE
After extracting the $MASTER_PASSWORD = 'support@110'; from config.php, I immediately tried to log into the application with the administrator's email (specialadmin@support.thm). However, the login failed!
Realizing that the developer might have implemented a Password Mutation or formatting modification for the admin account, I closely analyzed the password structure. I decided to strip the special character (@) from the string, modifying it from support@110 to support110.
Trying the mutated password worked like a charm! This successfully authenticated us into the administrator session, giving us access to the IT Maintenance Dashboard and unlocking the primary command injection vector.
Capturing the First Flag
After successfully authenticating as an administrator, we are greeted with the admin dashboard, and there is our first flag!
Flag: THM{I_AM_ADMIN999}
Next, we refreshed the page and captured the new request.
Phase 7: Achieving Remote Code Execution (RCE) via WAF Bypass
Once we authenticated successfully as the administrator or inspected the internal administrative functionalities, we uncovered an IT Maintenance Dashboard containing a feature designed to execute system utilities (like checking the system time/date via a sys parameter).
However, when we initially tried to chain commands using standard Linux command separators like a semicolon (;), the application completely blocked us with a harsh error message:
Only date command is allowed.
The developers implemented a strict regular expression or string match filter (WAF) that scans our input. If it detects anything other than a clean date execution context, it drops the request.
The Ultimate Bypass Strategy:
To defeat this restriction, we can exploit how bash interprets alternative command separators. While semicolons (;), symbols like &&, or pipes (|) might be blacklisted or explicitly checked, many poorly written validation filters forget to check for a URL-encoded Newline character (%0a).
In Linux, a newline character instructs the shell to treat the subsequent string as a completely fresh command on a new line!
Let's structure our payload inside Burp Suite Repeater to verify if we can read the server's internal files using the %0a bypass technique. We will send a POST request to /dashboard.php with the following parameter string:
sys=date%0acat /var/www/db.phpsys=date%0acat /var/www/db.php
It worked flawlessly! The server executed the date command, hit our newline character, and then blindly executed cat /var/www/db.php, displaying the complete user array on our screen.
Phase 8: Capturing the Flags
Now that our Remote Code Execution (RCE) chain is fully functional and stable, we can easily navigate the filesystem to collect our rewards.
1. The User Flag
We modified our payload to target the standard home directory location where the user flag is hidden:
sys=date%0acat /home/ubuntu/user.txtsys=date%0acat /home/ubuntu/user.txt
Capturing the Second Flag
Flag: THM{GOT_THE_FLAG001}
Conclusion
This challenge was a fantastic, real-world demonstration of how minor flaws can be chained together to achieve complete system compromise. Security is only as strong as its weakest link; we witnessed how a simple logic bug in cookie handling led to an IDOR, which led to information disclosure, and ultimately allowed us to exploit a loose filter to achieve full Remote Code Execution (RCE).
A big shoutout to the creators of Support for this highly engaging web challenge, and a huge thank you to everyone who followed along with this walkthrough. Keep hunting, keep bypassing, and I'll see you in the next machine!👋🏻🫶🏻