你永远难以忘记的pool party:用windows线程池的新进程注入技术
字数 2296 2025-08-19 12:41:40
Windows线程池进程注入技术(Pool Party)深度解析
背景概述
进程注入是一种在目标进程中执行任意代码的规避技术,通常由三个核心函数组成:
- 分配函数:在目标进程上分配内存(如VirtualAllocEx)
- 写入函数:向分配的内存写入恶意代码(如WriteProcessMemory)
- 执行函数:执行编写的恶意代码(如CreateRemoteThread)
现代EDR主要基于执行函数进行检测,而分配和写入函数通常不会被检测。SafeBreach Labs团队发现了8种利用Windows线程池的新型进程注入技术,统称为"Pool Party"变体。
Windows用户模式线程池架构
Windows线程池由三个主要组件构成:
- 工作线程工厂(Worker Factories):管理工作线程的创建和终止
- 任务队列:存放常规工作项
- I/O完成队列:存放异步工作项
- 计时器队列:存放计时器工作项
线程池支持多种工作项类型,每种类型有对应的辅助结构体:
| 工作项类型 | 辅助结构体 | 触发方式 |
|---|---|---|
| TP_WORK | TP_TASK | 立即执行 |
| TP_IO | TP_DIRECT | I/O操作完成时 |
| TP_TIMER | TP_TIMER | 计时器到期时 |
| TP_WAIT | TP_DIRECT | 等待对象触发时 |
| TP_ALPC | TP_DIRECT | ALPC消息到达时 |
| TP_JOB | TP_DIRECT | 作业对象事件发生时 |
Pool Party技术详解
变体1:攻击工作线程工厂
-
获取工作线程工厂句柄:
- 使用
DuplicateHandle()API复制目标进程的工作线程工厂句柄 - 工作线程工厂默认存在于所有Windows进程中
- 使用
-
获取启动例程地址:
- 使用
NtQueryInformationWorkerFactory系统调用查询WorkerFactoryBasicInformation - 获取
StartRoutine字段值
- 使用
-
覆盖启动例程:
- 使用内存写入函数覆盖
StartRoutine指向的代码 - 或直接修改
StartRoutine指向shellcode
- 使用内存写入函数覆盖
-
触发执行:
- 使用
NtSetInformationWorkerFactory设置WorkerFactoryThreadMinimum - 设置最小线程数大于当前运行线程数,强制创建新工作线程
- 使用
变体2:攻击TP_WORK工作项
-
获取线程池结构:
- 通过
NtQueryInformationWorkerFactory获取TP_POOL结构指针 - 定位任务队列(双向链表)
- 通过
-
注入恶意任务:
- 伪造
TP_TASK结构体 - 修改任务队列链表指针,插入恶意任务
- 或直接覆盖现有任务
- 伪造
-
触发执行:
- 工作线程会自动从队列中取出并执行任务
- 无需额外触发操作
变体3-7:攻击异步工作项(TP_IO/TP_WAIT/TP_ALPC/TP_JOB)
-
获取I/O完成队列句柄:
- 使用
DuplicateHandle()复制目标进程的I/O完成队列句柄
- 使用
-
关联对象与队列:
- 对于TP_IO:使用
TpBindFileToDirect将文件对象与队列关联 - 对于TP_WAIT:将事件对象与队列关联
- 对于TP_ALPC:将ALPC端口与队列关联
- 对于TP_JOB:将作业对象与队列关联
- 对于TP_IO:使用
-
注入恶意工作项:
- 伪造
TP_DIRECT结构体 - 使用
NtSetIoCompletion直接将结构体排入队列 - 或通过关联对象操作间接触发
- 伪造
-
触发执行:
- 文件操作(读/写)
- 事件触发
- ALPC消息到达
- 作业对象事件
变体8:攻击TP_TIMER工作项
-
获取计时器队列:
- 从
TP_POOL结构中定位计时器队列 - 获取计时器对象句柄(使用
DuplicateHandle)
- 从
-
注入恶意计时器:
- 伪造
TP_TIMER结构体 - 修改
WindowStartLinks和WindowEndLinks链表指针 - 将恶意计时器插入队列
- 伪造
-
配置计时器:
- 使用
SetThreadpoolTimer配置计时器参数 - 或直接操作计时器对象
- 使用
-
触发执行:
- 计时器自动到期时执行
- 攻击者可在触发前清除所有痕迹
技术优势分析
-
普遍适用性:
- 所有Windows进程默认都有线程池
- 不受特定进程状态限制
-
隐蔽性强:
- 执行由合法操作触发(文件操作、计时器等)
- 不依赖传统注入API
-
持久性:
- 特别是计时器变体,可在攻击者退出后触发
-
绕过检测:
- 测试的5种EDR均未检测到(Cortex, SentinelOne, CrowdStrike, Defender, Cybereason)
防御建议
-
EDR增强检测:
- 监控线程池结构修改
- 检测异常的线程池操作
-
行为分析:
- 不依赖进程身份信任
- 分析线程行为的合理性
-
内存保护:
- 保护关键线程池数据结构
- 监控关键代码段修改
-
系统加固:
- 限制跨进程句柄复制
- 加强内核对象访问控制
总结
Pool Party技术通过滥用Windows线程池机制,实现了高度隐蔽的进程注入。8种变体覆盖了线程池的各个组件,提供了多样化的注入途径。这些技术展示了现代EDR在检测非传统注入技术上的局限性,强调了防御方需要采用更全面的检测方法。