你永远难以忘记的pool party:用windows线程池的新进程注入技术
字数 2296 2025-08-19 12:41:40

Windows线程池进程注入技术(Pool Party)深度解析

背景概述

进程注入是一种在目标进程中执行任意代码的规避技术,通常由三个核心函数组成:

  1. 分配函数:在目标进程上分配内存(如VirtualAllocEx)
  2. 写入函数:向分配的内存写入恶意代码(如WriteProcessMemory)
  3. 执行函数:执行编写的恶意代码(如CreateRemoteThread)

现代EDR主要基于执行函数进行检测,而分配和写入函数通常不会被检测。SafeBreach Labs团队发现了8种利用Windows线程池的新型进程注入技术,统称为"Pool Party"变体。

Windows用户模式线程池架构

Windows线程池由三个主要组件构成:

  1. 工作线程工厂(Worker Factories):管理工作线程的创建和终止
  2. 任务队列:存放常规工作项
  3. I/O完成队列:存放异步工作项
  4. 计时器队列:存放计时器工作项

线程池支持多种工作项类型,每种类型有对应的辅助结构体:

工作项类型 辅助结构体 触发方式
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:攻击工作线程工厂

  1. 获取工作线程工厂句柄

    • 使用DuplicateHandle()API复制目标进程的工作线程工厂句柄
    • 工作线程工厂默认存在于所有Windows进程中
  2. 获取启动例程地址

    • 使用NtQueryInformationWorkerFactory系统调用查询WorkerFactoryBasicInformation
    • 获取StartRoutine字段值
  3. 覆盖启动例程

    • 使用内存写入函数覆盖StartRoutine指向的代码
    • 或直接修改StartRoutine指向shellcode
  4. 触发执行

    • 使用NtSetInformationWorkerFactory设置WorkerFactoryThreadMinimum
    • 设置最小线程数大于当前运行线程数,强制创建新工作线程

变体2:攻击TP_WORK工作项

  1. 获取线程池结构

    • 通过NtQueryInformationWorkerFactory获取TP_POOL结构指针
    • 定位任务队列(双向链表)
  2. 注入恶意任务

    • 伪造TP_TASK结构体
    • 修改任务队列链表指针,插入恶意任务
    • 或直接覆盖现有任务
  3. 触发执行

    • 工作线程会自动从队列中取出并执行任务
    • 无需额外触发操作

变体3-7:攻击异步工作项(TP_IO/TP_WAIT/TP_ALPC/TP_JOB)

  1. 获取I/O完成队列句柄

    • 使用DuplicateHandle()复制目标进程的I/O完成队列句柄
  2. 关联对象与队列

    • 对于TP_IO:使用TpBindFileToDirect将文件对象与队列关联
    • 对于TP_WAIT:将事件对象与队列关联
    • 对于TP_ALPC:将ALPC端口与队列关联
    • 对于TP_JOB:将作业对象与队列关联
  3. 注入恶意工作项

    • 伪造TP_DIRECT结构体
    • 使用NtSetIoCompletion直接将结构体排入队列
    • 或通过关联对象操作间接触发
  4. 触发执行

    • 文件操作(读/写)
    • 事件触发
    • ALPC消息到达
    • 作业对象事件

变体8:攻击TP_TIMER工作项

  1. 获取计时器队列

    • TP_POOL结构中定位计时器队列
    • 获取计时器对象句柄(使用DuplicateHandle)
  2. 注入恶意计时器

    • 伪造TP_TIMER结构体
    • 修改WindowStartLinksWindowEndLinks链表指针
    • 将恶意计时器插入队列
  3. 配置计时器

    • 使用SetThreadpoolTimer配置计时器参数
    • 或直接操作计时器对象
  4. 触发执行

    • 计时器自动到期时执行
    • 攻击者可在触发前清除所有痕迹

技术优势分析

  1. 普遍适用性

    • 所有Windows进程默认都有线程池
    • 不受特定进程状态限制
  2. 隐蔽性强

    • 执行由合法操作触发(文件操作、计时器等)
    • 不依赖传统注入API
  3. 持久性

    • 特别是计时器变体,可在攻击者退出后触发
  4. 绕过检测

    • 测试的5种EDR均未检测到(Cortex, SentinelOne, CrowdStrike, Defender, Cybereason)

防御建议

  1. EDR增强检测

    • 监控线程池结构修改
    • 检测异常的线程池操作
  2. 行为分析

    • 不依赖进程身份信任
    • 分析线程行为的合理性
  3. 内存保护

    • 保护关键线程池数据结构
    • 监控关键代码段修改
  4. 系统加固

    • 限制跨进程句柄复制
    • 加强内核对象访问控制

总结

Pool Party技术通过滥用Windows线程池机制,实现了高度隐蔽的进程注入。8种变体覆盖了线程池的各个组件,提供了多样化的注入途径。这些技术展示了现代EDR在检测非传统注入技术上的局限性,强调了防御方需要采用更全面的检测方法。

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_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在检测非传统注入技术上的局限性,强调了防御方需要采用更全面的检测方法。