堆栈不在,何必欺骗?
字数 1784 2025-08-29 22:41:10

DeathSleep技术:通过消除堆栈绕过EDR检测的深入解析

摘要

本文详细解析了一种新型EDR(终端检测与响应)绕过技术——DeathSleep,该技术基于"如果堆栈不存在,就没有必要伪造堆栈"的创新思路。该技术通过终止当前线程并在执行前恢复它,有效规避了现代EDR系统对线程堆栈的扫描检测。本文将从上下文恢复过程、调度恢复过程等核心环节进行深入剖析,并提供完整的技术实现细节。

技术背景

现代C2(Command and Control)框架普遍实现了睡眠机制,而EDR产品(如Elastic EDR)则发展出了在睡眠期间或调用敏感API时扫描线程堆栈的检测技术。传统的内存加密和堆栈欺骗技术已广为人知,而DeathSleep技术则提供了一种全新的绕过思路。

上下文恢复过程

核心思想

终止当前线程并在执行前恢复它,使EDR无法扫描到有效的线程堆栈。实现这一目标需要保存两样关键数据:

  1. CPU状态(通过线程上下文)
  2. 堆栈内容

实现步骤

  1. Hook Sleep函数:在beacon睡眠期间跳转到自定义的SleepHook函数
  2. 保存执行上下文
    • 使用RtlCaptureContext函数捕获调用方上下文
    • 修改RIP寄存器指向DeathSleep的返回地址
    • 计算并保存堆栈结构
// 修改RIP指向DeathSleep的返回地址
threadCtxBackup.Rip = *(PDWORD64)(threadCtxBackup.Rsp + stackFrameSize);

// 计算并保存堆栈
stackBackupSize = initialRsp - (threadCtxBackup.Rsp + stackFrameSize + 0x8);
stackBackup = malloc(stackBackupSize + 0x150);
memcpy(stackBackup, (PVOID)(initialRsp - (DWORD64)stackBackupSize), stackBackupSize + 0x150);

关键技术挑战与解决方案

  1. 进程保持运行

    • 初始方案:while(TRUE)循环
    • 优化方案:WaitForSingleObject((HANDLE)-1, INFINITE)
  2. 堆栈结构分析

    • 方案一:编译后通过调试器分析并填充变量
    • 方案二:使用标记变量并通过Unwind Info获取值
  3. 堆栈恢复

    • 使用汇编获取当前RSP:
    getRSP PROC
        mov rax, rsp
        add rax, 8
        ret
    getRSP ENDP
    
    • 解决函数调用破坏恢复堆栈:移动awake函数并修改RSP

调度恢复过程

线程池技术应用

使用Windows线程池API管理任务执行,相比传统线程管理具有以下优势:

  • 自动管理线程生命周期
  • 无需手动创建/销毁线程
  • 支持任务队列和调度

线程池初始化关键点

  1. 使用CreateThreadpoolTimer等新API替代旧API
  2. 设置最大线程数确保顺序执行
  3. 使用CloseThreadPool进行清理

内存保护修改技术

由于直接调用VirtualProtect会导致崩溃,采用以下解决方案:

  1. 使用NtContinue重定向执行:

    • 修改RIP指向VirtualProtect函数
    • 设置四个寄存器传递参数
    • 解决RSP定位问题:
      RtlCaptureContext(&ctx);
      ctx.Rsp += 8;  // 指向返回地址
      
  2. 多阶段恢复问题:

    • 在新线程中再次使用RtlCaptureContext
    • 使用ROP链构建执行流

线程池API深度分析

研究发现不同线程池API的参数传递机制差异:

  1. CreateThreadpoolTimerTpAllocTimer的包装
  2. SetThreadpoolTimerTpSetTimer的转发
  3. CreateTimerQueueTimer内部调用RtlCreateTimer,后者又调用TpAllocTimerTpSetTimer

回调函数实际由RtlpTpTimerCallback处理,它会重新组织参数顺序,因此需要特殊调用方式适配。

技术优势与创新点

  1. 彻底规避堆栈扫描:通过消除而非伪造堆栈,从根本上规避检测
  2. 资源高效:精确控制线程生命周期,避免资源浪费
  3. 稳定性强:完善的上下文保存与恢复机制
  4. 兼容性好:适配多种线程池API实现

实现注意事项

  1. 确保在所有执行路径上正确保存和恢复上下文
  2. 注意不同Windows版本线程池API的差异
  3. 精确计算堆栈空间,避免内存破坏
  4. 处理异常情况下的资源释放

