文章总结: 本文介绍一种不依赖WriteProcessMemory与VirtualAllocEx的远程进程注入技术,利用Windows控制台命名管道向目标进程写入载荷,通过劫持线程RIP执行代码。该方法规避EDR对传统API的监控,但需避开特定坏字符。防御建议关注VirtualProtectEx调用及命名管道读写。文章仅供教育研究使用。 综合评分: 85 文章分类: 红队,渗透测试,免杀,安全工具,安全运营
EDR 对抗:不使用 WriteProcessMemory 的进程注入
ZeroSalarium ZeroSalarium
securitainment
2026年9月29日 12:06 中国香港
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
一、引子
在对目标开展红队行动或渗透测试的过程中,你极有可能需要使用远程进程注入来执行你的载荷。由于这项技术被如此频繁地使用,端点检测与响应(EDR)系统对相关 API 的监控非常严密。
本文将介绍一种远程向进程注入代码的新方法——它不依赖众所周知的 WriteProcessMemory与 VirtualAllocEx这两个 API。
在我跟一堆 EDR 许可证较劲的时候,我发现两位非常有实力的研究者——来自 SensePost 的 Max Hirschberger 与 Ogulcan Ugur ——独立想出了类似的思路并就此发表了文章。他们的工作还引导我找到了 modexp 对一种密切相关方法的研究。事实上,这些研究者做得比我好得多。
不过,我并不完全满意于「在初始化时必须暂停进程」这一点,也不满意 lpCommandLine与 lpEnvironment所需的那些怪异格式。因此我把那些方法搁置一旁,转向一种新的注入技术,也就是下面要介绍的内容。
想获取我一直在研究的渗透测试与红队最新技巧,可以在 X 上找到我:Two Seven One Three(@TwoSevenOneT)。
二、正文
1. 远程进程注入技术概览
进程注入是一项关键的规避与持久化技术:攻击者迫使一个合法的、受信任的 Windows 进程代其执行任意代码。
在经典的远程线程注入或 PE 注入流程中,注入方进程必须首先通过 OpenProcess获取目标应用(例如 explorer.exe或 svchost.exe)的句柄,并用 VirtualAllocEx在其虚拟地址空间中分配一块专用缓冲区。
内存准备好之后,攻击者调用 WriteProcessMemoryAPI 把恶意载荷复制进远程进程的内存空间。
随后,攻击者使用 CreateRemoteThread或其他方法创建一个线程,使其 RIP 指向刚写入的、包含 shellcode 的内存区域。
由于这种跨进程转换天然地绕过了常规的边界防御,并且继承了宿主进程的访问权限,端点检测与响应(EDR)方案会通过用户态挂钩(userland hooks)与内核回调对 WriteProcessMemory进行严密监控与审查。
EDR 平台把跨进程内存修改视为高危遥测事件,这促使现代威胁行为体不断寻找能够绕过传统内存操作特征的规避替代方案。
大多数远程注入技术背后的通用公式是:
[OpenProcess/CreateProcess] + [VirtualAllocEx] + [WriteProcessMemory] + [某种创建线程、把 RIP 重定向到新写入 shellcode 的方法]
2. 使用 Windows 命名管道向远程进程写入任意载荷
当你打开一个交互式控制台程序、它带着一个名为 conhost.exe的子进程,你输入命令与它交互时——这些命令的内容存储在哪里?
答案是:存储在程序内存的某个地方。
为演示这一点,我会写一个小程序,用 CreateProcess创建一个子进程,并向该子进程的 hStdInput写入数据。
我以控制台程序 nslookup.exe为例:
当我向子进程的 hStdInput调用 WriteFile时,被写入的数据会存储在子进程的内存中。
于是思路就来了:利用 hStdInput命名管道把载荷写入另一个进程,而不是对子进程调用 WriteProcessMemory。
不过问题出现了:Windows 控制台界面只能显示有限的一组可读字符,而写入命名管道本质上就是一次 WriteFile调用。理论上这意味着,我们应该能够向 hStdInput写入控制台无法显示的字节。我们来实际验证一下。我有如下的二进制数组:
这证实了:我们几乎可以把任意数据写入一个控制台进程的内存。
3. 经由控制台命名管道的远程进程注入
基于上述信息,要在不使用VirtualAllocEx与 WriteProcessMemory的情况下把载荷注入远程进程,需要以下主要步骤:
-
选择一个交互式控制台程序。我找到了两个:
netsh.exe与nslookup.exe。 -
调用
CreateProcess,获取子进程hStdInput的句柄。 -
对该
hStdInput调用WriteFile,把载荷写入子进程。 -
在子进程的内存中定位刚写入的载荷。
-
使用
VirtualProtectEx为刚识别出的内存区域添加执行权限。 -
劫持一个线程
,把它的 RIP 重定向到该地址。
使用 WriteFile向 hStdInput写入时,载荷必须避开在 Windows 控制台中具有特殊含义的某些坏字符:
-
0x0D:回车符(CR),ASCII 与 Unicode 中的控制字符。
-
0x0A:换行符(LF),控制字符。
-
0x1A:SUB(替换字符),由按下 Ctrl+Z 产生,历史上被用作文件结束(EOF)标记。
在生成载荷时,我们必须避开这些字符。否则,子进程会把载荷当作一条命令来解释并以普通命令执行。结果就是「命令未找到」之类的提示,而原始载荷将不再留在进程内存中。
为了在子进程内存中定位刚写入的载荷,我会在载荷开头放置一串独特的字符,我称之为标记(marker)。通过搜索这个标记,我们就能识别出载荷的位置。重定向 RIP 时,我们需要在 RIP 将要指向的地址上加上标记的长度:
RIP = marker_addr + sizeof(marker)
我写了一个概念验证程序,执行上述六个步骤来远程注入并执行 shellcode,如下所示:
此前的研究者已针对多款 EDR 测试过这项技术,因此这里我不再附上自己的测试结果。
演示视频:https://youtu.be/DCUnbj_usPM
4. 防御
由于这种控制台命名管道注入技术完全消除了对 VirtualAllocEx与 WriteProcessMemoryAPI 的使用,监控重点应转向:对远程进程调用 VirtualProtectEx的行为,以及对命名管道的读写操作。
三、结语
红队行动或渗透测试中使用的大多数远程注入技术都依赖 VirtualAllocEx与 WriteProcessMemory这一对 API,因此 EDR 对它们监控得非常严密。
与传统方法不同,控制台命名管道注入不使用VirtualAllocEx与 WriteProcessMemory。相反,它利用了经由命名管道的读写操作,以及控制台程序把交互式命令存储在内存中这一特性。此外,该技术还具备若干其他优势:
- 它不要求用
CreateProcess以挂起状态启动进程。 - 它不会导致子进程的
lpCommandLine或lpEnvironment出现异常格式。
载荷或 shellcode 所使用的字符受到的限制相对较少,也就是说需要避开的坏字符更少。
因此,传统的监控方法无法可靠地检测和阻止这项技术。防御方应转而关注控制台程序存储其命令的内存区域、监控 VirtualProtectEx的使用,并跟踪命名管道上的读写操作。
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:securitainment ZeroSalarium ZeroSalarium《EDR 对抗:不使用 WriteProcessMemory 的进程注入》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论