【M01N】CVE-2020-0601 Windows CryptoAPI欺骗漏洞分析

1月15日,微软发布了针对CVE-2020-0601的安全补丁,该漏洞是微软在实现椭圆曲线加密算法数字证书验证时产生,可被利用于伪造来自可信任来源的签名或证书,并且因其业务特性会衍生出多种攻击向量,具有极高的可利用价值和极大的潜在破坏力,Win 10和windows server 2016 & 2019也都在其影响范围内。

背景介绍

1月15日,微软发布了针对CVE-2020-0601的安全补丁,该漏洞是微软在实现椭圆曲线加密算法数字证书验证时产生,可被利用于伪造来自可信任来源的签名或证书,并且因其业务特性会衍生出多种攻击向量,具有极高的可利用价值和极大的潜在破坏力,Win 10和windows server 2016 & 2019也都在其影响范围内。该漏洞由美国NSA国家安全局发现后汇报给微软公司,也被认为是第一个NSA公开披露的软件系统漏洞,当然也有可能存在其特殊的战术目的。绿盟科技M01N攻击安全研究团队对此漏洞原理进行了详细分析并复现了多种可能的攻击方法,提出了详细的检测及整改方案。

ECC算法简介

CVE-2020-0601的根源是微软的加密库crypt32.dll中椭圆曲线加密算法的实现问题,首先我们来了解一下椭圆加密算法的基本原理。

要形象地理解椭圆曲线加密算法,可以结合图形来看,以下是一个符合椭圆曲线的方程y2 = x3 + ax + b,图像如下:

椭圆曲线具有的一些独特的性质使它适合用于加密算法:

  1. 椭圆曲线关于x轴对称
  2. 任何一条非垂直的线与曲线最多有三个点相交
  3. 曲线是光滑的,即曲线的所有点都没有两个或者两个以上的不同的切线

在椭圆曲线上任意两点A、B(若A、B重合则作A的切线),作直线交于椭圆曲线另一点C`,过C`做y轴的平行线与椭圆曲线交于C点,定义A+B=C。椭圆曲线的加法符合交换律和结合律。

如果A、B是同一个点,则过A作椭圆曲线的切线,以同样的方法得到对应的结果 C=2A 。

接下来是椭圆曲线加密相关的重点,如果对多个A进行累加,则可依次累加连线得到nA的值 。

起点为A,终点D=3A,阶为3 。

起点为A,终点G=4A,阶为4。

椭圆曲线加密。

考虑K=kG,其中K、G为椭圆曲线Ep(a,b)上的点,n为G的阶。k为小于n的整数。则给定k和G,根据加法法则,计算K很容易(只要逐次求解)但反过来,给定K和G,求k就非常困难。因为实际使用中的ECC原则上把私钥k取得相当大,n也相当大,且椭圆曲线不再连续而是在实数内离散的值,要把n个解点逐一算出几乎是不可能的。这就是椭圆曲线加密算法的数学依据 。

  • 点G称为基点
  • k(k<n)为私有密钥
  • K为公开密钥

椭圆曲线加密算法(ECC)和RSA一样是一种公开密钥加密技术,对原始数据以公钥加密,以私钥解密,即便攻击者获取密文和公钥也无法(在合理的时间或代价下)解密获取明文。

同样的,椭圆曲线加密算法(ECC)也被用于数字签名,以私钥加密生成签名,以公钥解密验证签名,如果和原文一样则签名验证成功。

公开密钥加密之所以可靠是因为它们利用了公钥密码领域的单向函数原理,正向操作非常简单,而逆向操作非常困难。

由G(基点)出发,进行k(私钥)次变换,只要按部就班地计算,就能很容易地得到终点K(公钥)的值。

已知起点G(基点)和终点K(公钥),要逆推得到移动次数k(私钥)则是一个很难的问题(最佳算法也达到了全指数复杂度)。

相比传统RSA加密算法,椭圆加密算法具有着天生的优势,椭圆加密算法的逆向过程相比RSA有着更大的时间复杂度。在密钥长度相同的情况下,椭圆加密算法相比RSA具有更好的安全强度。一般认为,160比特的椭圆曲线密钥即可提供与1024比特的RSA密钥相当的安全强度。

