文章总结: 本文介绍一种不依赖WriteProcessMemory和VirtualAllocEx的远程进程注入新思路,利用Windows控制台命名管道将payload写入目标进程内存,通过VirtualProtectEx添加执行权限并劫持线程执行。该技术可规避EDR对传统API的监控,防御侧应聚焦VirtualProtectEx调用监控及命名管道读写行为追踪。
综合评分: 85
文章分类: 红队,渗透测试,免杀,恶意软件
EDR 规避新思路:不调用 WriteProcessMemory 的进程注入
Ots安全
2026年9月27日 13:28
广东
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
威胁简报
恶意软件
漏洞攻击
一、引言
在红队演练或针对目标的渗透测试过程中,你极有可能需要用到远程进程注入来执行自己的 payload。正因为这种手法太常用,EDR(终端检测与响应)对其中涉及的 API 盯得格外紧。
本文要介绍一种远程向进程注入代码的新思路——它完全不依赖大家耳熟能详的 WriteProcessMemory 和 VirtualAllocEx 这两个 API。
作者在文末坦白:自己是在折腾一堆 EDR 授权许可的时候,偶然发现 SensePost 的两位研究员 Max Hirschberger 和 Ogulcan Ugur 已经独立想到了相似的思路,并在他们的博客上发表了相关文章(即 Process Parameter Poisoning);顺着这条线,又找到了 modexp 早前探索过的高度相关的技术路线。作者也大方承认,那几位前辈做得比自己更出色。
不过,作者对自己方案里「初始化阶段必须暂停进程」以及「lpCommandLine / lpEnvironment 需要特殊格式」这两点不太满意,于是把那些思路放到一边,转向了一种全新的注入手法——也就是下面要讲的这种。
二、正文
1. 远程进程注入技术概览
进程注入是一种关键的规避与持久化手段:攻击者强迫一个合法的、受信任的 Windows 进程,替自己去执行任意代码。
在经典的「远程线程注入」或「PE 注入」流程里,注入进程必须先通过 OpenProcess 拿到目标程序(比如 explorer.exe、svchost.exe)的句柄,再用 VirtualAllocEx 在目标虚拟地址空间里开一块专用缓冲区。
内存准备好之后,攻击者调用 WriteProcessMemory 这个 API,把恶意 payload 拷贝进远程进程的内存空间。
最后,攻击者用 CreateRemoteThread 或别的办法创建一条线程,让它的 RIP 指向那块刚写入 shellcode 的内存区域。
由于这种跨进程的转换天然绕过了常规的边界防御、还继承了宿主进程的访问权限,EDR 会通过用户态钩子(hook)和内核回调对 WriteProcessMemory 进行严密监控。
EDR 把跨进程内存修改视为高严重度的遥测事件,这也逼着现代威胁行为者不断寻找能够绕过传统内存操作特征的规避替代品。
绝大多数远程注入技术背后的通用公式可以概括为:
[OpenProcess / CreateProcess] + [VirtualAllocEx] + [WriteProcessMemory] + [某种创建线程并劫持 RIP 指向新写入 shellcode 的方式]
2. 用 Windows 命名管道把任意 payload 写入远程进程
当你启动一个交互式控制台程序(它会拉起一个名为 conhost.exe 的子进程),并通过输入命令与之交互时——你敲下的那些命令内容,最终存在哪里?
答案是:存在这个程序的内存里某处。
为了说明这一点,作者写了一个小程序:它用 CreateProcess 创建一个子进程,然后往子进程的 hStdInput(标准输入)里写数据。
作者以控制台程序 nslookup.exe 为例来演示:
当对子进程的 hStdInput 调用 WriteFile 时,被写入的数据就实实在在地落在了子进程的内存中。
于是就有了一个想法:与其对子进程调用 WriteProcessMemory,不如利用 hStdInput 这个命名管道,把 payload 写进另一个进程。
但这里冒出一个问题:Windows 控制台界面只能显示有限的一组可读字符,而往命名管道里写数据,本质上就是一次 WriteFile 调用。理论上讲,这意味着我们完全可以把控制台「显示不了」的字节写进 hStdInput。我们来实地验证一下。作者准备了下面这个二进制数组:
写入命名管道之后:
这就证实了:我们几乎可以把任意字节流写进一个控制台进程的内存里。
3. 通过控制台命名管道实现远程进程注入
基于上面的认知,要不使用 VirtualAllocEx 和 WriteProcessMemory 就把 payload 注入远程进程,主要需要以下六个步骤:
-
挑选一个交互式控制台程序。
作者找到了两个可用的:
netsh.exe和nslookup.exe。 -
调用
CreateProcess,拿到子进程hStdInput的句柄。 -
对
hStdInput调用WriteFile,把 payload 写进子进程。 -
在子进程内存里定位刚刚写入的 payload。
-
用
VirtualProtectEx给这块新识别出来的内存区域加上**执行(Execute)**权限。 -
劫持一条线程
,把它的 RIP 重定向到这个地址。
在使用 WriteFile 往 hStdInput 写数据时,payload 必须避开 Windows 控制台里具有特殊含义的「坏字符」:
-
0x0D
:回车(CR),ASCII 与 Unicode 中的控制字符。
-
0x0A
:换行(LF),控制字符。
-
0x1A
:SUB(替换符),由 Ctrl+Z 产生,历来被当作文件结束(EOF)标记。
生成 payload 时必须规避这几个字符,否则子进程会把 payload 当成一条命令来执行,结果往往是「找不到命令」之类,而原始的 payload 也就不再留在进程内存里了。
为了在子进程内存里定位刚写入的 payload,作者在 payload 开头放了一段特征鲜明的字符,称之为 marker(标记)。只要搜索这个 marker,就能确定 payload 的位置。在把 RIP 重定向过去时,需要给目标地址加上 marker 的长度:
RIP = marker_addr + sizeof(marker)
作者据此写了一个概念验证(PoC),完整跑通了上面这六步,实现远程注入并执行 shellcode,效果如下:
此前已有研究者针对多款 EDR 实测过这类技术,所以作者这里就不再罗列自己的测试结果了。
演示视频:https://youtu.be/DCUnbj_usPM
4. 防御侧建议
由于这种「控制台命名管道注入」完全绕开了 VirtualAllocEx 和 WriteProcessMemory 这两个 API,检测重心应当转移到:
- 对远程进程调用
VirtualProtectEx(尤其是为内存区域添加执行权限)的行为; - 以及对命名管道的读写操作上。
三、结语
红队演练或渗透测试中使用的绝大多数远程注入技术,都依赖 VirtualAllocEx 与 WriteProcessMemory 这对 API 组合,所以 EDR 对它们的监控非常密集。
与传统思路不同,控制台命名管道注入既不调用 VirtualAllocEx,也不调用 WriteProcessMemory。它借力于命名管道的读写操作,再加上「控制台程序会把交互命令存进内存」这一特性来达成目的。此外,它还有几处额外的优势:
- 不需要用
CreateProcess以挂起(suspended)状态启动进程; - 不会让子进程的
lpCommandLine或lpEnvironment出现奇怪的格式。
payload 或 shellcode 里可用字符的限制也相对更少,需要规避的坏字符也就更少。
结果是:传统的监测手段无法可靠地检测并阻断这项技术。防御者应当转而聚焦——控制台程序存放命令的那块内存区域、对 VirtualProtectEx 的监控,以及命名管道读写行为的追踪。
参考
https://www.zerosalarium.com/2026/09/edr-evasion-process-injection-without-WriteProcessMemory.html
END
公众号内容都来自国外等平台- 搜索的内容通过结合编写 –
公众号 | AnQuan7 (Ots安全)
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Ots安全 《EDR 规避新思路:不调用 WriteProcessMemory 的进程注入》