Local File Inclusion (LFI)

The Local File Inclusion (LFI) vulnerability allows an attacker to include a file. The vulnerability occurs due to invalid validation of user input which makes it possible, in many cases, to obtain a remote code execution (RCE).

Example

Imagine the following PHP code that includes a file, executes all the PHP code in the included file, and outputs the file content.

The default file default.php contains the following PHP code that simply print the current date for us.

default.php

The attacker can control the GET parameter named page that is being being used in the include(...) function. In case the page parameter isen't presented by the user, the PHP code will include the file default.php instead.
By including an optional file, we can not only retrieve the content of the file, but it will also execute any PHP code presented in the file we specify. As proof, we will start by reading a file from our target.

If we set the value ../../../../../../etc/passwd to the GET parameter page, we will be able to see the content of the file: /etc/passwd (if our target runs a Unix system). If we succeed, the result should look something like below:

Remember that if this file had contained any PHP code, that code would have been executed. If we can upload a file to the server and then specify the path to our upload file in the GET parameter page, it would then allow us to have a PHP code injection.
We may not be able to upload our own file every time, in which case we can take advantage of a known file that we can modify and infect with our payload (PHP code). A good example is the log file, let's imagine that this application uses a proxy like Apache. By infecting a log file with PHP code and then including the infected log file in the GET parameter page, we can achieve a PHP code injection.

The default log file for Apache is: /var/log/apache/access.log and Apache will log the User-Agent header from the client by default. We can send a HTTP request to the application with a User-Agent containing our payload as its value: <?php echo system('id'); ?> similar to the following HTTP raw data:

To trigger the infected PHP code, we now exploit the LFI vulnerability in the GET parameter page by including the Apache log file containing our malicious PHP code as follows:

The response from the application will now give us the result of the executed PHP code (our payload) that we previously infected inside the User-Agent header.

If you want to learn more about LFI and how to defeat protections you can take a look at our practical challenge: