lfi-file-inclusion
Local File Inclusion (LFI)
In modern web application, in order to generate dynamic content, developers uses parameter page loading like index.php?page=about. where index.php sets static content and pulled the dynamic content specified in the parameter, which may be read from a file called about.php.
How to find LFI vulnerability
We should look for such URLs which take filename as parameters http://vulnerable_site/preview.php?file=example.html
Bypass methods overview
Link of techniques
Testing_for_Local_File_Inclusion
Null byte Injection
If .php extension is appended we can use Null byte Injection
http://vulnerable_host/preview.php?file=../../../../etc/passwd%00PHP file limit of 4096 bytes
PHP drops when the given filename is longer than the length. When this happens not error is triggered
Use Unicode encoding
Use Double encoding
PHP wrappers add some functionality and Remote Code Execution:
PHP filters:
This wrapper can be used to get content of a file preventing the server from execution php://filter/convert.base64-encode/resource=FILE
PHP Zip:
It is used to manipulate zip compressed files
It can be used to upload file and bypass extension restriction
zip:///filename_path#internal_filename
PHP data:
It take base64 encoded content data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==
PHP expect:
It is not enabled by default, provides access to processes expect://command
Using double string (….//)
LFI can lead to:
Source code disclosure
Sensitive data exposure
Remote code execution
Example of vulnerable code
A website may have a ?language GET parameter, if a user change language from the drop-down menu, the ?language parameter would change as well. In such cases, changing the language my change the directory where the web app is loading the pages.
Read/write functions:
PHP
include()/include_once ()
✔️
✔️
✔️
require()/require_once()
✔️
✔️
❌
file_get_content()
✔️
❌
✔️
fopen()/file()
✔️
❌
❌
NodeJS
fs.readFile()
✔️
❌
❌
fs.sendFile()
✔️
❌
❌
res.render()
✔️
✔️
❌
Java
include
✔️
❌
❌
import
✔️
✔️
✔️
.NET
@Html.Partial()
✔️
❌
❌
@Html.RemotePartial()
✔️
❌
✔️
Response.WriteFile()
✔️
❌
❌
include
✔️
✔️
✔️
File Disclosure
Web application preventions
Common files to read
Back-end Scenarios (it depends upon the web server coding style)
When the whole user input is include (include(
$_GET['language']);) Absolute path /etc/passwdWhen the only string appended
[parm value](include("./languages/" . $_GET['language']);) Relative path ../../etc/passwdFilename prefix is used
(include("lang_" . $_GET['language']);)Relative path../../etc/passwdAppended extensions
(include($_GET['language'] . ".php");)Absolute path/etc/passwdAdvance attack (second-order attacks)
This attack occurs many web applications functionalities may be insecurely pulling file from the back-end server based on user-controlled parameters.
When a web application tries to download our avatar through URL like
/profile/$username/avatar.png
Basic Bypasses
Non-recursive path traversal filters:
One of the most basic filters against LFI is a search and replace filter, where it simply delete substring of (../) to avoid path traversal. Example: $language = str_replace('../', '', $_GET['language']);
How do I bypass it
This filter is not recursively deleting ../ string we can use double string ….// ….//
Encoding:
URL encoding
Approved paths:
Only accepts specific paths under, let's say, ./language directory How do I bypass it We may start our payload with the approved path, and then use ../ to go back to the root directory and read the file we specify ?language=./language/../../../etc/passwd
Combine any two or more bypass techniques
Appended extension
We may not be able to bypass it, there are couple of techniques but they only works with PHP version before 5.3/5.4 Path truncation: In earlier version of PHP, strings have maximum length of 4096 characters, due to limit of 32-bit systems. Any text after the max length will be ignored. Linux general, also disregard multiple slashes in the path. Payload:
Null bytes
PHP version before 5.5 were vulnerable to null byte injection, anything after a null byte (%00) will not consider. (This is how strings are store in low-level memory, null byte indicate the end of string in memory) /etc/passwd%00.php
PHP filters
PHP filters are a type of PHP wrappers, where we can pass different types of input and have it filtered by the filter we specify. These filters/wrappers can used to read restricted source code or local files.
Input filters
Filter wrapper has several parameters:
Resource
Read
e.g.,
php://read/.
Different types of filters
String filters
Conversion filters
Compression filters
Encryption filters
Fuzz for PHP files (first step)
FUZZ for different available PHP pages
Dir: directory-list-2.3-small.txt
URL:
http://target/FUZZ.phpObtain a list of files to read e.g.
config.php
Standard PHP inclusion (LFI with appended PHP extension)
If we try to access config file as it just a configuration. it is executed and not show in the html page, so we will use PHP base64 wrapper/filter to encode the file content and show on the browser instead of execute.
Remote file Inclusion (RFI)
RFI is usually disabled by default as it dangerous practice. Any remote URL inclusion in PHP would require the allow_url_include settings to be enabled.
Verify RFI
In this page
RCE > check php configuration > check
It is always best practice to start with local file e.g.
http://<SERVER_IP>:<PORT>/index.php?language=http://127.0.0.1:90/index.php
[[CPTS Notes/04 Web Exploitation/LFI/RCE|RCE with RFI]]
Automated Scanning
It is essential to understand how LFI & RFI attacks work and how we can manually craft advanced payloads and use custom techniques to reach remote code execution.
Fuzzing parameters
Fuzz for exposed parameters
LFI wordlists
Once we have identified payloads, we should manually test them to verify that they works as expected.
Fuzzing server files
Depending on our LFI situation, we may need to add a few back directories(eg. ../../../../).
Server Webroot
Wordlist for Linux
Wordlist for windows
We can also use LFI-Jhaddix.txt file here
Server logs/configurations
I need to able to identify the correct logs directory to be able to perform the log poisoning attacks.
We may use LFI-Jhaddix.txt file
After the scan is complete and got results
Try to access files
LFI tools
lostsec.py
File Inclusion prevention
Do not include user controlled input into any file inclusion function.
Prevent directory traversal by using programming language built-in tools to pull only the filename.
Sanitize user input to recursively remove any attempts to traversing directories.
Web server configuration (allow_url_fopen and allow_url_include to off)
Install web application firewall (WAF)
Last updated