Local File Inclusion Exploitation
Local File Inclusion lets you read arbitrary files the web server process can access. The immediate value is credential extraction from config files, SSH keys, and system files. The follow-on path is escalation to code execution via log poisoning, session injection, or PHP wrappers — covered in LFI to Remote Code Execution.
Confirm the vulnerability with /etc/passwd before targeting anything else. Adjust traversal depth until you get a hit.
Basic Path Traversal
root:x:0:0:root:/root:/bin/bash
If the baseline traversal returns nothing, increment depth. Start at ../../ and go up to ../../../../../. Check response size changes — even a slight difference indicates a successful read that may not print cleanly.
PHP Filter Wrapper for Source Disclosure
The php://filter wrapper reads files as base64 without executing them. This lets you read PHP source files that would otherwise be executed instead of displayed:
<?php $db_host = 'localhost'; $db_user = 'admin'; $db_pass = 'SuperSecret123!'; $db_name = 'webapp';
Source code disclosure from config files frequently contains database credentials, API keys, and internal service addresses. Read the main application files to map further injection points before escalating.
High-Value File Targets
After confirming traversal works, target files likely to contain credentials or intelligence useful for escalation:
Linux target | Value |
|---|---|
/etc/passwd | User list, home directories |
/etc/shadow | Password hashes if readable |
/home/USER/.ssh/id_rsa | SSH private key |
/var/www/html/config.php | Database credentials |
/var/www/html/.env | App secrets, API keys |
/var/log/apache2/access.log | Log poisoning target |
/proc/version | Kernel version |
Filter Bypass Techniques
When basic traversal is blocked, the application is likely stripping or blocking ../ sequences. Try these variants in order — stop when one works:
Warning
Null byte truncation (%00) only works on PHP 5.3.3 and earlier. On modern PHP versions this has no effect.
Automated Fuzzing
Use ffuf with a dedicated LFI wordlist to test all traversal variants against the parameter automatically:
Explain command
| -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt | Wordlist file containing LFI payloads to fuzz with. |
| -u "http://$TARGET_IP:$PORT/index.php?page=FUZZ" | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP | Placeholder for the target host IP address. |
| $PORT | Placeholder for the target port number. |
| -mc 200 | Match only HTTP responses with status code 200. |
| -fs 1234 | Filter out responses with a body size of 1234 bytes. |
Set -fs to the normal response size so only results with different content are shown. Once you have reliable file read, escalate to code execution via LFI to Remote Code Execution.
References
-
PHP — php:// Wrapperswww.php.net/manual/en/wrappers.php.php (opens in new tab)
php://filter and php://input wrapper documentation
-
SecLists — LFI Wordlistsgithub.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI (opens in new tab)
LFI traversal payload lists including Jhaddix and common variants
-
PayloadsAllTheThings — File Inclusiongithub.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion (opens in new tab)
LFI bypass payloads and wrapper-based techniques
Was this helpful?
Your feedback helps improve this page.