首页 > 开发 > PowerShell > 正文

如何防范PowerShell代码注入漏洞绕过受限语言模式

2020-05-30 20:21:24
字体:
来源:转载
供稿:网友

导语:受限语言模式是缓解PowerShell攻击的一种方式,能够阻止执行任意未签名的代码。

介绍

受限语言模式是缓解PowerShell攻击的一种方式,能够阻止执行任意未签名的代码。当Device Guard或者AppLocker处于强制模式时,它是最实际有效的强制安全措施,因为未被策略允许的任何脚本或者模块都位于受限语言模式下,这严重限制了攻击者执行未签名的代码。通过限制语言模式限制了Add-Type的调用。限制Add-Type明显是考虑到了它能编译并加载任意的C#代码到你的运行空间中去。

但策略允许的PowerShell代码运行在“Full Language”模式下,允许执行Add-Type。这样,微软签名的PowerShell代码就能调用Add-Type。不相信吗?运行下面的命令你就会发现我是正确的。

利用

现在想象如果以下的PowerShell模块代码(暂且被称为“VulnModule”)是由Microsoft签名的。

ls C:* -Recurse -Include '*.ps1', '*.psm1' | Select-String -Pattern 'Add-Type' | Sort Path -Unique | % { Get-AuthenticodeSignature -FilePath $_.Path } | ? { $_.SignerCertificate.Subject -match 'Microsoft' }

那么有什么可以影响来自受限语言模式的Add-Type的输入呢?

让我们一起思考下吧:

1. Add-Type作为类型定义传递给一个全局变量。因为它是全局的,它可以被任何人访问,包括我们和攻击者。
2. 问题是,签名的代码先于调用Add-Type就定义了全局变量,因此如果我们使用自定义的恶意C#代码,这将会被合法的代码覆盖。

3. 你知道能用Set-Variable cmdlet来设置变量只读吗?你知道我现在在想什么了吧?

武器化

好的,为了从受限语言模式注入代码到Add-Type,攻击者需要将它们的恶意代码定义为只读变量,从而设置全局“Source”变量来拒绝签名的代码。这是一个武器化的概念证明:

  $Global:Source = @'  public class Test {    public static string PrintString(string inputString) {      return inputString;    }  }'@Add-Type -TypeDefinition $Global:Source

简要说明下Add-Type注入缺陷。受限语言模式的一个限制是你不能调用非白名单类的.NET方法,但有两个例外:属性(getter方法)和ToString方法。在上面的PoC中,我选择了实现一个静态的ToString方法,因为ToString允许传递参数(getter不行)。我的类也是静态的,因为.NET类的白名单只在New-Object实例化对象时适用。

那么上面的漏洞代码是否听起来不切实际呢?你可以这么认为,但是Microsoft.PowerShell.ODataUtils 模块中的Microsoft.PowerShell.ODataUtils也有这个漏洞。微软在 CVE-2017-0215, CVE-2017-0216, CVE-2017-0219中修复了它。说实话,我不太记得了。Matt Nelson 和我都报告了这些注入bug。

缓解攻击

尽管微软在推动解决这个漏洞,我们有什么可以做的呢?

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表