技术分享 | 如何利用COM绕过AppLocker CLM

栏目: ASP.NET · 发布时间: 5年前

内容简介:受限语言模式是PowerShell限制用户访问高级功能的一种方式,暂且不管微软怎么说的,这个功能本质上是一种安全控制措施,很多防御者可以利用这种功能来阻止类似“Invoke-Mimikatz”这样的工具。不管微软方面是怎么看待的,这个功能目前已经被大家当做一种安全控制功能了,因为它可以帮助防御人员阻止类似“Invoke-Mimikatz”这样的工具运行。在这篇文章中,我将告诉大家如何以非管理员用户的身份绕过这种保护机制。

严正声明:本文仅用于教育和讨论目的,请勿用于非法用途。

前言

受限语言模式是PowerShell限制用户访问高级功能的一种方式,暂且不管微软怎么说的,这个功能本质上是一种安全控制措施,很多防御者可以利用这种功能来阻止类似“Invoke-Mimikatz”这样的工具。

不管微软方面是怎么看待的,这个功能目前已经被大家当做一种安全控制功能了,因为它可以帮助防御人员阻止类似“Invoke-Mimikatz”这样的 工具 运行。在这篇文章中,我将告诉大家如何以非管理员用户的身份绕过这种保护机制。

技术分享 | 如何利用COM绕过AppLocker CLM

直奔主题

我们首先要做的就是在我们的实验环境中启用AppLocker。这篇文章中,在启用脚本限时时,我将使用Windows分配的默认角色。开启了应用程序识别服务之后,我们就可以使用下列命令来确保CLM已成功启用:

$ExecutionContext.SessionState.LanguageMode

这里我们可以看到程序返回的值,这表明我们已经处于受限环境了。我们还可以在PowerShell中尝试执行受限命令来二次确认:

Add-Type"namespace test { }"

技术分享 | 如何利用COM绕过AppLocker CLM

既然我们已经启用了CLM,那我们应该怎么绕过它呢?

AppLockerCLM中的New-Object

有趣的是,当我在寻找CLM的攻击面时,我发现当CLM通过AppLocker启用时,会出现一个New-Object,大家看看下面这条命令:

New-Object-ComObject WScript.Shell

这样一来,我们好像就可以直接在PowerShell里面修改PowerShell进程了,因为COM对象通过DLL暴露在外,并且能够直接被加载到调用进程中。那么我们如何才能创建一个待加载的COM对象呢?如果我们查看ProcMon调用New-Object -ComObject xpntest的过程,我们就可以看到大量针对HKEY_CURRENT_USER注册表项的请求:

技术分享 | 如何利用COM绕过AppLocker CLM

研究了半天之后,我们发现,我们可以在下面这段脚本的帮助下直接在HKCU中创建所需要的注册表键:

技术分享 | 如何利用COM绕过AppLocker CLM

现在,如果我们尝试加载我们自己的COM对象,我们会发现自定义的DLL会被加载到PowerShell进程空间中:

技术分享 | 如何利用COM绕过AppLocker CLM 技术分享 | 如何利用COM绕过AppLocker CLM

这就很棒了,现在我们已经可以向PowerShell中注入任意DLL了,无需调用动作太大的CreateRemoteThread或者WriteProcessMemory,而且所有操作都是在受限场景下实现的。但我们的目标是绕过CLM,如何利用我们的非托管DLL加载方式来实现?我们可以利用.NET CLR,或者更确切一点,我们可以通过非托管DLL加载.NET CLR来调用.NET 工具。

非托管DLL->托管DLL->反射

现在我们可以使用Cobalt Strike这样的工具,这款工具提供了Execute-Assembly功能,可以将CLR加载到非托管进程中,我在 GIST 上给大家提供了一份代码,它可以独立完成这个任务:

技术分享 | 如何利用COM绕过AppLocker CLM

这里我就不详细介绍代码内容了,感兴趣的同学可以参考微软给出的【官方示例】,这段代码可以让DLL加载.NET CLR,并加载.NET工具,最后将执行权限转移给特定的方法。

