PhantomBuffer:用 SendMessage 和 cdb.exe 静默绕过 EDR

导语:Zero Salarium 的作者 Two Seven One Three 10 月 17 日丢出一篇新型 EDR 绕过研究,整套打法不走老路:先用 SendMessage(Windows 消息发送 API)的 WM_SETTEXT(设置文本消息)消息把载荷灌进目标进程的 Edit(编辑框)控件,绕过最经典的 WriteProcessMemory(向目标进程写入内存的 API)监控;再让系统自带的 cdb.exe(Windows Console Debugger 命令行调试器)改 RIP 寄存器(x64 指令指针寄存器)劫持线程,绕过 SetThreadContext(设置线程上下文 API)/ NtSetContextThread(其内核态等价调用)这套同样盯得很紧的 API。组合拳打完,作者实测在高端 EDR 眼皮底下静默完成注入。


一、为什么需要”另辟蹊径”的注入

进程注入(process injection)是红队作业里绕不开的动作:渗透测试要落 shell、绕过 UAC(用户账户控制)提权、藏 payload(载荷)做持久化,都得把代码塞到别人进程里。EDR(Endpoint Detection and Response,终端检测与响应系统)盯的就是这个动作。

注入流程通常拆成四步:OpenProcess(打开目标进程句柄)、远程分配 / 保护内存、用 WriteProcessMemory 把载荷写进去、在目标进程里执行。EDR 厂商把每个步骤都挂上钩子,WriteProcessMemory 是重灾区——任何对远程进程的写入都会被重点观察。

PhantomBuffer 的价值就在这里:它不用 WriteProcessMemory,写入载荷用的是 SendMessage。

PhantomBuffer 攻击流程示意

二、SendMessage + WM_SETTEXT:把载荷塞进 Edit 控件

SendMessageW 是 Windows 桌面交互的老朋友。WM_SETTEXT 是它最常用的消息之一——更新窗口的标题、按钮文字、Edit 控件内容都靠它。

关键点:Edit 控件的内容会留在进程的内存里。

那思路就出来了——枚举有 Edit 控件的 GUI(图形界面)进程(Notepad.exe、Regedit.exe 都能凑合),拿到控件句柄,把载荷编码后通过 WM_SETTEXT 灌进去。然后用 ReadProcessMemory 在目标进程内存里搜出载荷,给那段内存开执行权限,最后劫持线程执行。

整套流程里没有 WriteProcessMemory。EDR 那套针对写入 API 的告警规则全部落空。

PhantomBuffer 用 SendMessage WM_SETTEXT 投递载荷

小坑:作者实测发现载荷里不能出现两个连续的 0x00(null 字节)。WM_SETTEXT 走的是 C 风格字符串,碰到 null 字节就截断。设计 shellcode 的时候记得规避。

三、PhantomBuffer 工具套件拆解

作者把 PoC(Proof of Concept,概念验证代码)拆成了两个小工具。

FindTargetWindows:扫一圈当前活跃的 GUI 进程,挑出有合适控件(默认 Edit)的目标。扫不到也能手动指定要新拉一个进程。

FindTargetWindows 工具界面

PhantomBuffer:主工具,做四件事。

  1. 从文件读载荷,Base64 解码。
  2. SendMessage + WM_SETTEXT 把载荷送进目标进程的控件。
  3. ReadProcessMemory 在目标进程内存里搜出载荷,给那段内存改可执行权限。
  4. 劫持目标进程的一个线程,让它去执行载荷。
PhantomBuffer 把载荷写进目标进程内存
PhantomBuffer 在高端 EDR 监控下运行成功

四、cdb.exe:合法调试器来背书

第二个大坎是劫持线程。SetThreadContext / NtSetContextThread 这两个 API 在 EDR 眼里就是”准备劫持线程”的信号,间接系统调用(indirect syscall,即通过跳板跳进内核避开用户态 hook)、直接调用 NtSetContextThread、调用栈伪装(call stack spoofing)——攻防双方在这条路上已经卷到没边。

