What is Local File Inclusion (LFI)?
Local File inclusion (LFI), or simply File Inclusion, refers to an inclusion attack through which an attacker can trick the web application in including files on the web server by exploiting functionality that dynamically includes local files or scripts. The consequence of a successful LFI attack includes Directory Traversal and Information Disclosure as well as Remote Code Execution.
Typically, Local File Inclusion (LFI) occurs, when an application gets the path to the file that has to be included as an input without treating it as untrusted input. This would allow a local file to be supplied to the include statement.
Local File Inclusion is very much like Remote File Inclusion (RFI), with the difference that with Local File Inclusion, an attacker can only include local files (not remote files like in the case of RFI).
The following is an example in PHP that is vulnerable to Local File Inclusion (LFI).
/**
* Get the filename from a GET input
* Example - http://example.com/?file=filename.php
*/
$file = $_GET['file'];
/**
* Unsafely include the file
* Example - filename.php
*/
include('directory/' . $file);
In the above example, an attacker could make the following request to trick the application into executing a malicious script such as a webshell that the attacker managed to upload to the web server.
http://example.com/?file=../../uploads/evil.php
In this example, the file the uploaded by the attacker will be included and run as the user running the web application. That would allow an attacker to run any code they wanted on the web server.
Directory Traversal
The above example is a worst-case scenario. The reality is that an attacker does not always have the ability to upload a malicious file to the application.
Even if the attacker did have the ability to upload arbitrary files, there is no guarantee that the application will save the file on the same server where the Local File Inclusion (LFI) vulnerability exists. Even then, the attacker would still need to know the path-on-disk to the uploaded file in order to include it in an LFI attack.
Even without the ability to upload and execute arbitrary code however, an Local File Inclusion vulnerability can be very useful for an attacker. An attacker can still perform a Directory Traversal attack using an LFI vulnerability as follows.
http://example.com/?file=../../../../etc/passwd
In the above example, an attacker can get the contents of /etc/passwd file containing a list of users on the server using the Local File Inclusion vulnerability to perform a Directory Traversal attack. Similarly, an attacker may leverage the Directory Traversal vulnerability to gain access to credentials, logs, source code and other sensitive information that may help advance an attack.
Preventing Local File Inclusion (LFI) vulnerabilities
The best way to eliminate Local File Inclusion (LFI) vulnerabilities is to avoid dynamically including files based on user input. If this is not possible, the application should maintain a whitelist of files that can be included in order to limit the attacker’s control over what gets included.
What is a Local File Inclusion (LFI) vulnerability?
Local File Inclusion (LFI) allows an attacker to include files on a server through the web browser. This vulnerability exists when a web application includes a file without correctly sanitising the input, allowing and attacker to manipulate the input and inject path traversal characters and include other files from the web server.
The following is an example of PHP code vulnerable to local file inclusion.
<?php
$file = $_GET[‘file’];
if(isset($file))
{
include(“pages/$file”);
}
else
{
include(“index.php”);
}
?>
Identifying LFI Vulnerabilities within Web Applications
LFI vulnerabilities are easy to identify and exploit. Any script that includes a file from a web server is a good candidate for further LFI testing, for example:
/script.php?page=index.html
A penetration tester would attempt to exploit this vulnerability by manipulating the file location parameter, such as:
/script.php?page=../../../../../../../../etc/passwd
The above is an effort to display the contents of the /etc/passwd file on a UNIX / Linux based system.
Below is an example of a successful exploitation of an LFI vulnerability on a web application:
PHP Wrappers
PHP has a number of wrappers that can often be abused to bypass various input filters.
PHP Expect Wrapper
PHP expect:// allows execution of system commands, unfortunately the expect PHP module is not enabled by default.
php?page=expect://ls
The payload is sent in a POST request to the server such as:
/fi/?page=php://input&cmd=ls
Example using php://input against DVWA:
Request:
Image description: POST request using php://input
Web Application Response:
Image description: The output from the command “ls” is rendered above the DVWA banner.
PHP php://filter
php://filter allows a pen tester to include local files and base64 encodes the output. Therefore, any base64 output will need to be decoded to reveal the contents.
An example using DVWA:
vuln.php?page=php://filter/convert.base64-encode/resource=/etc/passwd
Image description: Image showing the base64 encoded text at the top of the rendered page
Base64 decoding the string provides the /etc/passwd file:
Image description: An image showing the base64 decoded output from /etc/passwd on a UNIX / Linux system
php://filter can also be used without base64 encoding the output using:
?page=php://filter/resource=/etc/passwd
Image description: An image showing the output from /etc/passwd on a UNIX / Linux system using php://filter
PHP ZIP Wrapper LFI
The zip wrapper processes uploaded .zip files server side allowing a penetration tester to upload a zip file using a vulnerable file upload function and leverage he zip filter via an LFI to execute. A typical attack example would look like:
1. Create a PHP reverse shell
2. Compress to a .zip file
3. Upload the compressed shell payload to the server
4. Use the zip wrapper to extract the payload using: php?page=zip://path/to/file.zip%23shell
5. The above will extract the zip file to shell, if the server does not append .php rename it to shell.php instead
If the file upload function does not allow zip files to be uploaded, attempts can be made to bypass the file upload function (see: OWASP file upload testing document).
LFI via /proc/self/environ
If it’s possible to include /proc/self/environ via a local file inclusion vulnerability, then introducing source code via the User Agent header is a possible vector. Once code has been injected into the User Agent header a local file inclusion vulnerability can be leveraged to execute /proc/self/environ and reload the environment variables, executing your reverse shell.
Useful Shells
Useful tiny PHP back doors for the above techniques:
<? system(‘uname -a’);?>
Null Byte Technique
Null byte injection bypasses application filtering within web applications by adding URL encoded “Null bytes” such as . Typically, this bypasses basic web application blacklist filters by adding additional null characters that are then allowed or not processed by the backend web application.
Some practical examples of null byte injection for LFI:
vuln.php?page=/etc/passwd
vuln.php?page=/etc/passwd%2500
Truncation LFI Bypass
Truncation is another blacklist bypass technique. By injecting long parameter into the vulnerable file inclusion mechanism, the web application may “cut it off” (truncate) the input parameter, which may bypass the input filter.
Log File Contamination
Log file contamination is the process of injecting source code into log files on the target system. This is achieved by introducing source code via other exposed services on the target system which the target operating system / service will store in log files. For example, injecting PHP reverse shell code into a URL, causing syslog to create an entry in the apache access log for a 404 page not found entry. The apache log file would then be parsed using a previously discovered file inclusion vulnerability, executing the injected PHP reverse shell.
After introducing source code to the target systems log file(s) the next step is identifying the location of the log file. During the recon and discovery stage of penetration testing the web server and likely the target operating system would have been identified, a good starting point would be looking up the default log paths for the identified operating system and web server (if they are not already known by the consultant). FuzzDB’s Burp LFI payload lists can be used in conjunction with Burp intruder to quickly identify valid log file locations on the target system.
Some commonly exposed services on a Linux / UNIX systems are listed below:
Apache / Nginx
Inject code into the web server access or error logs using netcat, after successful injection parse the server log file location by exploiting the previously discovered LFI vulnerability. If the web server access / error logs are long, it may take some time execute your injected code.
Email a Reverse Shell
If the target machine relays mail either directly or via another machine on the network and stores mail for the user www-data (or the apache user) on the system then it’s possible to email a reverse shell to the target. If no MX records exist for the domain but SMTP is exposed it’s possible to connect to the target mail server and send mail to the www-data / apache user. Mail is sent to the user running apache such as www-data to ensure file system permissions will allow read access the file /var/spool/mail/www-data containing the injected PHP reverse shell code.
First enumerate the target system using a list of known UNIX / Linux account names:
Image description: The above image uses the smtp-user-enum script confirming the www-data user exists on the system
The following screenshot shows the process of sending email via telnet to the www-data user:
Image description: The above image shows the process of sending a reverse PHP shell via SMTP using telnet
Image description: The above image shows the inclusion of www-data mail spool file containing the emailed PHP reverse shell code
Image description: The above image shows the emailed PHP reverse shell connecting to a netcat listener
No comments:
Write comments