深度分析CVE-2017-0007是如何绕过防护措施的

简介: 本文讲的是深度分析CVE-2017-0007是如何绕过防护措施的,简而言之,设备用户模块代码完整性防护措施是指阻止没有授权的程序运行,除非他在windows当中经过了信任授权。当然这一防护措施只有windows当中存在,并且它存在于Powershell中防护语言模式(Contrainted Language mode)。
本文讲的是 深度分析CVE-2017-0007是如何绕过防护措施的简而言之,设备用户模块代码完整性防护措施是指阻止没有授权的程序运行,除非他在windows当中经过了信任授权。当然这一防护措施只有windows当中存在,并且它存在于Powershell中防护语言模式( Contrainted Language mode )。当我研究开启防护措施的机器上是如何执行脚本一段时间后,我最后找到了一种方法可以在开启防护措施的系统中执行任意脚本。在向MSRC报告问题后,最终将该漏洞命名为CVE-2017-0007(MS17-012),并且已经修补。这个特定的错误只会影响PowerShell和Windows脚本主机,而不会影响编译代码。

这个漏洞是我第一个CVE,同时也是我第一次分析补丁。所以这篇文章不仅介绍了漏洞的生成,还将会逆向分析补丁如何工作。由于这是我第一次做这种工作,所以可能会有一些错误。如果在文章中出现了错误,请在下方评论告诉我,我加以改正。

当执行一个拥有签名的程序时,wintrust.dll会验证这个文件的签名。这是文件执行后查看得知的。事实上,如果你使用有微软签名的脚本对这个程序进行修改,那么这个程序的完整性就会受到破坏,并且签名不会有效。此类验证对于设备防护至关重要,它的唯一目的就是防止没有签名或者不受信任的代码运行。

CVE-2017-0007就绕过了这种防护措施,允许你通过简单地修改先前已经获得批准的签名的脚本来运行任何未签名的代码。这种情况,我们选择有一个微软签名的脚本是为了能够在开启设备防护措施的机器上运行。举个例子,如果我们尝试在PowerShell中运行一个没有签名的脚本(可以是实例化网站的脚本),会因为PowerShell处于防护语言模式(Constrained
Language
mode)导致执行失败。通过部署代码的完整性策略可以批准任何有签名并且受信任的Powershell脚本在任何语言模式(Fulllanguage)下没有任何限制的运行。在这种情况,我们的代码并没有签名而且也不是受信任代码,所以他在防护语言模式不会被执行成功。

深度分析CVE-2017-0007是如何绕过防护措施的

很幸运的是,微软有能够进行签名的脚本,你可以使用sigcheck或者Powershell命令Get-AuthenticodeSignature。在这种情况,我从Windows SDK中抓取到了一个具有签名的Powershell脚本,并且将它重命名为:"MicrosoftSigned.ps1"

深度分析CVE-2017-0007是如何绕过防护措施的

像这样具有签名的脚本,它们往往在正文中被嵌入一个认证签名。如果你修改了这个文件的任何内容,则这个文件的完整性就会破坏,那么这个签名就会无效。你可以简单的从已经存在签名文件中复制签名到一个没有签名的文件中。

深度分析CVE-2017-0007是如何绕过防护措施的

就像你看到的这样,这个脚本的内容已经被我们自己的代码替换了,并且sigcheck脚本给出“这个文件的签名无效”的提示。这意味着文件的完整性已经遭到了破坏,并且代码会被阻止运行,不过确实会这样吗?

深度分析CVE-2017-0007是如何绕过防护措施的

如上图所示,尽管我们的签名是无效的,但是我们已经执行了我们的程序。微软将这个漏洞命名为CVE-2017-0007,归类为:MS17-012。这个漏洞根本原因是确保文件的完整性的代码并没有验证成功,也就是验证程序没有对存在错误代码的未签名程序进行验证,最后成功执行未签名的脚本。

那么,这个漏洞的是什么造成的,并且应该如何修补这个漏洞呢?设备防护依赖于wintrust.dll去解决已签名文件的验证签名以及完整性的问题。由于这个漏洞的根本原因,所以我找到了第一个漏洞发生的位置。使用bindiff比较打补丁前的wintrust.dll(10.0.14393.0)以及打补丁后的wintrust.dll(10.0.14393.953),我发现新增了一个代码块。同时,还有一个变化,这个变化是在验证签名这一方面的唯一变化。因此,我猜出这一部分是漏洞的补丁:

