Web Security Vulnerabilities - Local File Inclusion (LFI)
Table of Contents
- What is Local File Inclusion (LFI)?
- What is the Impact of LFI?
- How to Find LFI?
- How to Test LFI?
- How to Prevent LFI?
- Time to Practice
- Resources
- Conclusion
What is Local File Inclusion?
Local File Inclusion also known as LFI is a web security vulnerability that allows an attacker to include files from the server’s filesystem through a web browser. This occurs when a web application dynamically includes files based on user input without proper validation.
Example:
Consider an application that includes files based on user input using the following URL:
http://example.com/?page=index.php
The application code:
<?php
$file = $_GET['file'];
if(isset($file))
{
include('pages/$file');
}
else
{
include('index.php');
}
?>
In this code, the $file
parameter is used directly in the include
function without any validation. An attacker can exploit this vulnerability by supplying a malicious file path, such as /etc/passwd
, to access sensitive system files:
http://example.com/?page=../../etc/passwd
../../ used to back two directories
This would include the contents of the /etc/passwd
file in the web page, potentially exposing sensitive information.
What is the impact of LFI?
The impact of local file inclusion depends on the server files. An attacker can read or access sensitive files such as configuration files or log files, and potentially achieve Remote Code Execution (RCE) if they can include and execute malicious code.
How to find LFI?
To find LFI vulnerabilities, focus on parameters that allow file inclusion. Some common parameters to test:
page
file
path
include
show
locate
download
view
site
How to test LFI?
After finding parameters that takes files as input, it’s time to test for LFI. There are some steps you can follow to get better understanding of how application handles input file:
Manual
-
Directory Traversal: Attempt to traverse directories to access sensitive files.
/etc/passwd ../../../etc/passwd ../../../../var/www/html/index.php
-
URL Encoding: Encodes characters in the URL.
../../../etc/passwd --> %2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd
-
**Use Null Byte to bypass file extensions: **Use
%00
to terminate file extensions in PHP.../../etc/passwd%00 ../../etc/passwd%00.jpg ../../etc/passwd%00.php
-
**PHP Wrappers: **PHP stream wrappers can help access file contents in alternative formats:
php://filter/convert.base64-encode/resource=index.php
Decode the response to analyze sensitive data.
Another useful wrappers:
-
file:// — Access local filesystem
-
http:// — Access HTTP(s) URLs
-
ftp:// — Access FTP(s) URLs
-
php:// — Access various I/O streams
-
zlib:// — Compression Streams
-
data:// — Data (RFC 2397)
-
glob:// — Find pathnames matching pattern
-
phar:// — PHP Archive
-
ssh2:// — Secure Shell 2
-
rar:// — RAR
-
ogg:// — Audio streams
-
expect:// — Process Interaction Streams
-
-
Log Poisoning: If an application writes user-controlled input into log files, attackers can inject PHP code into log files and
Access the log via LFI:
../../var/log/access.log?cmd=id
-
Obfuscation: Use techniques to disguise the payload
..//..//..//etc/passwd ..%2f%2f..%2f%2f..%2f%2fetc/passwd
Automation
- Use
Burp Intruder
/Gobuster
to fuzz file paths
How to prevent LFI
To prevent Local File Inclusion (LFI) vulnerabilities, the most effective approach is to avoid passing file names via user input entirely. However, if you must pass file names in user input, you can take the following measures:
- Input Validation: Never trust user input. Before including files based on user input, ensure that the input is sanitized and validated to prevent malicious file inclusions.
- Use Whitelists: Maintain whitelists of allowed files that can be included. This approach restricts the files that users can access and helps prevent unauthorized file inclusions.
- Limit File Permissions: Set appropriate permissions for files and directories on the server to restrict access. This helps prevent attackers from accessing sensitive files even if they manage to exploit an LFI vulnerability.
- Error Handling: Disable detailed error messages to avoid exposing sensitive server paths.
By implementing these measures, you can effectively prevent LFI vulnerabilities in your web application.
Time to practice
Now let’s practice on some challenge.
Challenge #1
Challenge available files:
- home.php
- about.php
So, the first challenge that I created is simple as we can see that we are asked to enter a file name.
The website shows an error: Invalid Page
.
Let’s try to access home.php
which is provided in the challenge description.
Now here is Local File Inclusion
comes in, as we have parameter called file
and it takes file name, It may be vulnerable to LFI. Let’s try accessing files on the server, like /etc/passwd
.
We can see the contents of the /etc/passwd
file, indicating an Local File Inclusion vulnerability.
Challenge #2
In the second challenge, we are asked to enter a file path.
Attempting to access index.php
yields an error, indicating the file path should start with /var/www/html/
.
Let’s try to access index.html
with the required path results in a file not found error.
The page
parameter may be vulnerable to LFI. We attempt to escape the /var/www/html/
directory.
The page
parameter may be vulnerable to LFI. So, the first step to access files on the server is to escape from the required directory /var/www/html/
.
Step-by-step directory traversal reveals we can escape only up to the /html/
directory.
We can use obfuscation techniques to bypass validation. Some applications block ../../../../
, but may not recognize ..//
. Both ../
and ..//
move up one directory level, but ..//
obfuscates the payload.
Obfuscation in the context of security exploits refers to the practice of disguising or altering an attack payload to bypass security mechanisms such as filters or intrusion detection systems. By modifying the appearance of the payload, an attacker can sometimes evade basic security checks that look for well-known patterns or strings associated with attacks.
By bypassing directory restrictions, we can read files on the server.
Challenge #3
Third Challenge is provided from rootme, the goal is to find a password in a file on the server.
The website has two pages: CV
and Contact
.
If we try to access any of them, we can observe that there is a page
parameter with file name as value. So, the first thing we can try is testing for Local File Inclusion
.
If we try to access /etc/passwd
, it shows us the following error:
Let’s back to test each character to determine what cause this error. When we try to go back one directory using ../
it shows us the same error.
So, the website filter using ../
. Let’s intercept the request to burp and try to bypass this filter using URL encoding.
We can see above, this is not working, but double URL encoding is working.
If we try to access any file, we can observe that the file name is concatenated to $filename.inc.php
.
So, we can try to access /etc/passwd
and bypass the reset of filename using nullbyte
technique, but it’s not working here.
So, we can think of another approach to access the source code of files. We can try PHP wrapper.
PHP wrappers are used to encode different PHP streams. Whenever you access a webpage the data is sent to you as a stream as opposed to downloading the entire file first before opening it. A wrapper can be used to tell the stream how to handle specific protocols encoding. So instead outputing the output with its default encoding a wrapper can be used to encode the stream with say base64 encoding instead. This post will focus on using PHPs base64 encode wrapper.
We can use PHP wrapper as it encodes the source code. The server does not interpret the file but instead outputs the encoded stream instead. As we know the default page in the challenge is home
so let’s try to access it’s source code.
We can see above the server respond with base64 encoded source code, so let’s decode it using CyberChef
.
We can see there is a hidden file called conf.inc.php
. and as we know that the filename ends with .inc.php
, so let’s try to access it using PHP wrapper.
We can see above the server respond with base64 encoded source code successfully, so let’s decode it using CyberChef
.
Finally we get the flag.
Resources
Conclusion
In conclusion, LFI are a serious security issue that can allow attackers to take full control of a web server. Developers and Administrators should take steps to prevent these types of attacks by implementing proper security measures and best practices.
Hope you enjoy this guide! Thanks for reading.