用户态异步执行注入-APC与Fiber"

admin 2026-10-21 03:31:15 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

用户态异步执行注入-APC与Fiber

原创

pandazhengzheng
pandazhengzheng

安全分析与研究

2026年8月28日 22:00
广东

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

目录

  1. 为什么需要异步执行注入
  2. Remote Thread Injection 的检测回顾
  3. APC 机制深度原理
  4. APC Injection 技术
  5. Early Bird APC Injection
  6. 特殊 APC 变体与进阶
  7. Fiber 机制深度原理
  8. Fiber 注入技术
  9. 两种技术的对比与组合
  10. EDR 检测与规避总览
  11. 小结

1. 为什么需要异步执行注入

1.1 注入的本质问题

\"注入\"要解决两个问题:

  1. 代码落地:把 shellcode/payload 放到目标进程的内存中(可执行);
  2. 执行触发:让目标进程的某个线程开始执行这段代码。

经典的 CreateRemoteThread 同时解决两者:VirtualAllocEx 落地 + WriteProcessMemory 写入 + CreateRemoteThread(start=addr) 触发。但它产生一组极强的信号:

  • 跨进程 OpenProcess(句柄回调);
  • 跨进程 VirtualAllocEx(ETW-TI EtwTiLogAllocExecVm);
  • 跨进程 WriteProcessMemory(ETW-TI EtwTiLogReadWriteVm);
  • 跨进程 CreateRemoteThread(inline hook + ETW-TI EtwTiLogCreateThread + PsSetCreateThreadNotifyRoutine)。

1.2 异步执行的思路

异步执行注入保留\"代码落地\"(仍需跨进程写入),但改变\"执行触发\"方式:不创建新线程,而是让目标进程已有的线程去执行 payload。这削减了\"新线程创建\"这一最强信号,并将\"执行\"伪装为该线程的正常异步处理。

Windows 提供两种用户态异步执行机制:

  • APC(Asynchronous Procedure Call):内核提供的线程异步调用队列;
  • Fiber(纤程):用户态实现的协作式调度单元。

2. Remote Thread Injection 的检测回顾

作为对照基线,回顾 CreateRemoteThread 的完整检测链:

步骤 API 检测信号
1 OpenProcess(PROCESS_ALL_ACCESS) ObRegisterCallbacks 记录跨进程句柄;剥离危险权限
2 VirtualAllocEx(RWX) inline hook + ETW-TI EtwTiLogAllocExecVm;RWX 是强特征
3 WriteProcessMemory inline hook + ETW-TI EtwTiLogReadWriteVm
4 CreateRemoteThread(addr) inline hook + ETW-TI EtwTiLogCreateThread + PsSetCreateThreadNotifyRoutine
5 线程执行 新线程的调用栈不自然(起始地址为私有内存)

关键信号:第 4 步的\"跨进程线程创建\"几乎无法在用户态规避——NtCreateThreadEx 必然触发内核回调。因此异步执行注入的核心收益是消除第 4 步。


3. APC 机制深度原理

3.1 APC 的内核数据结构

每个线程(KTHREAD)内嵌一个 KAPC_STATE:

typedef struct _KAPC_STATE {
    LIST_ENTRY ApcListHead[2];   // [0]=KernelMode, [1]=UserMode
    PKPROCESS Process;
    BOOLEAN KernelApcInProgress;
    BOOLEAN KernelApcPending;
    BOOLEAN UserApcPending;
    ...
} KAPC_STATE;

每个 APC 节点是一个 KAPC:

typedef struct _KAPC {
    UCHAR Type;            // ApcObject
    UCHAR SpareByte0;
    UCHAR Size;
    UCHAR SpareByte1;
    ULONG SpareLong0;
    PVOID Thread;          // 目标线程
    LIST_ENTRY ApcListEntry;
    PVOID KernelRoutine;   // 内核态例程(派发时先执行)
    PVOID RundownRoutine;  // 线程退出时的清理例程
    PVOID NormalRoutine;   // 用户态例程(最终执行)
    PVOID NormalContext;
    PVOID SystemArgument1;
    PVOID SystemArgument2;
    CHAR ApcMode;          // KernelMode / UserMode
    BOOLEAN Inserted;
} KAPC;