深度分析CVE-2017-0007是如何绕过防护措施的

进一步查看,你可以看到从"sub_18002D0F8"中删去了一些代码:

深度分析CVE-2017-0007是如何绕过防护措施的

新添加的代码块叫做"sub_18002D104",你可以从中发现它包含一些来自"sub_18002D0F8"的代码同时一些补充。这些函数没有特定的符号,所以我们必须用他们定义的名字。或许,你可以在IDA中对这些函数进行更有意义的命名。

深度分析CVE-2017-0007是如何绕过防护措施的

上图中的文字有点小,不过我会更深一层次的解释上面代码做了什么。我不会详细的介绍如何使用bindiff,但是如果你想了解更多,你可以查看使用手册。有了漏洞发生的确切位置,我开始探索在执行未签名程序时,到底发生了什么。我们知道修复过程中,从"sub_18002D0F8"删除了一些代码,并且添加了新的代码块叫做"sub_18002D104"。所以这两处变化是个不错的起点。首先,我在IDA中打开了没有打补丁之前的wintrust.dll(10.0.14393.0),跳转到补丁中修补的地方,即:sub_18002D0F8。这个函数通过设置一些变量开始,然后他们调用:"SoftpubAuthenticode"

深度分析CVE-2017-0007是如何绕过防护措施的

查看"SoftpubAuthenticode"发现接下来它调用了"CheckValidSignature"方法:

深度分析CVE-2017-0007是如何绕过防护措施的

似乎"CheckValidSignature"这个方法会在程序执行之前验证签名或者完整性。查看这个方法的内容,可找到在返回值之前调用的最后一个方法:

深度分析CVE-2017-0007是如何绕过防护措施的

通过在最后一个函数设置一个断点,我们可以在eax寄存器中可以看到来自”CheckValidSignature”的错误代码。如下图黄色标记:

深度分析CVE-2017-0007是如何绕过防护措施的

错误代码为:"0x80096010",根据WIN SDK中的wintrust.h源码解码之后解释为:"TRUST_E_BAD_DIGEST"也就是签名错误。这就是为什么我们运行sigcheck检查未签名文件时,我们看到了"这个文件的签名无效"的原因。在"CheckValidSignature"返回之后,我们又到达了"SoftpubAuthenticode"方法。

深度分析CVE-2017-0007是如何绕过防护措施的

调用"SoftPubAuthenticode"之后,会继续调用"SoftpubCallUI"方法,接下来会返回到"sub_18002D0F8",并且在这个过程中,eax寄存器中一直都存放着"0x80096010"这个错误代码。现在我们知道了错误代码是什么,并且在哪个位置存放错误代码。现在我们可以更进一步了解为什么"CheckValidSignature"返回错误,但是我们还是可以将我们的脚本执行成功。此时,在"SoftpubAuthenticode"调用后立即在"sub_18002D0F8"中恢复执行。

深度分析CVE-2017-0007是如何绕过防护措施的

由于错误代码存放在eax寄存器中,它通过mov rax,[r12]从SoftpubAuthenticode方法返回后,直接被覆盖。
由于判断我们脚本的签名不正确的错误代码已经不存在了,所以它现在处于认证状态,并且已经被允许执行:

深度分析CVE-2017-0007是如何绕过防护措施的

我们现在已经知道了这个漏洞是如何形成的,我们现在可以看看微软是如何对漏洞进行修复的。为了去了解他的做法,我们需要下载安装补丁KB4013429。通过查看新版本的wintrust.dll(10.0.14393.953),我们可以搜索"sub_18002D104"也就是之前提到的新添加的代码块。我们现在已经知道这个漏洞的原因是寄存器中的错误代码被覆盖而导致没有被认证。我们可以看到这个补丁在”SoftPubAuthenticode”返回之后添加了一条新的调用:

深度分析CVE-2017-0007是如何绕过防护措施的

在上图中,你还可能注意到我们的错误代码存放在了ecx寄存器中,并且覆盖rcx寄存器的指令现在取决于一个跟随"jump if
zero"指令的测试指令。这就意味着我们存储在"ecx"寄存器的错误代码只有不遵循跳转的情况进行重写。在新引入的代码中,你可以发现以下内容:

