找回密码
立即注册
搜索
发回帖 发新帖

6284

积分

0

好友

767

主题
发表于 11 小时前 | 查看: 5| 回复: 0

PhantomBuffer 载荷投递概念插画:信使递出带核辐射警告的信封

做红队或者渗透测试,迟早都要面对同一个问题:怎么把代码悄悄送进另一个进程,还不让 EDR 响一声。

Windows 上经典的注入四件套——OpenProcess、VirtualAllocEx、WriteProcessMemory、CreateRemoteThread——被安全产品盯了十几年,调用链上任何一环露出跨进程的苗头,告警就来了。攻击者和防御方在这条链上反复拉扯:间接系统调用、调用栈伪造、syscall stub 自己拼,花样层出不穷。但万变不离其宗,总要有一次"往别人内存里写数据"的动作。

10 月 17 日,安全研究者 Two Seven One Three(Zero Salarium)放出了一篇新研究和配套 PoC,名字起得很直白:PhantomBuffer(幻影缓冲)。它的思路是——既然"写内存"这个动作本身扎眼,那就不写:把载荷伪装成一条发给窗口的普通文本消息,让 Windows 自己把它搬进目标进程;执行环节也不亲自上手,外包给微软自家的调试器。作者称对一款高端 EDR 实测有效。

这篇文章就把这套方法拆开讲清楚。

一、先看清楚:隐形注入到底要绕过什么

进程注入绕不开四个核心动作,EDR 的检测也正是围着它们打转:

  1. 打开目标进程:OpenProcess,拿到操作对方的句柄;
  2. 远程准备内存:VirtualAllocEx 之类,在对方地址空间划一块地;
  3. 写入载荷:WriteProcessMemory,把 shellcode 抄过去;
  4. 触发执行:CreateRemoteThread 建远程线程,或者劫持已有线程。

现有的注入技术,本质上都是在跟这四个步骤较劲:要么想办法消掉其中几步,要么把每一步换成一种不那么显眼的用法。所以判断一种新手法值不值得投入精力,就看它到底动了哪一环。

PhantomBuffer 的选择是:干掉第 2 步和第 3 步——不分配、不写入,让目标进程"自己"把载荷收进内存;同时把第 4 步从最危险的 API 上挪走。

顺便说一句,这不是该作者头一回做"无 WriteProcessMemory 注入"。今年 9 月他就发过一篇"控制台命名管道注入":把子进程的标准输入重定向到命名管道,用 WriteFile 把 payload 从管道塞进 nslookup、netsh 这类控制台程序的输入缓冲区,再靠 marker 定位内存、VirtualProtectEx 提权、劫持线程执行。那篇的核心是"借输入缓冲区",PhantomBuffer 则是"借窗口文本区"——同一个哲学,不同的落点。

二、核心思路:把载荷当成一条窗口文本发过去

先把整条链路摆在桌面上:

PhantomBuffer 四步攻击链流程图:不写一个字节把载荷送进目标进程

熟悉 Win32 的人都知道 SendMessageW:给一个或多个窗口发消息。配合 WM_SETTEXT 使用时,目标窗口会调用默认窗口过程,更新自己的标题栏或者控件内容——比如编辑框(Edit control)里的文字。

编辑框的内容存在哪里?存在目标进程自己的内存里。

那问题就来了:如果发给对方的不是普通文本,而是我们的载荷呢? 只要找到这块内存的地址,载荷就已经神不知鬼不觉地进了目标进程——全程没有一个字节是我们"写"进去的,都是 Windows 消息机制代劳。

整套投递分四步:

  1. 枚举系统里带合适控件的 GUI 进程(本文用 Edit 控件);找不到合适的,就自己启动一个(Windows 10 上用记事本,Windows 11 上用注册表编辑器);
  2. 拿到控件句柄;
  3. 通过 SendMessageW 发 WM_SETTEXT,把载荷作为窗口文本发给目标;
  4. 用 ReadProcessMemory 在目标进程内存里搜这条"消息",定位载荷落点。

PhantomBuffer 工具运行日志:SendMessageW 发送 WM_SETTEXT 成功

目标进程 regedit.exe 内存 hexdump:载荷已驻留 Edit 控件文本区

第二张图是目标进程内存的 hexdump 视图:载荷安安静静躺在一块属于注册表编辑器的内存区域里,旁边就是正常的窗口数据。对内存扫描型检测来说,它此刻只是"一段看起来像文本的东西"。

当然,限制也是实实在在的:作者实测发现,载荷里含两个连续的 0x00 字节时无法被正确写入。0x00 是这条路的坏字符——毕竟对方终究是在处理"文本"。

三、PoC 拆解:两个小工具

为了演示这套技术,作者做了个叫 PhantomBuffer 的工具包,里面是两个小程序。

FindTargetWindows:找载体

负责搜索系统里带合适 GUI 控件的进程;如果一个都没有,也可以按参数直接启动一个你指定的进程。作者拿注册表编辑器做的演示:

FindTargetWindows 扫描可见标准 Edit 控件并定位注册表编辑器窗口

从输出能看到,它严格只扫"可见的标准 Edit 控件",启动注册表编辑器后拿到了 "Registry Editor" 窗口的编辑框句柄和当前文本。

PhantomBuffer:干脏活

主工具的逻辑就四步:

  1. 从文件读取并解析 Base64 编码的载荷;
  2. 调 SendMessage 发 WM_SETTEXT,把载荷送到目标;
  3. 在目标内存里定位载荷,并把所在内存区域改成可执行;
  4. 把目标进程的某个线程重定向到载荷。

