admin 管理员组

文章数量: 887021

1. 背景

这是第一个由美国国安局(NSA)所发现并主动提交给微软的安全漏洞。

过去外界曾抨击NSA隐匿安全漏洞,只为追求网络间谍与攻击的做法罔顾广大用户的权益,才使得这次NSA主动向微软通报安全漏洞的事件跃上媒体标题。

CVE-2020-0601漏洞位于Window的加密组件CryptoAPI。 CryptoAPI是微软提供给开发人员的Windows安全服务应用程序接口,可用于加密的应用程序,实现数据加密、解密、签名及验证等功能。

由Crypt32.dll提供的Microsoft Windows CryptoAPI无法以正确验证ECC证书的信任链。攻击者可以利用该漏洞伪造受信任的根证书签发证书。Crypt32.dll中的CertGetCertificateChain()函数用来验证X.509的合法性,跟踪到受信任的根CA签发的证书,由于函数中存在漏洞,可以使证书,包括第三方非Microsoft的根证书,都不能得到正确的验证。

360对该漏洞分析:CVE-2020-0601 Windows CryptoAPI验证绕过漏洞原理简要分析 - 360CERT

2. 原理

2.1 ECC/椭圆曲线密码

ECC椭圆曲线加密(Elliptic curve cryptography)于1985年由Neal Koblitz和Victor Miller分别独立提出的公钥密码算法。

优势:使用更小的密钥(对比RSA)来提供相当或更高等级的安全。

ECC核心离散对数问题:

设G为曲线上一点G=(Gx, Gy),d为一个整数, 点Q = d*G。

给定d和G,很容易求Q。

给定G和Q,很难求出d。

ECC中Q为公钥,公开;d为私钥,用户自己秘密掌握。

2.2 CVE-2020-0601漏洞原理

CVE-2020-0601漏洞原理在于 win10 增加了对带参数ECC密钥的支持,但在 crypt32.dll 中做签名验证时,只检查匹配的公钥 Q,而没有检查生成元 G。

假设合法用户A,分别取基点G、私钥d、公钥 Q,Q = dG。

由于 win10 支持自定义生成元 G',攻击者可以取基点 G' = Q,私钥d' = e(单位元),公钥任然为Q,Q = dG = d'G'。

此时合法用户A的公钥和攻击者的公钥相同,都是Q。

由于验证缺陷,只检测 公钥Q。 从而,攻击者用自己的私钥d' = e(单位元),会被验证通过,认为是用户A的私钥d 做出的签名。

个人认为,攻击者可以取随机数x为自己的私钥, 选基点为inv(x)Q,这样他的公钥仍然为Q=x*inv(x)Q,即使检查用户的基点是不是为G,也能执行此攻击。不知这样的理解是否正确。

2.3 攻击(简化)

简单地讲,伪造的Q = d'G'在验证签名时过程如下:

假设exe文件 A 的hash值是 X,用伪造的私钥 d' 对X签出的值是 Y,验证时,用公钥Q 验证X和签名值Y会认证通过,系统认为签名正确,完成绕过。

利用此漏洞可以使用伪造的证书对恶意的可执行文件进行签名,使文件看起来来自可信的来源,或者进行中间人攻击并解密用户连接到受影响软件的机密信息。

3. 解法

在ECDSA中,基点是随域参数一起发布的。个人觉得不应该由用户自定义基点(生成元),而应该固定选择使用域参数中的基点,或者对自定义参数的曲线进行更加严格的管控,比如参数检测,严禁自定义曲线和标准曲线之间可能存在的交叉等。

附录 ECDSA签名流程

点击图解漏洞CVE-2020-0601中涉及的ECC签名算法ECDSA

本文标签: 安全漏洞 说一说 原理 Windows CVE