参考资源

  1. 项目地址:https://github.com/janoglezcampos/DeathSleep
  2. Ekko项目:https://github.com/Cracked5pider/Ekko
  3. 原始研究:https://twitter.com/httpyxel

结论

DeathSleep技术代表了一种新型的EDR绕过思路,通过创新的"无堆栈"方法有效规避了现代安全产品的检测机制。该技术结合了精细的上下文操作、线程池管理和内存保护修改等多种技术,为红队操作提供了强有力的隐蔽执行能力。理解并掌握这一技术对于安全研究人员和渗透测试人员都具有重要意义。

DeathSleep技术:通过消除堆栈绕过EDR检测的深入解析 摘要 本文详细解析了一种新型EDR(终端检测与响应)绕过技术——DeathSleep,该技术基于"如果堆栈不存在,就没有必要伪造堆栈"的创新思路。该技术通过终止当前线程并在执行前恢复它,有效规避了现代EDR系统对线程堆栈的扫描检测。本文将从上下文恢复过程、调度恢复过程等核心环节进行深入剖析,并提供完整的技术实现细节。 技术背景 现代C2(Command and Control)框架普遍实现了睡眠机制,而EDR产品(如Elastic EDR)则发展出了在睡眠期间或调用敏感API时扫描线程堆栈的检测技术。传统的内存加密和堆栈欺骗技术已广为人知,而DeathSleep技术则提供了一种全新的绕过思路。 上下文恢复过程 核心思想 终止当前线程并在执行前恢复它,使EDR无法扫描到有效的线程堆栈。实现这一目标需要保存两样关键数据: CPU状态(通过线程上下文) 堆栈内容 实现步骤 Hook Sleep函数 :在beacon睡眠期间跳转到自定义的SleepHook函数 保存执行上下文 : 使用 RtlCaptureContext 函数捕获调用方上下文 修改RIP寄存器指向 DeathSleep 的返回地址 计算并保存堆栈结构 关键技术挑战与解决方案 进程保持运行 : 初始方案: while(TRUE) 循环 优化方案: WaitForSingleObject((HANDLE)-1, INFINITE) 堆栈结构分析 : 方案一:编译后通过调试器分析并填充变量 方案二:使用标记变量并通过Unwind Info获取值 堆栈恢复 : 使用汇编获取当前RSP: 解决函数调用破坏恢复堆栈:移动awake函数并修改RSP 调度恢复过程 线程池技术应用 使用Windows线程池API管理任务执行,相比传统线程管理具有以下优势: 自动管理线程生命周期 无需手动创建/销毁线程 支持任务队列和调度 线程池初始化关键点 使用 CreateThreadpoolTimer 等新API替代旧API 设置最大线程数确保顺序执行 使用 CloseThreadPool 进行清理 内存保护修改技术 由于直接调用 VirtualProtect 会导致崩溃,采用以下解决方案: 使用 NtContinue 重定向执行: 修改RIP指向 VirtualProtect 函数 设置四个寄存器传递参数 解决RSP定位问题: 多阶段恢复问题: 在新线程中再次使用 RtlCaptureContext 使用ROP链构建执行流 线程池API深度分析 研究发现不同线程池API的参数传递机制差异: CreateThreadpoolTimer 是 TpAllocTimer 的包装 SetThreadpoolTimer 是 TpSetTimer 的转发 CreateTimerQueueTimer 内部调用 RtlCreateTimer ,后者又调用 TpAllocTimer 和 TpSetTimer 回调函数实际由 RtlpTpTimerCallback 处理,它会重新组织参数顺序,因此需要特殊调用方式适配。 技术优势与创新点 彻底规避堆栈扫描 :通过消除而非伪造堆栈,从根本上规避检测 资源高效 :精确控制线程生命周期,避免资源浪费 稳定性强 :完善的上下文保存与恢复机制 兼容性好 :适配多种线程池API实现 实现注意事项 确保在所有执行路径上正确保存和恢复上下文 注意不同Windows版本线程池API的差异 精确计算堆栈空间,避免内存破坏 处理异常情况下的资源释放 参考资源 项目地址: https://github.com/janoglezcampos/DeathSleep Ekko项目: https://github.com/Cracked5pider/Ekko 原始研究: https://twitter.com/httpyxel 结论 DeathSleep技术代表了一种新型的EDR绕过思路,通过创新的"无堆栈"方法有效规避了现代安全产品的检测机制。该技术结合了精细的上下文操作、线程池管理和内存保护修改等多种技术,为红队操作提供了强有力的隐蔽执行能力。理解并掌握这一技术对于安全研究人员和渗透测试人员都具有重要意义。