完成之后,我们就可以访问.NET了,重要的是,我们可以访问的是.NET的反射功能,接下来我们要做的就是如何启用/禁用CLM了。

System.Management.Automation.Runspaces.RunspaceBase.LanguageMode属性中有一个地方可以识别当前的语言模式。由于我们要使用反射技术,因此需要找到引用Runspace的变量,然后在运行时修改该变量。我觉得 最好的实现方法 就是利用Runspaces.Runspace.DefaultRunspace.SessionStateProxy.LanguageMode:

技术分享 | 如何利用COM绕过AppLocker CLM

编译为.NET工具之后,我们就可以利用反射的方式来禁用CLM了,这里我们只需要创建并运行一个PowerShell脚本【 下载地址 】即可:

技术分享 | 如何利用COM绕过AppLocker CLM

这样就搞定啦!

演示视频

攻击原理

为什么COM可以绕过这种保护机制?PowerShell又是如何处理COM加载的呢?我们可以在SystemPolicy.IsClassInApprovedList方法中找到答案,这个方法可以用来检查程序是否允许我们向New-Object提供CLSID。下面这段代码负责的是核心检测功能:

if(SystemPolicy.WldpNativeMethods.WldpIsClassInApprovedList(ref clsid, refwldp_HOST_INFORMATION, ref num, 0u) >= 0 && num == 1) { … }

这个函数调用只是WldpIsClassInApprovedList函数(位于wldp.dll中)的一个封装函数,而后者主要用来检查CLSID是否匹配DeviceGuard(现已更名为Windows Defender Application Control)策略。由于该方法没有考虑到AppLocker,这意味着任何通过检查的CLSID都可以使用。

意外发现

在测试这项技术的过程中,我遇到过一次奇怪的情况,当我们使用如下方法设置CLM时,这项技术就无法正常使用了:

$ExecutionContext.SessionState.LanguageMode= "ConstrainedLanguage"

这就很尴尬了,因为之前我都是使用上述命令来测试Payload的,现在有什么区别吗?重新检查了我们的反汇编代码之后,我在Microsoft.Powershell.Commands.Utility.dll那里找到了问题的答案。这个文件的具体路径位于NewObjectCommand类的BeginProcessing方法中:

技术分享 | 如何利用COM绕过AppLocker CLM

这里我们可以看到上述的代码中存在两条代码路径,具体使用哪一条取决于CLM的启用方式。如果SystemPolicy.GetSystemLockdownPolicy返回的是Enfore,即执行第一条路径,此时的AppLocker或者DeviceGuard将被启用。如果直接设置这个参数,则会直接进入if (!flag)…代码段,此时就会抛出异常。实际上,CLM会根据具体的启用方法(是通过AppLocker、DeviceGuard,还是通过LanguageMode属性来启用)而有不同的行为。

本文介绍的方法并不是绕过CLM的唯一方法,即使粗略分析PowerShell,我们也能找到实现类似效果的其他方法。如果大家对这个topic感兴趣的话,可以看看Oddvar Moe在Debycon大会上的演讲【 传送门 】。

* 参考来源: mdsec ,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM


以上所述就是小编给大家介绍的《技术分享 | 如何利用COM绕过AppLocker CLM》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

互联网产品运营:产品经理的10堂精英课

互联网产品运营:产品经理的10堂精英课

丁华、聂嵘海、王晶 / 电子工业出版社 / 2017-5 / 59

《互联网产品运营:产品经理的10堂精英课》共有10章,前9章分别从互联网产品运营的9个点入手,最后一章辅以案例,分析当下市场热门产品的运营模式。 第1章点明在运营产品之前需要经过缜密的策划,这样才能有明确的运营方向;第2章讲述产品运营的定位,有了准确的定位,运营才不会走偏;第3章描述用户运营,用户是一款产品的根本,没有用户,产品就是死的;第4章讲述内容运营的技巧,产品内容要怎么运营才能受到用......一起来看看 《互联网产品运营:产品经理的10堂精英课》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具