Local File Inclusion

A introduction to one of the most important web attacks.

Date: 26/7/2021

File inclusion as local file inclusion or remote file inclusion is a common vulnerability that affects web applications functionalities. Some sever-side languages are more probable to have this flaws as PHP and JSP as they are normally used to dynamically allocate external scripts. The problem appears when the inclusion logic is not implemented properly, so anyone can include local (lfi) or remote (rfi) files. This vulnerability can make anyone able to include sensitive data from the server within the content of the web page. 

LFI and RFI

To prevent remote files inclusion, setting allow_url_include to 0 will disallow remote resources to interact with the in PHP.

Common Places to Search For

It is very common to find this vulnerability in templates engines, templates will keep web applications the same while you are navigating within the pages, such as headersnavigation bar and footer as dynamic page generator. All pages seems to be the same, just changing the content, when updates needs to be done this way helps a lot turning easier changing multiple pages.

This is why it is common to see URL like /index.php?page=about. Inside the application probably the environment is being taken by the index from places like header.phpabout.php and footer.php to build the entire page.

Places like language ?lang=en can be a good vector of exploration, since the application is probable getting the content from the directory /en/.

Sense it is probably the most common place to find LFI the template engine is not the unique thing that must to be tested. It can be found where the user is allowed to download file, as a example, engine to download the profile photo or a software:

/profile/$user/avata.png

If the user crafts a malicious username, maybe the user can grab other files instead the avatar photo, changing the request:

/profile/../../../../etc/passwd%20avatar.png

Local File Inclusion

LFI is often found in GET parameters, where the content requested will be included from sever-side scripts.

EXAMPLE: We are seeing a web page from a web site of articles. This web site has two options of language that the content can be read, English and Portuguese on e drop down menu to be chosen. Clicking on English the URL that was like:

http://example.com/index.php

So the content from the page changes their language to English. The file inclusion is based on the following PHP code:

include($_GET['lang']);

It is possible to see that there is no type of filter sanitizing the data that could be manipulated, A prove of concept can be done to see if it is possible to include others Linux files like /etc/passwd:

http://example.com/index.php?lang=/etc/passwd

If the application responded as expected the new content will be something like this:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

Almost all examples will be shown using /etc/passwd as a target. If it is possible to do, the page content will contain the file information.

LFI with Path Transversal

The developer will some times specify the absolute path of the directory in the system for when including files is requested.

include("./langs/" . $_GET['lang'].".php");

This statement will include the file present in a specified folder, so including just will not be /etc/passwd possible. The attacker will need to get some folders backward and than try to include the file, all in the same line of code:

http://example.com/index.php?lang=../../../etc/passwd

/langs/etc/passwd - In this situation the basic payload will not work.

/langs/../../../../../etc/passwd - This payload probably works in this scenario.

File As Extension

Another common form that will make it a little harder is when the value will result in a filename but the extension extension is attached while the file is included:

include("lang_" . $_GET['lang'].".php");

So the URL example.com/index.php?lang=en will have the value from the parameter lang attached with a extension to be included. So in this scenario the attacker would have to modify the payload appending a null byte using PHP wrappers.

Null Byte Injection

The null byte is a character with no value that is injected in the final of the payload. Null byte injection is a exploitation technique to bypass types of sanity checking filters. This process can in many cases alter the intended logic of the application engine giving unauthorized access to files. The reason is that the null character is a control character reserved to mark the end of a string, when used, any character after that special byte will be ignored.

Probably this technique will not work when trying to exploit applications PHP version after 5,4.

It is normal to use URL encoded strings like %00 as the null byte ending the payload.

http://example.com/index.php?file=../../../../etc/passwd%00

include("./pages/" . $_GET['file'].".php");

Using this technique to explore a parameter that is not sanitized properly, it will case the web application do to not know where is the true ending of the string because the null byte is interpreted as the end.

Bypassing Filters

Some types of filters can be used to prevent this attacks, it can make harder for who is attacking. No type of prevention will be really efficient because it will be leading with information that can be manipulated by someone, something that is very hard to do is to prevent what someone else will try to exploit the application.

Blacklisting

Some times looking for avoiding common techniques of LFI, some engines can use functions to replace malicious patterns:

$file = str_replace('../',' ', $_GET['page']);

This code shown above would call a function to replace ../ patterns just taking it out

../../../etc/passwd would be replaced to /etc/passwd. The strings has been removed and it results in the usual path and the Path Transversal  will not work.

If a payload is created knowing about this possibility, it is just to create a payload with different patterns looking for bypassing this prevention:

....//....//....//etc/passwd

After the replace function the payload would work as the normal one.

URL Encoding

The use of URL encoding is not good for to bypass filter but it can help trying to make harder to be detected by things as web application firewall, bypassing simple blacklists defenses:

Encoded payload: %2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswd

It is always good to try with double encoded payloads:  

%252E%252E%252F%252E%252E%252F%252E%252E%252Fetc%252Fpasswd

Conclusion

After walking thought this introduction to local file inclusion it is possible to see that this vulnerability comes with much possibilities sense it makes anyone able to open files within the system.

References

OWASP - Testing for LFI.

Hacktricks - File Inclusion.