EDR在R3层Hook原理以及绕过研究
字数 2613 2025-09-23 19:27:46

EDR R3层Hook原理与绕过技术研究

一、EDR Hook原理

1.1 Hook位置

  • NTDLL中的NT函数:EDR通过Hook ntdll.dll 中的系统调用(如NtOpenProcessNtAllocateVirtualMemory等)以监控参数和行为。
  • Kernel32函数:部分EDR也会Hook kernel32.dll 中的函数(如CreateProcessWriteProcessMemory等)。

1.2 Hook方式

  • Inline Hook:修改函数开头指令,跳转至EDR注入的DLL中的检测代码。
  • IAT Hook:修改导入地址表,较少见,本文主要讨论Inline Hook。

1.3 DLL注入机制

  • 传统方式AppInit_DLLs(Windows 8之前),系统加载user32.dll时同时加载指定DLL。
  • 现代方式:驱动 + KAPC(内核异步过程调用)
    • 驱动监控进程创建(PsSetCreateProcessNotifyRoutine)。
    • 在目标进程分配内存,写入APC例程和DLL路径。
    • 初始化APC对象,插入线程APC队列,触发时执行LoadLibrary加载DLL。

二、阻止EDR Hook的方法

2.1 BlockDLLs(Cobalt Strike)

  • 功能:子进程仅加载微软签名DLL,阻止非微软DLL(如EDR注入)。
  • 实现
    • 使用STARTUPINFOEX结构设置安全策略:PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON
  • 局限性
    • 部分EDR具微软签名,仍可注入(如Crowdstrike Falcon)。
    • 虚假DLL(如SentinelOne的InProcessClient64.dll)可能仍存在。

2.2 ACG(Arbitrary Code Guard)

  • 功能:禁止分配/修改可执行内存(如VirtualAllocVirtualProtect申请PAGE_EXECUTE_READWRITE)。
  • 实现SetProcessMitigationPolicy(ProcessDynamicCodePolicy, ...)
  • 局限性
    • EDR在进程启动时即完成Hook(通过内核回调),ACG启用后已晚。
    • 不影响远程进程使用WriteProcessMemory+CreateRemoteThread执行shellcode。

三、绕过EDR Hook的方法

3.1 读取干净ntdll数据

3.1.1 从磁盘读取

  • 步骤
    1. 使用CreateFile + ReadFileCreateFileMapping读取磁盘上的ntdll.dll
    2. 覆盖进程内存中已Hook的.text节区。
  • 风险:可能触发EPP启发式检测(文件操作行为)。

3.1.2 管道(Pipe)方式

  • 步骤
    1. 创建管道,启动可信进程(如cmd.exe)读取ntdll.dll并写入管道。
    2. 从管道读取数据,避免直接调用文件API。
  • 优点:减少可疑行为,规避启发式检测。

其他隐秘读取技术:

  • Blindside:通过异常处理机制读取内存。
  • NTDLLReflection:利用反射加载机制获取干净副本。
  • Sacrificing Suspended Processes:挂起进程读取其内存中的ntdll。

3.2 Syscall技术

3.2.1 Direct Syscall

  • 直接执行syscall指令,跳过ntdll。
  • 代表项目
    • Syswhispers1/2:硬编码SSN或通过排序ntdll导出函数获取SSN。
    • Hell's Gate:遍历ntdll导出表,计算函数哈希匹配SSN。
    • Halo's Gate:在Hell's Gate基础上,检测Hook并上下搜索未Hook的syscall stub,推算正确SSN。

3.2.2 Indirect Syscall

  • 跳转至ntdll中的合法syscall指令(如其他未Hook函数中的syscall)。
  • 代表项目
    • Syswhispers3
      • jumper:跳转到目标函数的syscall地址。
      • jumper_randomized:跳转到随机syscall地址。
      • egg_hunter:将syscall指令替换为垃圾代码,运行时修复。
    • HWSyscall:基于Halo's Gate获取SSN,并在kernel32中找Gadget跳转,实现堆栈欺骗。

其他Syscall项目参考:

  • ParallelSyscalls:多线程并行执行syscall。
  • TartarusGate:结合Direct/Indirect Syscall和堆栈混淆。

四、EDR检测与应对

4.1 检测手段

  1. 行为监控
    • 读取ntdll.dll(文件/管道操作)。
    • 非微软模块加载(BlockDLLs绕过检测)。
  2. 堆栈分析
    • Direct Syscall:调用栈缺少kernel32 → ntdll流程。
    • Indirect Syscall:返回地址不在预期模块内。
  3. 内核态检测
    • 分析KTRAP_FRAME中的RIP(返回地址),判断是否来自ntdll。
    • 使用EtwTi记录syscall事件。

4.2 绕过建议

  • 合法上下文:模拟正常调用链(如Indirect Syscall)。
  • 减少可疑行为:避免直接文件操作,使用管道或内存反射。
  • 动态行为:随机化syscall地址、SSN获取方式。

五、总结

  • EDR的R3层Hook主要依赖Inline Hook和KAPC注入。
  • 阻止Hook方法(BlockDLLs、ACG)存在局限性,需结合环境测试。
  • 绕过Hook主流方法:覆盖干净ntdll、Syscall(Direct/Indirect)。
  • EDR可通过行为、堆栈、内核上下文等多维度检测,需动态适配和模拟合法调用链。

