[PHP] File inclusion vulnerability

Preface


A file inclusion vulnerability is a type of vulnerability that is most commonly found to affect web applications that rely on a scripting run time. This issue is caused when an application builds a path to executable code using an attacker-controlled variable in a way that allows the attacker to control which file is executed at run time. If a file contains this loophole ot often was implemented in the development stage for convenience. Because it is often used in development and later forgotten, it has become the target of multiple attacks and has resulted in a variety of file-based attacks.

Local file inclusion


First of all, when the value can directly be be controlled we have a very similar code snippet as below present:

<? php
$ file = $ _GET ['file'];
include ($ file);

If we can find the above code, there is a directly included $file, which we have control over.

Note: The file can be anything. It is included no matter if it’s an exptected file type, a picture, or anything arbitrary.

First of all in the current folder create an arbitrary file with any suffix, such as: file.txt (even if it is a picture format like file.jpg then the following effect takes place).
Set the contents of the file as:

<? php
phpinfo ();

File Inclusion Vulnerabilities also contain other files within the current server while supporting directories that contain web applications, as follows:
Try to include some of the contents of your HDD for example: C:\WINDOWS\system.ini

If we do this, we can see that the contents of any file will be outputted to the browser.

This only works if we have total control and the file type is not further specified.
So what can we do if the code snippet changes to this:

<?php
	$file = $_GET['file'] . '.php';
	echo $file;
	include($file);

In this case, we can try to follow the method above:
This will result in an output like this:

We can see that if the suffix is fixed, then just like in the figure above, we will not find the file we included earlier.
The searched for filename is: ./Include.txt.php.


So here’s another way to do that: %00 truncates a string upon reaching.
This trick is widly spread and used in different areas as well.
I won’t go into any more detail here .
I recommend checking out online ressources like this!

Using %00 in PHP:

  1. PHP version <5.3 (excluding 5.3);
    PHP magic_quotes_gpc = off;
    PHP does not use the addslashes function for the received parameters, such as `$ _GET [‘file’] in the above code

In PHP version 5.3 or later this issue has been fixed.
The sequence will be correctly escaped if gpc is turned on or the addslashes function is used.
First of all, we can try what happens if the gpc is turned on (the effect is the same as using the function)

We can directly see how this case is handled if we enable the gpc flag.

Next we take a look at the situation in 5.3:


There is no noticeable effect here either.

So we can see that as long as the above three conditions are satisfied, %00 can be used.
First we change the PHP version to 5.2 and restart Apache after php.ini changes magic_quotes_gpc = on to magic_quotes_gpc = off.
This enables us to use truncation when attempted.

We can see that we have successfully made use of truncated inclusion.
So does the file only contain the included functions?
That is certainly not the case, since we have control of what can be included let’s do this :wink: .
Let’s create a file: shell.txt to further exploit this vulnerability.

We can see, including shell is not a problem either.

So what is the difference between the two? In fact, there is no difference, the principle is the same, but the first is introduced with the suffix, the second is fixed in the program dead suffix. But % 00 can be used because it terminates directly when the program stream encounters% 00 terminator.

remote file inclusion


The local file contains the same principle as the remote file, except that the former can only contain the files that exist on the server, and the latter can contain the files on the remote server.

For remote files we need to consider the following:

  1. Need allow_url_include = on and allow_url_fopen = on in php.ini
  2. The required remote file suffix cannot be the same as the target server’s language, such as (the target server parses PHP code, then the remote file suffix can not be .php)

Let me explain the second point.
If your remote file has .php suffix and your remote file content is something like:

<? php
phpinfo ();

Then the contents of the target server are obtained after your remote server executes phpinfo()
It will not run the code, so the information contained is not the target server but your remote server.

This is illustrated below:

This is my remote machines information for PHP5.6 version, the target machine is version 5.2.
Next we include the file!

We can see that after the file is included, our remote machine changed! why??
Because the target server does not contain the this code:

<? php phpinfo ();?>

Instead, the remote server executes the source code of this code, as shown below:

So to make this attack work we need to make a few modifications:

1.Modify the configuration

2.Modify the file suffix

Let’s try the include attack vector again:

We can see the desired information got returned after this inclusion and our target machine information did not change anymore.

Next up we want to do the shell example again for the remote file inclusion

Remote file contains the use of the premise is in line with the local file contains the premise and meet the remote file contains the premise of its availability.

File contains on of many pseudo-protocols


There can be quite a few different pseudo-protocols contained in a file.
I’ll demonstrate a few of them below.

data:text/plain or data: text/plain; base64
php://input
php://filter
file://
zip://

Other protocols can looked up in the official documentation

data:text/plain

Output is directly in the corresponding URL showing the parameters: data:text/plain.
Then we need to execute the php code as shown below:

data: text/plain; base64

For data: text/plain; base64` there is another way to use it.
We need to execute PHP code using base64 encoding: the base64php code is as shown below:


php://input

php://input accesses the read-only stream of the requested raw data, executing the data in the post request as PHP code.

You can see that the program has automatically an added .php suffix.
Hence using include php://input will automatically add .php so it is certainly not working properly.
We can come back to the nifty little %00 trick to truncate the file path!

You can see the terminator is very powerful.


php://filter

php://filter can read the php file code base64 encoded output and return it to us.
For example, we want to read a php file but do not want it to be normal php.

Usage: php://filter/read=convert.base64-encode/resource=
../ressource= needs to read the contents of the file code

After decoding the base64 we can get the contents as usual:


file://

file:// is used to access the local file system and is not affected by allow_url_fopen or allow_url_include.

Usage: file://absolute/path/to/file


zip://

zip:// can access the files in a zip file. But it needs an absolute path.

Usage: zip://[archive absolute path] # [compressed file name]

Create a file locally and compress it into a zip archive.

You can see that I have already filled in the absolute path and the name of the file.
Why we cannot include it successfully shows the error:

Warning: include (zip://C:/phpStudy/WWW/include/phpinfo.zip.php)

We do not want to include this file, instead we want to include the file inside the zip!
Why is the value after # gone?
Because # will ignore the parameters behind it, so we need to use the %23 in the form.
Another point is that the included file ends in a .php, but we compressed the file for the php suffix.
So we do not need to have this suffix, as shown below:

PS:My English is not good, please understand!

10 Likes

Hope to make friends in the community, exchange and study together!

1 Like

i see Chinese chopper ;)

I remember publishing a paper about this back in 2006, or maybe it was earlier. I am still surprised to see these kinds of exploits in the wild. nice coverage of this kind of exploit.

ingilizcem yetmiyor güzel döküman da sikcem ya translate bi bok anlatamıyor


EDIT: English translation (from Turkish) by @oaktree:

I do not have enough english to translate a good document

Yes, that’s right. Haha!

Sorry, you can try Google Translate

In fact, there are many ways to use this attack

php5.3以下已经不多见了,不过还是谢谢分享,学到了


EDIT: English translation (from Chinese) by @ricksanchez:

PHP version 5.3 is kinda rare nowadays but thank you for sharing it. I learned something :slight_smile:

Thank you. We can learn from each other.

I am also Chinese, do not understand English, reluctantly understand the meaning of the forum by translation software, do not know how this forum can whisper these gods. I need the help of the Great God.

Ah yes we all need help of great god, meaning and understand from forum of translations is the key to unlocking chinese to english conversion softwares

你也是中国人吗?我们中国人口就是多哈哈。

我很自豪的英国人,从西方不是中国人:(但我相信伟大的上帝!

哈哈,可以问一句你的黑客技术牛逼吗?善意的提问哈。

这个对话最适合IRC。 请随时查看,irc.0x00sec.org