较短的密钥也意味着更少的存储空间、更快的加解密速度和更少的带宽消耗,正因为椭圆加密算法的这些优势,它被用于Windows的签名系统、https的证书、比特币系统和中国的二代身份证系统中。

漏洞原理

虽然椭圆曲线加密算法具有着许多优势,纯算法角度破解难度极大,微软对此算法的实现的缺漏却给漏洞利用提供了可乘之机。回到椭圆曲线加密最基本的等式 K=kG,首先需要明确的是,虽然对于给定的基点G和公钥K,要求解私钥k很困难,但是如果可以任意指定基点G,要构造一对k和G使等式成立却极其简单;最简单的情况,令基点G=K,则私钥k=1,这样一对基点和私钥可以使等式成立,也是有效的解。

在正常的标准椭圆曲线算法中,基点G并不是随意指定的,而是有固定的值(标准的作用,便是对基点G等参数的选择做出规定),例如在secp256r1版本的椭圆曲线算法中,基点G应当为标准规定的固定值,如果对参数不加验证,使得用户可以自定义传入的基点G的值(作为函数的参数),上面的私钥k=1的特殊解即可成立。

在有漏洞版本的crypt32.dll中验证使用ECC算法签名部分的函数恰恰是这个情况,原先的函数未加参数验证,参与计算的基点G的内容由被验证的证书随意指定,使未授权的证书能够构建私钥k=1的特殊解来成功通过椭圆加密算法的签名验证的过程。

让我们以CVE-2020-0601的一个POC为例来解析虚假密钥的构建过程:

require 'openssl'

raw = File.read ARGV[0] 	# 读取使用ECC算法的证书文件
ca = OpenSSL::X509::Certificate.new(raw) 	# 读取使用ECC算法的证书
ca_key = ca.public_key 	# 从证书中提取公钥ca_key

ca_key.private_key = 1 	# 设置私钥为1,使得公钥K==1*基点G的等式成立
group = ca_key.group 
group.set_generator(ca_key.public_key, group.order, group.cofactor)
group.asn1_flag = OpenSSL::PKey::EC::EXPLICIT_CURVE
ca_key.group = group 		# 利用构建的假基点G和假密钥k设置新group
File.open("spoofed_ca.key", 'w') { |f| f.write ca_key.to_pem } 	# 将新的group写入文件

修补后的Crypt32.dll中椭圆曲线加密算法的函数已加入了参数验证的部分,解决了由自由指定参数G导致的构造第二个特殊的有效密钥的问题。

一处验证机制的失误导致信任链的连锁反应。

现代的安全系统中存在着“信任链”的概念,信任链的上下级存在一种类似单向担保的关系,子级证书的可靠性由签名其的父级证书担保。签名时由根证书开始一级级向下签名,验证时则逐层溯源验证,直到找到信任的根证书文件,构成了一条信任链。位于整个“信任链”最上方的是最为重要不需要自证身份的根证书。根证书一般随系统附带或由管理员安装在系统内。

这个漏洞的存在则使得构造的无效签名通过了验证机制,使本应断裂的信任链被利用,逐级担保继续下去,最终使非法内容获得了证书所有者的合法签名身份。

漏洞利用

自月初CVE-2020-0601公布,微软很快地推出了对应的安全补丁,世界各地的安全研究者也不断挖掘着它的各种利用方式,NSA在其漏洞报告中概括性地描述了该漏洞可能的危害:

  1. HTTPs 连接
  2. 文件签名和邮件签名
  3. 被签名的可执行代码作为用户进程执行

由于加密签名属于基础安全应用,它的安全问题会根据业务导致多个攻击向量的产生,并且伪造后的签名可以完成针对基于证书签名验证的防御策略绕过,具有极大的危害,M01N安全研究团队利用该漏洞的复现了以下几种可用攻击链:

  1. 伪造PE文件签名
  2. 伪造网站ssl证书
  3. 伪造邮件签名
  4. 伪造office宏签名
  5. 伪造Powershell脚本签名

伪造PE文件签名

