Wednesday, November 12, 2014

Metasploit: Getting outbound filtering rules by tracerouting

Deciding between a bind or reverse shell depends greatly on the network environment in which we find ourselves. For example, in the case of choosing a bind shell we have to know in advance if your machine is reachable on any port from outside. Some time ago I wrote how we can get this information (inbound filtering rules) using the packetrecorder script from Meterpreter. Another alternative is to use a IPV6 bind shell (bind_ipv6_tcp). The idea of this payload is to create an IPv6 tunnel over IPv4 with Teredo-relay through which it will make the bind shell achievable from an IPv6 address. You can read more info about this in the post: Revenge of the bind shell

On the other hand, in the case of using a reverse shell, we must know the outbound filtering rules of the organization to see if our shell can go outside. In most situations, we usually choose 80 or 443 ports since these ports are rarely blocked for an ordinary user. However, there are cases in which we have a much more restrictive scenario. For example, if we get access to a server from an internal network and want to install a reverse shell from that server to the outside, maybe outgoing connections on ports 80 and 443 are denied. The reverse_tcp_allports() payload was created to work in such environments. This payload will attempt to connect to our handler (installed on certain external machine) using multiple ports. The payload supports the argument LPORT by which we specify the initial connection port. If It can not connect to the handler it will increase the port number 1 by 1 until a connection is done. The problem with this approach is that it is very slow due to timeouts of blocked connections. In addition, much noise is generated as a result of each of these connections.
Because of the need to know which outgoing ports are allowed, I have made a post-exploitation Meterpreter module that allows you to infer TCP filtering rules for the desired ports. At first I thought to use the same logic as the MetaModule "Egrees Firewall Testing" built into Metasploit Pro v4.7. This MetaModule allows you to get outbound rules by sending SYN packets to one of the servers hosted by Rapid7 ( The server is configured to respond to all ports (all 65535 ports are open), so if your host receives a SYN/ACK you can deduce that certain port is not filtered. This service is similar to  which I have used sometimes, usually on linux machines, to know the filtering policies of the organization in which I am doing a pentest.

However, I did not like the idea of depending on a particular external service. Moreover, while it would be easy to prepare a machine with a couple of Iptables rules I still found it a bit cumbersome.

After shuffling some options, I ended up creating the outbound_ports.rb module for Windows which does not depend on any service or external configuration. The module is a kind of traceroute using TCP packets with incremental TTL values. The idea is to launch a TCP connection to a public IP (this IP does not need to be under your control) with a low TTL value. As a result of the TTL some intermediate device will return an ICMP "TTL exceeded" packet. If the victim host is able to read that ICMP packet we can infer that the port used is not filtered. By default, the TTL will start with a value of 1 although this can be changed with the parameter MIN_TTL. With HOPS we indicate the number of peers to get. Personally I tend to use a low value since all I need is to get an ICMP response from a public IP. The module will also have the TIMEOUT parameter to set the waiting time of the ICMP socket.

In the following example I've used the public IP to check if the outbound connection to ports 443 and 8080 are filtered. As shown, we have obtained several ICMP replies from different routers; so now we know that those ports would be good candidates for our reverse shell.

You can play around with the HOPS and MIN_TTL options. For example, if you do not want to create so much noise you can set an initial TTL of 3 and set the number of hops to 1. In that case, and unless the organization has a complex network, you could receive a quick response from an external IP. Another alternative is to set the STOP option to true. Thus, when a public IP responds with an ICMP packet, the script will not continue launching more connections.

As you can tell, the module will also be useful to infer the network topology of our target; working in the same way that a "traceroute". Internally, the module will use two sockets, first a TCP socket in non-blocking mode. This socket will be in charge of launching SYN packets with different TTL values (set with the setsockopt API and the IP_TTL option).

On the other hand, a raw ICMP socket will be needed to read the ICMP responses. Since Window's firewall blocks this type of packets by default the module will use netsh to allow incoming ICMP traffic.

For now the module is under review. The module is already included in Metasploit.

No comments:

Post a Comment