这一方法根据我们对错误代码进行的操作进而返回Bool类型。添加的这一方法是用来检查调用"SoftpubAuthenticode"方法是否成功,或者检查返回的代码是不是和"0x800B0109"匹配,也就是和"CERT_E_UNTRUSTEDROOT"匹配。在这一方面,SoftpubAuthenticode返回0x800996010(TRUST_E_BAD_DIGEST),显然返回的代码与条件不一样,所以这一方法返回1,即True。

将“al”设置为“1”并返回到先前的方法后,我们可以看到这个错误是如何实际修补的:

深度分析CVE-2017-0007是如何绕过防护措施的

将"al"设置为"1"时,这一方法又对"al"的值是否是0做了判断。如果不是0,它会设置"r14b"寄存器为0(由于前一个测试指令中没有设置ZF标志)。最后判断"r14b"寄存器中的值是不是0。如果它是0,那么会跟随跳转,将重写"rcx"    寄存器这一步骤跳过(留下ecx寄存器保留我们的错误代码)。错误代码最后被验证,以及我们的脚本会在防护语言模块被拦截,导致执行失败。

深度分析CVE-2017-0007是如何绕过防护措施的




原文发布时间为:2017年4月13日
本文作者:xnianq
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。
目录
相关文章
|
6月前
|
云安全 安全 BI
CC攻击该怎么防护更好
随着互联网发展,CC攻击成为严峻的网络安全问题。这种DDoS攻击通过操纵大量主机,向目标服务器发送大量请求,导致服务器资源耗尽。应对CC攻击,可以采取以下策略:部署高防IP或SCDN服务,限制请求频率,以及使用验证码验证。德迅云安全提供一站式安全加速解决方案,包括Web应用防火墙、CDN加速和抗DDoS防护,利用AI检测、智能语义解析等技术,有效防御各种网络攻击,同时保证网站内容的快速稳定访问。通过实时数据统计和安全可视化工具,便于监控和应对安全威胁。综合运用这些方法能有效降低CC攻击影响,保障Web应用程序的安全稳定运行。
|
3月前
|
安全 物联网 网络安全
网络安全的盾牌:漏洞防御与信息保护策略
【9月更文挑战第25天】在数字时代的浪潮中,网络安全和信息安全的重要性日益凸显。本文旨在探讨网络安全漏洞的成因、加密技术的应用以及提升安全意识的必要性。通过深入浅出的分析,揭示网络攻防的复杂性和对策的多样性,强调个人和企业应如何构建坚固的防线以保护数据不受威胁。
|
2月前
|
安全 网络协议 NoSQL
SSRF漏洞深入利用与防御方案绕过技巧
SSRF漏洞深入利用与防御方案绕过技巧
127 0
|
5月前
|
传感器 数据采集 Web App开发
揭秘攻击者规避XDR检测的惯用手法及应对建议
为了更好地理解攻击者如何规避XDR系统,本文深入分析了XDR系统运营的三个关键时期:数据采集、检测分析和响应处置,并对其中容易发生的检测规避情况提出防护建议和策略。
|
4月前
|
SQL 人工智能 安全
网络安全漏洞与防御策略
在数字化时代,网络安全成为维护信息安全的关键防线。本文将探讨网络安全中常见的漏洞类型、加密技术的应用以及提升安全意识的重要性。通过分析具体案例,我们将了解如何识别和防御网络威胁,并强调个人与企业在构建网络安全体系中的作用。
|
7月前
|
安全 Java Shell
网络安全-webshell详解(原理、检测与防御)
网络安全-webshell详解(原理、检测与防御)
826 1
|
开发框架 安全 JavaScript
网络安全-文件上传漏洞的原理、攻击与防御
网络安全-文件上传漏洞的原理、攻击与防御
673 0
网络安全-文件上传漏洞的原理、攻击与防御
|
SQL 存储 安全
web安全攻击方法流量分析
web安全攻击方法流量分析
650 1
web安全攻击方法流量分析
|
SQL 安全 Java
网络安全-webshell详解(原理、攻击、检测与防御)
网络安全-webshell详解(原理、攻击、检测与防御)
1303 0
网络安全-webshell详解(原理、攻击、检测与防御)
|
监控 安全 druid
如何强化应用安全能力,全面拦截 Log4j 漏洞攻击
「ARMS应用安全」为企业业务安全保驾护航!
如何强化应用安全能力,全面拦截 Log4j 漏洞攻击
下一篇
无影云桌面