3.2 APC 排队:NtQueueApcThread

用户态调用 NtQueueApcThread(hThread, pApcRoutine, pArg1, pArg2, pArg3) 时,内核:

  1. 分配并初始化一个 KAPC,NormalRoutine = pApcRoutine,ApcMode = UserMode;
  2. 将其插入目标线程 KTHREAD.ApcState.ApcListHead[UserMode];
  3. 若目标线程正在 alertable wait,置 UserApcPending = TRUE 并取消其等待(使其从 wait 返回);
  4. 目标线程在从 wait 返回路径上调用 KiDeliverApc,派发 APC。

3.3 APC 派发:KiDeliverApc

当线程进入 alertable wait 后被唤醒(或主动调用 NtTestAlert),内核在返回用户态前调用 KiDeliverApc:

  1. 遍历 ApcListHead[KernelMode],对每个内核 APC 调用其 KernelRoutine;
  2. 遍历 ApcListHead[UserMode],对每个用户 APC:
  • 先调用 KernelRoutine(通常是 KeBugCheck 或默认的 KiInitializeUserApc);
  • KiInitializeUserApc 在用户态栈上构造一个 trap frame,设置用户态返回到 ntdll!KiUserApcDispatcher;
  1. 返回用户态,控制权交给 KiUserApcDispatcher;
  2. KiUserApcDispatcher 调用 NormalRoutine(NormalContext, SystemArgument1, SystemArgument2);
  3. NormalRoutine 返回后,KiUserApcDispatcher 调用 NtContinue 恢复原 trap frame,线程从被中断处继续。

3.4 Alertable Wait

线程只有在 alertable 状态才会派发用户态 APC。以下 API 使线程进入 alertable wait:

  • SleepEx(..., TRUE)
  • WaitForSingleObjectEx(..., TRUE)
  • WaitForMultipleObjectsEx(..., TRUE)
  • SignalObjectAndWait(..., TRUE)
  • GetOverlappedResultEx(alertable 变体)

关键实战问题:目标线程必须实际进入 alertable wait,APC 才会派发。许多线程从不进入 alertable wait(如 GUI 线程的消息循环、纯计算线程),对它们排队 APC 会一直挂起在队列中不执行。

3.5 哪些线程适合作为 APC 目标

  • 服务线程:svchost.exe 中的服务线程经常在 WaitForSingleObjectEx 上等待事件,且常 alertable;
  • 工作线程:线程池工作线程(ntdll!TppWorkerThread)在 alertable wait 等待工作项;
  • I/O 线程:使用 overlapped I/O 的线程;
  • 新创建的挂起线程:见 Early Bird。

不适合:GUI 消息循环线程(GetMessage 非 alertable)、纯 CPU 计算线程。


4. APC Injection 技术

4.1 经典流程

HANDLE hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid);
LPVOID addr = VirtualAllocEx(hProc, NULL, shellcodeSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, addr, shellcode, shellcodeSize, NULL);
DWORD oldProt;
VirtualProtectEx(hProc, addr, shellcodeSize, PAGE_EXECUTE_READ, &oldProt);

HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
NtQueueApcThread(hThread, addr, NULL, NULL, NULL);
// 等待目标线程进入 alertable wait,APC 自动派发

4.2 关键实现细节

4.2.1 内存属性

  • 先分配 PAGE_READWRITE 写入,再 VirtualProtectEx 改为 PAGE_EXECUTE_READ,避免直接分配 RWX(RWX 是强特征);
  • 但 VirtualProtectEx 提升至可执行仍触发 ETW-TI EtwTiLogProtectExecVm。

4.2.2 APC 例程地址

NtQueueApcThread 的第二个参数是目标进程地址空间中的例程地址。攻击者直接传 shellcode 地址。但 EDR 在 hook 中检查该地址:

  • 若落在 MEM_PRIVATE → 强可疑;
  • 若落在 MEM_IMAGE 但非合法导出函数 → 可疑;
  • 若落在 MEM_IMAGE 的合法函数(如 LoadLibraryW)→ 较不可疑,但 LoadLibraryW 加载非签名 DLL 仍被映像加载监控。

进阶:将 shellcode 写入一个已 Module Stomping 的合法 DLL 的 .text,使 APC 例程地址通过\"映像范围\"检查(见第三节组合)。

