Sometimes, it’s easy to get code execution in a network, but very difficult to egress out of it. When you are an external actor trying to get a foothold, it’s important that your attack package use a payload that’s likely to leave your target’s network. If you can’t get out, all of your work is wasted.
Payloads in the Metasploit Framework are staged. This means that the payload is delivered in pieces. The first piece, known as the stager, connects to you, the attacker, and downloads the second piece, known as the stage. Once the stage is downloaded, the stager executes it.
The Metasploit Framework’s stagers are compatible with different payload options. For example, the Metasploit Framework’s reverse_http stager can deliver Meterpreter or Cobalt Strike’s Beacon.
If your stager can not get past egress filters to download a payload, then your payload will not execute. This blog post focuses on how to get past egress restrictions with a stager.
Egress Assumptions
Some networks are wide open. If you’re dealing with an open network, then this blog post is of little use to you. Here’s what you can expect in a modern enterprise:
- Default policy is to deny all outbound connections
- Allowed outbound connections must go through a proxy
- Outbound connections must conform to the expected protocol
- Outbound connections must pass other checks as well.
With these assumptions in mind, let’s talk about the different Metasploit Framework stagers and how they apply.
Reverse TCP Stagers
The reverse_tcp stager establishes a connection to the attacker on an arbitrary port and downloads the payload.
A variation of the reverse_tcp stager is the reverse_tcp_allports stager. This stager will attempt to connect back to the attacker on port 1, then port 2, port 3, so on and so forth. Once it establishes a connection, it will download the payload and pass control to it. From a network security monitoring point of view, this looks like an attempted port scan from a workstation to an internet host. If your goal is to avoid tripping alarms, I highly recommend that you avoid this stager.
Another variation is the reverse_tcp_dns stager. Contrary to some beliefs, this is NOT a stager to use a Metasploit Framework payload over DNS. The reverse_tcp_dns stager allows you to specify a fully qualified domain name as the LHOST value the stager should connect to.
Our assumptions immediately rule out use of these stagers. If you want to get past tough egress restrictions, forget these stagers.
HTTP and HTTPS Stagers
The Metasploit Framework’s reverse_http stager makes an HTTP GET request to an attacker controlled system to download the payload stage. The reverse_http stager uses the WinINet API to communicate. WinINet is the same library Internet Explorer uses to fulfill requests.
The reverse_https is similar to the reverse_http stager. The main difference is that the reverse_https stager uses SSL, where reverse_http does not.
Proxy (No Authentication)
In our assumptions, all outbound connections must go through a proxy of some sort. The reverse_http stager will pick up the user’s proxy settings by default. This is thanks to WinINet.
If the proxy server requires no authentication, the HTTP and HTTPS stagers will go right through it.
Proxy (NTLM Authentication)
If the proxy server requires NTLM authentication, the HTTP and HTTPS stagers will usually go right through it. There is a caveat.
For WinINet to authenticate to a proxy server, it needs a valid domain user’s token. If your stager runs as a domain user, then you’re all set. If your stager runs as SYSTEM, then you have a problem. The SYSTEM token means nothing to another system on the domain. If WinINet tries to authenticate with this token, it will fail.
WinINet is also not designed for programs run as a service. When a program runs as a service the proxy settings are not available to WinINet.
These caveats are important to know. Some persistence techniques will automatically run your code as SYSTEM or as a service. The Metasploit Framework’s PsExec modules will run your payload as SYSTEM. It’s a shame to set up persistence or PsExec to a host, but never get a session, because of a WinINet limitation.
These limitations are known and they’re by design. WinINet is made for use by Windows desktop applications. For Windows services, the correct library to use is WinHTTP. WinHTTP is another internet communication library in Windows. There is no WinHTTP-based stager or payload in the Metasploit Framework.
Proxy (Static Username/Password)
If the proxy server requires a static username and password to get out, you’re in trouble. The Metasploit Framework’s reverse_http stager will not prompt the user for this information or pick up on the cached values.
There is a reverse_https_proxy stager in the Metasploit Framework. This stager allows the attacker to supply a known username and password to get out through a proxy server.
Protocol Checks
Thanks to WinINet, the reverse_http and reverse_https stager will pass basic protocol checks. To a proxy server, the traffic from these stagers will look like valid traffic. That said, there are a few other checks that may bite you.
FQDN Checks
Some proxy devices have an option to block URLs that reference an IP address directly. This closes a potential loophole to get access to restricted websites. If you plan to use the HTTP or HTTPS stagers, I recommend that you make sure LHOST is set to a fully qualified domain name, not your IP address.
User-Agent Checks
The Metasploit Framework’s HTTP and HTTPS stagers specify an empty User-Agent string. I assume that this to keep these stagers small. Some HTTP proxy devices include a Browser Check feature. This feature will block HTTP requests with User-Agent strings that are not present in an allow list. If this option is on, it may hurt your ability to stage a payload with the reverse_http stager.
The reverse_https stager is immune to most checks like this. When an HTTPS request goes through a proxy server, the client tells the proxy server which host and port to connect to. From that point, the proxy server relays the SSL encrypted traffic between the client and the requested server, with no knowledge of the content of the conversation. There are exceptions to this, but they’re rarer.
DNS Stager
dns_txt_query_exec is a Metasploit Framework module that demonstrates how to download code over DNS and execute it.
Cobalt Strike includes a heavily modified payload stager based on the dns_txt_query_exec module. These changes add resiliency to the stager (DNS requests do fail sometimes!) and make it capable of downloading payloads larger than 25KB. Cobalt Strike also includes a DNS server to automatically speak this staging protocol without forcing the user to create records by hand.
A TXT record is limited to 255 characters. It takes many TXT record requests to download a payload. I use the modified dns_txt_query_exec to stage Cobalt Strike’s Beacon over DNS when needed. It takes around 1,000 TXT record requests to stage Beacon. Over the internet, this takes about one minute.
DNS Staging is a nice option for systems that can’t connect to the internet or when other egress restrictions are too much work to figure out. If a system can resolve a fully qualified domain name to an IP address, then it can probably stage a payload over DNS too.
Tradecraft, part 8: Offense in Depth discusses this topic as well.