For our January V-Day, we’re introducing two new payload modules, python/meterpreter/rev_http and python/meterpreter/rev_https. These stagers are shellcode-less, ‘pure’ Meterpreter stagers somewhat similar to traditional reverse_tcp stagers.
Meterpreter reverse_https[s] stagers are actually a bit simpler than reverse_tcp. The general idea is the same- the handler serves up a .dll file that the client then injects using the VirtualAlloc/etc. methodology. However, instead of having to patch the .dll ourselves with assembly instructions and the socket file descriptor, the Metasploit handler patches the user-agent, transport method (http/https), url and expiration/communication timeout dynamically as it serves the Meterpreter .dll:
The only slightly tricky part is reversing the http checksum method that a Metasploit stager uses for requesting the specific resource from the handler (that /aIc0 above) . This URI resource generation method is ‘generate_uri_checksum()’ in metasploit-framework/lib/msf/core/handler/reverse_http/uri_checksum.rb (formally in metasploit-framework/lib/msf/core/handler/reverse_http.rb) . The algorithm can be implemented in Python as follows:
# adds up all character values and mods the total by 256 def checksum8(s): return sum([ord(ch) for ch in s]) % 0x100 # generate a metasploit http handler compatible checksum for the URL def genHTTPChecksum(): chk = string.ascii_letters + string.digits for x in xrange(64): uri = "".join(random.sample(chk,3)) r = "".join(sorted(list(string.ascii_letters+string.digits), key=lambda *args: random.random())) for char in r: if checksum8(uri + char) == 92: return uri + char
Since http[s] stagers are packet-based instead of stream-based, the MSF devs put a system into the handlers that corrals ‘orphaned’ sessions. That is, if you close your reverse_http handler, then start it up later (within the specified reconnect window) the handler will pick the session back up and reregister it. We talked about this during our Building in the Meterpreter .dll post. Here, since we’re registering a session in the correct way, we stay with the ’92’ checksum value (which corresponds to URI_CHECKSUM_INITW).
With the checking algorithm implemented in the stagers, you’ll get a nice and different checksum value every time each stager is run, instead of having to rely on a single hardcoded value. Another nice little bonus with the rev_http is that it plays functions nicely as a native stager for Cobalt Strike’s beacon. We talked about using beacon with Veil previously and this gives a nice alternative to using straight shellcode stagers.