4.2.3 目标线程选择

  • 枚举目标进程线程:NtQuerySystemInformation(SystemProcessInformation) 获取所有 TID;
  • 优先选择工作线程/服务线程(更可能 alertable);
  • 若目标线程不 alertable,APC 永不派发——需选择或制造 alertable 线程。

4.3 EDR 对 APC Injection 的检测

检测点 信号源 检测逻辑
NtQueueApcThread 调用 inline hook 检查例程地址合法性、目标线程是否跨进程
APC 排队 ETW-TI EtwTiLogQueueApc 内核埋点,记录排队者/目标/例程地址
APC 派发 ETW-TI EtwTiLogApcCapture 派发时感知,可检查例程地址
跨进程内存操作 ETW-TI EtwTiLogAllocExecVm 、EtwTiLogReadWriteVm
例程地址内存属性 内存扫描 派发后扫描例程地址所在内存
调用栈 栈回溯 APC 派发时栈帧不自然(无合法调用方)

注意:APC Injection 不触发PsSetCreateThreadNotifyRoutine 和 EtwTiLogCreateThread——这是相对 CreateRemoteThread 的核心收益。

4.4 规避策略

  1. 避免跨进程:在 loader 自身进程内创建一个 alertable 线程,对其排队 APC。由于不跨进程,ETW-TI 的\"跨进程\"信号不触发。但 loader 自身仍需不被怀疑。
  2. 例程地址合法化:结合 Module Stomping,使例程地址落在合法映像。
  3. \\使用 NtQueueApcThreadEx / Ex2\\:较新变体支持更多上下文,但同样被 hook/ETW-TI 感知。
  4. APC 内容伪装:排队一个指向 LoadLibraryW 的 APC,参数为 DLL 路径——但 DLL 加载仍被监控。可结合反射加载(但反射加载又有自身信号)。

5. Early Bird APC Injection


不再只伪装IT岗:朝鲜远程工作者渗透销售医疗机构等岗位" 网络安全文章

不再只伪装IT岗:朝鲜远程工作者渗透销售医疗机构等岗位"

朝鲜关联组织FAMOUSCHOLLIMA通过伪造身份渗透医疗金融销售等远程岗位,利用VPN代理掩盖位置并窃取数据。关键特征包括硬件级控制设备PiKVM接入、证件照片篡改及EXIF异常、非工作时段活跃。建议企业完善背景调查、核验入职材料元数据、监控终端USB设备接入及多源日志交叉分析,融合安全与HR团队协同处置以防范此类社会工程学攻击。
用户态异步执行注入-APC与Fiber" 网络安全文章

用户态异步执行注入-APC与Fiber"

本文讲解Windows用户态异步执行注入技术,先回顾CreateRemoteThread注入的完整EDR检测链,再深入剖析APC内核数据结构、KiDeliverApc派发机制、经典APC注入流程、EarlyBird变体及Fiber原理与注入方法,指出异步执行可消除跨进程线程创建这一最强检测信号,但跨进程内存操作仍受ETW-TI监控,并给出选择alertable目标线程、结合ModuleStomping合法化例程地址等规避建议。
【0828】重保演习每周情报汇总" 网络安全文章

【0828】重保演习每周情报汇总"

攻防演练期间烽火台实验室每周情报汇总:本周新增11条漏洞累计51条,涉及云ERP的SSRF、反序列化、任意密码重置及文件读写,水利平台硬编码、车牌识别信息泄露、调度客户端未授权访问等,各漏洞附自查指纹、编号与临时修复建议,相关防护与检测规则已同步更新至盛邦安全RayWAF、RayIDP、RayScan等多款产品。
-8.0%!网络安全行业收入连续12个季度下滑" 网络安全文章

-8.0%!网络安全行业收入连续12个季度下滑"

2026年第二季度网络安全行业收入连续第12个季度下滑,18家样本公司合计收入51.74亿元,同比下降8.0%,降幅较一季度扩大6个百分点。奇安信和天融信合计减少4.46亿元,占净减少额99.4%。11家公司收入下降,8家为两位数降幅,行业收入拐点仍未出现,需求与竞争压力持续。
评论:0   参与:  0