前两步解决"怎么把数据送进去"的问题,第三步解决"数据躺在那儿但不能跑"的问题,第四步——才是真正难啃的骨头。

四、最敏感的一步,外包给调试器

载荷进内存、页属性也改好了,剩下的是让 CPU 跳到那儿去。作者没有亲自下场,而是把这一步的协作关系设计成了这样:

cdb.exe 代劳劫持架构图:调试器附加改 RIP 执行载荷

常规做法是用 SetThreadContext / NtSetContextThread 改写远程线程上下文——而这正是 EDR 盯得最死的一对 API。从间接系统调用,到直接调 NtSetContextThread,再到调用栈伪造,攻防双方在这对 API 上已经打了无数个来回,继续在枪林弹雨里冲没什么新意。

作者换了个角度想问题:微软当初造这对 API 是给谁用的? 一个合理的答案是:给杀毒软件、EDR 这类监控程序,以及调试器用的。

那——让一个正经调试器代劳这次注入,怎么样? 没有图形界面、没法手动操作调试器,这两个限制筛掉了大部分候选,答案落在 Windows 调试工具自带的 cdb.exe 身上。它的任务是四步:

  1. -p <PID>:按 PID 附加到目标进程;
  2. ~~[<TID>]s:按系统线程 ID 选中线程(TID 用十六进制、不带 0x 前缀);
  3. r rip=0x<地址>:把 RIP 寄存器改成载荷地址;
  4. qd:退出并分离,目标进程继续运行。

一条命令串起来就是:

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

于是整个链条里最敏感的动作——改写远程线程指令指针——由一个微软签名的合法程序完成。在 EDR 眼里,这更像一次普通的调试附加,而不是一次线程劫持。实测运行结果:

PhantomBuffer 完整执行日志:主线程已在载荷地址开始执行

作者还演示了把 cdb.exe 做成便携版:只带它自带的几个 DLL(dbgeng.dll、dbghelp.dll、DbgModel.dll 等),拷贝走就能跑。

cdb.exe 便携版所需 DLL 文件列表

但要提醒一句:有些 EDR 会标记从非默认路径运行的 cdb.exe。作者的建议是,条件允许的话,尽量把 cdb.exe 放回它的官方路径(C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\)下再运行。

五、防御视角

作者自己也给了防御建议,核心就是顺着攻击链找信号:

防御视角:SendMessage 与 cdb.exe 异常检测点

  • 盯 SendMessage 配合 WM_SETTEXT 的跨进程使用:这套方法的投递完全依赖这条消息,是防御的起点;
  • 盯 cdb.exe 的异常出现:从非默认路径运行、attach 后立刻 detach、命令行里带 r rip= 字样,都是强信号;
  • 别忘了残留动作:VirtualProtectEx 对远程内存提权、线程指令指针被外部改写,这些动作依然存在,依然可以被行为分析捕获。

六、一点冷静的评估

把这篇研究放回它该在的位置,有几句话不得不说。

这不是"完全隐身"。 先看一组直观对比:

传统注入链与 PhantomBuffer 对比:显眼 API 一个都不出场

PhantomBuffer 消掉的是 VirtualAllocEx 和 WriteProcessMemory——检测面上最显眼的两个目标,但 VirtualProtectEx(把远程内存改成可执行)和线程指令指针改写依然在场。它改变的是攻防对抗的战场位置,不是战场本身。对防御方而言,这意味着检测重心要跟着迁移:从 API 黑名单转向行为关联——跨进程 WM_SETTEXT、二进制块出现在窗口文本里、非默认路径的调试器、调试附加后线程 RIP 异常。

它有明确的适用边界。 目标必须是有合适控件的 GUI 进程(或者由攻击者自行启动);载荷不能含 0x00;最终执行依赖 cdb.exe 的存在与运行条件。每一条限制,都是防御方可以埋检测规则的地方。

它是这条演进路线上的一环。 从 SensePost 的进程参数污染,到该作者的命名管道注入,再到如今的窗口文本投递,共同的思路是一致的:注入不只有"写内存"一条路,凡是 Windows 自己会把攻击者数据搬进目标进程的合法机制,都是潜在的载体。可以预期,类似的"借道"手法还会继续出现。

对防守的人来说,这类研究的价值不在于给出了又一种攻击姿势,而在于反复提醒同一件事:任何只守 API 黑名单的检测体系,都会被下一次"借道"绕过。 像这类攻防细节与系统底层分析,也一直是云栈社区上开发者们持续讨论的话题。

参考来源

  1. Zero Salarium(2026-10-17)— https://www.zerosalarium.com/2026/10/PhantomBuffer-Effective-EDR-Evasion-Stealth-Injection.html
  2. PhantomBuffer PoC(GitHub)— https://github.com/TwoSevenOneT/PhantomBuffer
  3. 作者前作:EDR Evasion: Process Injection without WriteProcessMemory(2026-09)— https://www.zerosalarium.com/2026/09/edr-evasion-process-injection-without-WriteProcessMemory.html
  4. CN-SEC 中文网对该前作的编译介绍 — https://cn-sec.com/archives/5489443.html
  5. Cyber Press 对命名管道注入技术的报道 — https://cyberpress.org/new-windows-process-injection-technique-evades-edr-monitoring/
  6. MITRE ATT&CK T1055 Process Injection — https://attack.mitre.org/techniques/T1055/
  7. 微软文档:SendMessageW / WM_SETTEXT — https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagew



上一篇:Karakeep 0.34 自动离线下载,让自托管收藏列表离线可读
下一篇:链上侦探卧底朝鲜黑客洗钱网络:追踪 Bybit 15 亿美元赃款
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-10-19 21:20 , Processed in 0.067283 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表