使用COM将代码注入到受Windows保护的进程中
字数 1744 2025-08-27 12:33:31
通过COM将代码注入受Windows保护的进程(PPL)技术分析
1. Windows保护进程背景
1.1 保护进程模型发展
-
Vista引入Protected Process (PP):
- 最初为DRM进程设计
- 严格限制加载的DLL(仅限操作系统安装的代码子集)
- 可执行文件必须使用特定Microsoft证书签名
-
Windows 8.1引入Protected Process Light (PPL):
- 放宽DLL加载限制
- 引入不同签名要求
- 添加签名级别区分不同类型的受保护进程
1.2 签名级别体系
- 层级关系:
- 同级或更低级别PPL可完全访问同级或更低级别进程
- PPL不能完全访问任何级别的PP
- Anti-Malware PPL是特殊级别,允许第三方通过ELAM证书添加签名密钥
2. 技术原理与绕过方法
2.1 原始脚本注入技术(已修复)
-
实现方式:
- 通过加载COM对象将JScript代码注入PPL
- 利用脚本引擎DLL(jscript.dll、scrrun.dll等)
-
微软修复方案:
- 内核CI.dll中添加黑名单检查(5个脚本相关DLL)
- 修改DLL资源会导致签名失效
2.2 新攻击目标选择标准
- 从普通用户账户运行(非管理员)
- 目标是最高签名级别(PPL-WindowsTCB)
- 攻击面大的受保护进程
2.3 攻击NGEN进程(MSCORSVW.EXE)
2.3.1 选择原因
- 不需要管理员权限
- 加载.NET框架和COM组件
- 作为PPL运行(CodeGen签名级别)
2.3.2 COM通信分析
-
进程启动参数:
MSCORSVW -StartupEvent A -InterruptEvent B -NGENProcess C -Pipe D -
关键函数:
NGenWorkerEmbedding- 通过管道传输封送处理的COM对象(ICorSvcBindToWorker)
- 使用类型库生成代理/存根
2.3.3 类型混淆攻击
- 攻击步骤:
-
修改类型库定义:
- 将接口指针参数改为整数或其他类型
- 通过注册表或ROT替换类型库
-
代理/存根处理差异:
- 代理按修改后的类型库封送参数
- 存根按原始定义解封送
- 导致类型混淆和任意指针解引用
-
构造FakeObject结构:
struct FakeObject { BSTR FakeVTable; };- 通过BSTR控制VTable内容
2.3.4 结合KnownDlls机制
-
KnownDlls加载原理:
LdrpFindKnownDll通过LdrpKnownDllDirectoryHandle查找DLL- 完全PP禁用KnownDlls,但PPL仍可使用
-
攻击实现:
- 继承伪造的KnownDlls目录句柄到PPL进程
- 使用类型混淆修改
LdrpKnownDllDirectoryHandle值 - 通过
ICorSvcPooledWorker::CanReuseProcess实现内存写入
-
DLL注入:
- 放置恶意DLL到伪造的KnownDlls目录
- 诱导PPL加载System32中已知名称的DLL
- 执行任意代码(包括DllMain)
2.4 提升到PPL-WindowsTCB
-
缓存签名机制:
- 利用
NtCreateSection自动缓存签名 - 需要设置特殊标志(0x40)才能加载到PPL
- 利用
-
实现步骤:
- 伪造缓存签名DLL
- 通过WERFAULTSECURE.EXE(PPL-WindowsTCB)加载
- 利用CVE-2018-8449绕过设备保护
3. 防御与缓解
3.1 微软修复措施
- 脚本引擎DLL黑名单
- 修复缓存签名机制绕过(CVE-2018-8449)
- 限制PPL对KnownDlls的访问
3.2 防护建议
- 及时安装安全更新
- 监控可疑的进程注入行为
- 限制普通用户对COM和类型库的修改权限
- 使用更高安全机制(如VSM/IUM)替代PPL
4. 影响范围
- 受影响系统:Windows 10 1803及更早版本
- 攻击前提:普通用户权限
- 潜在危害:
- 绕过文件/资源保护(如Windows Store)
- 管理员权限下可攻击CSRSS、Windows Defender等关键进程
5. 技术总结
本技术通过组合利用以下漏洞实现PPL注入:
- COM类型库类型混淆
- KnownDlls机制缺陷
- 缓存签名验证逻辑问题
这种攻击方式展示了即使在高强度保护机制下,通过巧妙组合多个"非安全边界"问题,仍可能实现权限提升和代码执行。