利用签名验证的漏洞给恶意文件加签名来实现免杀的目的,这可能是伪造数字签名最容易想到的一种利用方式,签名保证了软件的来源与不被篡改,来自微软官方的数字签名更是无论对用户或是安全软件都有着很大的迷惑性。

签名后,在UAC中颜色显示也变成具有可信签名的蓝色,“已验证的发布者:Microsoft“这样的提示也很具有迷惑性。

伪造网站ssl证书

利用该漏洞,我们可以利用任意使用ECC算法的根证书,来伪造任意网站的证书,以伪造网站,实现钓鱼攻击等目的。

M01N攻击安全研究团队利用ollypwn团队公开的POC,利用此漏洞构建了google.com的虚假证书,并将自己的页面伪装成谷歌首页,通过了微软Edge浏览器的验证。

网站标识显示的即为我们利用的证书。

证书信息页面显示了证书的详细信息,在实际运用中域名、颁发者、区域和序列号等信息在生成时都可以自由指定,增强迷惑性 。

伪造邮件签名

在传统的书信时代,亲笔签名和锡封保护着那个年代的通信安全。而在数字时代,邮件的数字签名则保证了邮件来源的可靠性,邮件的内容始终如一、未被篡改。

在Outlook和ThunderBird等支持邮件数字签名的邮件客户端中支持使用用户指定的数字签名文件对邮件进行签名,这样签名的邮件因为“信任链”的存在(使用被双方信任的签名文件来签名作担保),在接收方查看时依然被验证为有效签名,这是数字签名。

虚假数字证书的制造者在签名生成时可以随意指定数字签名的颁发者名称,使用者名称,邮箱等关键信息,来自知名厂商的证书担保和看似合理的签名内容具有很强的迷惑性。

M01N攻击安全研究团队经过研究,成功使用伪造的数字签名通过Outlook客户端发送具有数字签名的邮件。

区别于普通邮件,被签名邮件具有明显的标识 。

在客户端内,数字签名被验证可靠。

在签名的详细信息中可以看到邮件的数字签名是以S/MIME的协议完成的 。

在制作该虚假签名时使用了谷歌(google.com)的根域名证书,域名使用者则设置为微软(Microsoft)的信息,一目了然,以作区分。在真实攻击中,签名伪造和其信任链关联的证书会更加具有迷惑性。

当黑客具有伪造任意邮件地址的数字签名的能力时,他至少可以作两件事:

  • 伪造特定目标的数字签名,发送钓鱼邮件,绕过邮件安全网关
  • 篡改邮件内容后加签名重新发送

据我国《电子签名法》的规定,具有数字签名的邮件具有法律效应,在诉讼时可以作关键的证据。在《合同法》中规定,具有数字签名的电子邮件签订的合同更是与传统纸质合同一样,具有作为书面合同的法律效益。

无论是伪造签名的钓鱼邮件造成的商业机密泄露,还是商业邮件、商业合同被篡改导致直接经济损失和法律风险,都可能造成不可估量的损失。如果是有组织地利用此漏洞,针对命脉行业发动类似攻击,造成的后果则更加不可想象。

伪造office宏签名

Office宏具有着很大的安全风险,使用具有恶意代码的宏的文档钓鱼攻击也是非常传统的攻击方法。完全禁止宏又可能导致一些文档内重要的功能无法使用。

“禁用无数字签署的所有宏”便是一个比较理想的设置,用户可以继续使用由可信来源签署的宏的功能,未经签名的宏则静默地被禁止,无法执行,也不会出现”启用内容”的提示按钮,最大程度地避免风险。

如图,未经签名的文件宏直接被禁止,也无任何提示。

但是当攻击者具有伪造数字签名的能力,他们便可以利用该数字签名对Office宏进行签名,避开“禁用无数字签署的所有宏”这个安全机制的限制。

虽然仍然需要点击“启动内容”的按钮才能执行代码,但是相比被静默地禁止增大了许多胜算,而且也只有第一次时需要手动点击,之后都会自动执行。

执行代码,弹窗。

同样的,利用了谷歌根证书来签名,伪造成微软官方的签名。因为“信任链”的存在,构建的文档可以直接投递到其他开启“禁用无数字签署的所有宏”安全机制的系统中,并且成功绕过禁止执行的限制。