参考资料


如果有新的想法,欢迎随时和我讨论!

EDR R3层Hook原理与绕过技术研究 一、EDR Hook原理 1.1 Hook位置 NTDLL中的NT函数 :EDR通过Hook ntdll.dll 中的系统调用(如 NtOpenProcess 、 NtAllocateVirtualMemory 等)以监控参数和行为。 Kernel32函数 :部分EDR也会Hook kernel32.dll 中的函数(如 CreateProcess 、 WriteProcessMemory 等)。 1.2 Hook方式 Inline Hook :修改函数开头指令,跳转至EDR注入的DLL中的检测代码。 IAT Hook :修改导入地址表,较少见,本文主要讨论Inline Hook。 1.3 DLL注入机制 传统方式 : AppInit_DLLs (Windows 8之前),系统加载 user32.dll 时同时加载指定DLL。 现代方式 :驱动 + KAPC(内核异步过程调用) : 驱动监控进程创建( PsSetCreateProcessNotifyRoutine )。 在目标进程分配内存,写入APC例程和DLL路径。 初始化APC对象,插入线程APC队列,触发时执行 LoadLibrary 加载DLL。 二、阻止EDR Hook的方法 2.1 BlockDLLs(Cobalt Strike) 功能 :子进程仅加载微软签名DLL,阻止非微软DLL(如EDR注入)。 实现 : 使用 STARTUPINFOEX 结构设置安全策略: PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON 。 局限性 : 部分EDR具微软签名,仍可注入(如Crowdstrike Falcon)。 虚假DLL(如SentinelOne的 InProcessClient64.dll )可能仍存在。 2.2 ACG(Arbitrary Code Guard) 功能 :禁止分配/修改可执行内存(如 VirtualAlloc 、 VirtualProtect 申请 PAGE_EXECUTE_READWRITE )。 实现 : SetProcessMitigationPolicy(ProcessDynamicCodePolicy, ...) 。 局限性 : EDR在进程启动时即完成Hook(通过内核回调),ACG启用后已晚。 不影响远程进程使用 WriteProcessMemory + CreateRemoteThread 执行shellcode。 三、绕过EDR Hook的方法 3.1 读取干净ntdll数据 3.1.1 从磁盘读取 步骤 : 使用 CreateFile + ReadFile 或 CreateFileMapping 读取磁盘上的 ntdll.dll 。 覆盖进程内存中已Hook的 .text 节区。 风险 :可能触发EPP启发式检测(文件操作行为)。 3.1.2 管道(Pipe)方式 步骤 : 创建管道,启动可信进程(如 cmd.exe )读取 ntdll.dll 并写入管道。 从管道读取数据,避免直接调用文件API。 优点 :减少可疑行为,规避启发式检测。 其他隐秘读取技术: Blindside :通过异常处理机制读取内存。 NTDLLReflection :利用反射加载机制获取干净副本。 Sacrificing Suspended Processes :挂起进程读取其内存中的ntdll。 3.2 Syscall技术 3.2.1 Direct Syscall 直接执行 syscall 指令,跳过ntdll。 代表项目 : Syswhispers1/2 :硬编码SSN或通过排序ntdll导出函数获取SSN。 Hell's Gate :遍历ntdll导出表,计算函数哈希匹配SSN。 Halo's Gate :在Hell's Gate基础上,检测Hook并上下搜索未Hook的syscall stub,推算正确SSN。 3.2.2 Indirect Syscall 跳转至ntdll中的合法 syscall 指令(如其他未Hook函数中的syscall)。 代表项目 : Syswhispers3 : jumper :跳转到目标函数的syscall地址。 jumper_randomized :跳转到随机syscall地址。 egg_hunter :将syscall指令替换为垃圾代码,运行时修复。 HWSyscall :基于Halo's Gate获取SSN,并在kernel32中找Gadget跳转,实现堆栈欺骗。 其他Syscall项目参考: ParallelSyscalls :多线程并行执行syscall。 TartarusGate :结合Direct/Indirect Syscall和堆栈混淆。 四、EDR检测与应对 4.1 检测手段 行为监控 : 读取ntdll.dll(文件/管道操作)。 非微软模块加载(BlockDLLs绕过检测)。 堆栈分析 : Direct Syscall:调用栈缺少 kernel32 → ntdll 流程。 Indirect Syscall:返回地址不在预期模块内。 内核态检测 : 分析 KTRAP_FRAME 中的RIP(返回地址),判断是否来自ntdll。 使用 EtwTi 记录syscall事件。 4.2 绕过建议 合法上下文 :模拟正常调用链(如Indirect Syscall)。 减少可疑行为 :避免直接文件操作,使用管道或内存反射。 动态行为 :随机化syscall地址、SSN获取方式。 五、总结 EDR的R3层Hook主要依赖Inline Hook和KAPC注入。 阻止Hook方法(BlockDLLs、ACG)存在局限性,需结合环境测试。 绕过Hook主流方法:覆盖干净ntdll、Syscall(Direct/Indirect)。 EDR可通过行为、堆栈、内核上下文等多维度检测,需动态适配和模拟合法调用链。 参考资料 : Syswhispers Hell’s Gate Halo’s Gate HWSyscall Blindside 如果有新的想法,欢迎随时和我讨论!