如何通过COM绕过AppLocker的约束语言模式(CLM)
字数 1240 2025-08-20 18:18:17
绕过AppLocker约束语言模式(CLM)的COM技术详解
1. 约束语言模式(CLM)概述
约束语言模式(Constrained Language Mode, CLM)是PowerShell的一种安全限制机制,主要用于:
- 限制PowerShell的访问权限
- 禁止使用
Add-Type等功能 - 阻止利用反射方法启动post-exploitation工具
- 防御如"Invoke-Mimikatz"等依赖反射技术的工具
检查当前语言模式:
$ExecutionContext.SessionState.LanguageMode
在CLM下会返回"ConstrainedLanguage"
2. 环境准备与验证
-
启用AppLocker:
- 使用Windows默认规则集配置CLM
- 启动Application Identity服务
-
验证CLM是否生效:
Add-Type "namespace test { }"
在CLM下此命令会失败
3. COM对象绕过技术
3.1 关键发现
通过AppLocker启用CLM时,New-Object -ComObject仍可工作(有一定限制):
New-Object -ComObject WScript.Shell
COM对象可以通过DLL加载到调用进程中,这为绕过CLM提供了可能。
3.2 注册自定义COM对象
- 在HKCU中创建注册表项(示例脚本未给出具体内容)
- 加载自定义DLL到PowerShell进程空间
3.3 技术实现流程
- 创建自定义COM DLL
- 通过注册表注册COM对象
- 使用
New-Object -ComObject加载 - DLL加载到PowerShell进程空间
4. 从非托管DLL到托管DLL
4.1 加载.NET CLR
通过非托管DLL加载.NET CLR,进而调用.NET程序集:
- 非托管DLL加载.NET CLR
- CLR加载.NET程序集
- 执行指定方法
4.2 反射技术应用
利用反射访问和修改关键属性:
Runspaces.Runspace.DefaultRunspace.SessionStateProxy.LanguageMode
通过反射可以禁用CLM限制。
5. 完整绕过流程
-
创建包含以下功能的DLL:
- 加载.NET CLR
- 加载自定义.NET程序集
- 使用反射修改LanguageMode属性
-
注册并加载该COM对象
-
执行PowerShell脚本完成CLM绕过
6. 技术原理分析
6.1 安全检查机制
关键检查函数:
SystemPolicy.IsClassInApprovedList
实际调用:
SystemPolicy.WldpNativeMethods.WldpIsClassInApprovedList
6.2 绕过成功原因
WldpIsClassInApprovedList只检查DeviceGuard策略- 不适用于AppLocker策略
- 导致任何CLSID都能通过检查
7. 特殊情况说明
直接设置语言模式时技术会失效:
$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
原因分析:
SystemPolicy.GetSystemLockdownPolicy返回不同值- AppLocker/DeviceGuard启用时返回"Enforce"
- 直接设置时进入不同代码路径并抛出异常
8. 防御建议
- 监控COM对象加载行为
- 限制非标准COM对象注册
- 结合DeviceGuard策略使用
- 监控LanguageMode属性修改
9. 扩展思考
- 此技术展示了CLM实现的不一致性
- 反映了安全边界设计中的潜在缺陷
- 提示了多种可能的绕过路径(如Oddvar Moe的研究)