伪造Powershell脚本签名

随着攻防技术的不断博弈发展,无文件攻击的理念越来越深入人心。从无文件攻击概念提出的一开始,Powershell就是无文件重要的攻击实现。

作为系统管理员,直接禁止未签名的Powershell脚本运行可以提高安全性。

开启“AllSigned”此项安全策略后,未经签名的Powershell脚本会被禁止运行。

利用之前伪造的数字签名对被禁止运行的Powershell脚本进行签名。

虽然依旧弹出了需要确认运行的提示,伪造的签名却也具有相当的迷惑性,最终使得恶意代码被执行。

总结一下,这些CVE-2020-0601的利用方法存在着类似的思路:

  • 利用存在漏洞的算法,伪造签名文件
  • 根据目标,定制伪造签名内容,具有欺骗性
  • 利用伪造的签名文件“瞒天过海”,获取信任
  • 利用“信任链”,广范围内的系统适用

虽然大部分POC利用的证书有限,实际上可利用的证书数量相当可观,各大厂商很多都提供了自己的PKI仓库,或者其他易于取得的公钥来源,其中一些基于椭圆加密算法(ECC)的证书便可能被用来制作伪造签名。

微软的PKI仓库(https://www.microsoft.com/pkiops/Docs/Repository.htm)中一些可被利用的证书。

在谷歌的PKI库(https://pki.goog/)中同样存在着这样一些可利用的证书文件。

现网威胁分析

通过以上的分析,印证了该漏洞极强的可利用性,该漏洞的披露也可能会引起一波攻击热点。绿盟科技高级威胁情报研判系统显示该漏洞相关样本数量呈上升趋势,M01N攻击安全研究团队也结合捕获到的CVE-2020-0601相关样本进行了简单分析统计。截止本文发布时间,现网针对PE文件进行伪造签名的攻击样本占绝大部分,伪造数字邮件钓鱼,签名office宏文件钓鱼,签名powershell脚本这些稍复杂的利用形式比较少,但不排除快速增长的可能性。NSA对次漏洞的披露也可能是“大隐隐于市”的目的。

检测防御

本次的签名伪造漏洞涉及面广、利用门槛低、造成的潜在危害大,以防守方的角度,便需要有效地检测系统中是否存在该漏洞,以及如何有效地防止漏洞造成损失。

1. 整改方案

修复此漏洞的唯一最佳方案便是及时安装微软官方推出的对应的安全补丁。

使用WindowsUpdate进行系统更新或访问https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0601以下载对应的安全补丁并安装。

2. 攻击检测

微软的安全更新不仅修复了这次的安全漏洞,还为系统管理员和研究者提供了很有价值的事件日志记录机制,任何利用CVE-2020-0601的尝试都会通过CveEventWrite API记录在册。

Windows Defender Antivirus会捕获利用CVE-2020-0601的行为,记录以下日志:

  • Exploit:Win32/CVE-2020-0601.A (PE 文件)
  • Exploit:Win32/CVE-2020-0601.B (脚本)

Microsoft Defender ATP也会有对应的威胁报告 。

距离漏洞公布和安全补丁发布已有一些时间,各大安全厂商都在改进自己的产品,对漏洞利用行为加以监测,尽量减少CVE-2020-0601的影响。所以即便系统没有安装安全补丁,更新至最新版的Windows Defender和目前大多数杀软已经掌握了其利用的一些特征,具备了一定的防御能力。

上图为一非恶意DLL文件利用CVE-2020-0601生成的虚假签名前后的VT扫描结果对照,许多杀软已具备了甄别能力,VT也为CVE-2020-06-01添加了标签。

参考

关于M01N Team

绿盟科技M01N红队安全研究团队专注于Red Team、APT等高级攻击技术、战术及威胁研究,涉及WEB安全、终端安全、AD安全、云安全等相关领域。通过研判现网攻击技术发展方向,以攻促防,为风险识别及威胁对抗提供决策支撑,全面提升安全防护能力。

Spread the word. Share this post!

Meet The Author

Leave Comment