作者换了个角度:让一个合法的调试器去执行劫持动作。

Microsoft 的 cdb.exe(Windows Debugger Tools 自带的命令行调试器)天生就是干这个的:按 PID 附加进程、选线程、改 RIP 寄存器、分离。命令一行就够:

cdb.exe -p <PID> -c "~~[<TID_IN_HEX>]s; r rip=0x<NEW_RIP>; qd"

四个参数的含义:

  • -p <PID>:附加到指定十进制 PID 的进程
  • -c "...":附加成功后立刻执行引号里的命令串
  • ~~[<TID>]s:选中系统 TID(线程 ID)为指定值的线程,TID 用十六进制、不带 0x 前缀
  • r rip=0x<NEW_RIP>:把 RIP 寄存器(x64 指令指针)设到指定地址,0x 前缀必须有
  • qd:Quit and Detach,分离后目标进程继续运行

EDR 看到的是 cdb.exe 这个合法的 Microsoft 签名二进制在”调试”目标进程——这是它的本职功能,告警阈值很难压低。

作者进一步把 cdb.exe 做成便携版:只用自带的 DLL 就能跑,不依赖注册表和环境变量。

便携 cdb.exe 运行截图

小坑:有些 EDR 还会盯 cdb.exe 的执行路径。默认路径是 C:Program Files (x86)Windows Kits10Debuggersx64cdb.exe,跑在别的路径下容易被标记。红队实战里如果要把 cdb.exe 拷过去,记得放在默认路径,或者改用其他 EDR 信任路径。

五、蓝队怎么防

防御思路很清晰,就看检测链路做不做得到。

第一道钩:监控 SendMessage API 的调用,特别是带 WM_SETTEXT 参数的。正常 GUI 交互不会跨进程传递大段 Base64 编码内容——出现这种模式基本就是在注入。

第二道钩:SetThreadContext / NtSetContextThread 的传统监测不能丢。PhantomBuffer 这条路绕开了它,但只要这两条 API 被盯死,攻击者就得走更复杂的间接调用或硬件断点,红队成本会显著上升。

第三道钩:盯 cdb.exe 的异常路径执行。如果 cdb.exe 不在默认 Windows Kits 路径下出现,且带 -p -c 参数,就是高危信号。

第四道钩:监控 Edit 控件内容异常变化。GUI 进程里 Edit 控件的内容忽然变成 Base64 字符或可执行 shellcode,是典型注入征兆。

六、红队视角:为什么这种组合拳值得收藏

PhantomBuffer 这套打法的本质是把”被盯死”的链路拆成两段,每一段都换成一个不容易告警的合法操作。

第一段用 GUI 消息协议(SendMessage)替代内存写入 API(WriteProcessMemory),把 EDR 重点监控的写入动作变成”GUI 进程间的正常通信”。

第二段用合法调试器(cdb.exe)替代劫持线程 API(SetThreadContext),让告警阈值翻车。

链路里的每个环节都是合法的 Windows 功能——单独拿出来 EDR 不应该告警。组合在一起就成了穿透 EDR 的双层盾。这种”合法行为组合”的攻击面,是当下 EDR 厂商最难处理的一类威胁——单纯给某个 API 加 hook 已经不够,得做调用上下文、调用者身份、调用链的整体画像。

作者公开了 PoC 仓库 https://github.com/TwoSevenOneT/PhantomBuffer 和演示视频 https://youtu.be/2UmMFXyZ2OU,方便读者复现。


素材出处

  • 原始研究:Two Seven One Three(@TwoSevenOneT),《PhantomBuffer: Effective EDR Evasion Through Stealth Injection》,Zero Salarium,2026 年 10 月 17 日。原文地址:https://www.zerosalarium.com/2026/10/PhantomBuffer-Effective-EDR-Evasion-Stealth-Injection.html
  • PoC 仓库:https://github.com/TwoSevenOneT/PhantomBuffer
  • 演示视频:https://youtu.be/2UmMFXyZ2OU
  • 作者 X 账号:Two Seven One Three (@TwoSevenOneT)

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容