Hitting a CurveBall Like a Pro!

Tal Be'ery
Zengo Wallet
Published in
6 min readFeb 3, 2020

Last month (Jan 14th 2020), Microsoft has released a security update for Windows which includes a fix to a dangerous bug that would allow an attacker to spoof a certificate, making it look like it came from a trusted source. The vulnerability (CVE-2020–0601 , AKA CurveBall) was reported to Microsoft by the NSA. In this blog post, we will explore how defenders can detect the exploitation of this vulnerability.

Previously on CurveBall

This is our third blog post on CurveBall. In our first blog post, we explained the cryptography principles behind CurveBall, enabling attackers to create an “evil twin” of a legitimate certificate by changing the base point.

In the second blog post, we explained the SSL certificate validation process and shed some light on the bug in Windows10 that allowed it to accept this “evil twin” certificate as valid.

In this third blog post we will try to make this knowledge actionable, by creating detection rules to catch exploits of the CurveBall vulnerability.

Detection Recipe by NSA

The original NSA advisory suggests

Packet capture analysis tools such as Wireshark can be used to parse and extract certificates from network protocol data for additional analysis…

..Certificates containing explicitly-defined elliptic curve parameters which only partially match a standard curve are suspicious, especially if they include the public key for a trusted certificate, and may represent bona fide exploitation attempts.

Breaking down this advice into four steps (or “bases” as we are dealing with a curve ball):

  1. Wireshark can be used to parse and extract certificates from network protocol data.
  2. Certificates containing explicitly-defined elliptic curve parameters
  3. Elliptic curve parameters which only partially match a standard curve
  4. Include the public key for a trusted certificate

In the following sections, we will follow the NSA’s blueprint to detect such exploits, starting from first base all the way to a home-run!

First base: Capturing certificates with Wireshark

I assume you are already familiar with Wireshark, the Swiss army knife of network capture. For this blog we need to use Wireshark of version 3.3.0 (or newer) which is currently available only as a nightly build (or by building from source code)

As the exploit abuses certificates in SSL. The certificates are exchanged in the handshake stage of the SSL protocol, so the certificates information is available in plaintext and no decryption is needed. Sweet!

A basic Wireshark filter for the handshake message with certificate “(tls.handshake.type == 11)” would help us zoom in on that message.

filtering for SSL certificates

To experiment in this stage any SSL traffic would do, so you can capture any browsing session to HTTPS site. However, for next stages real exploits traffic is needed. To obtain such, you can either browse to CurveBall testing sites curveballtest.com or testcve.kudelskisecurity.com or just download the capture files of SSL traffic we already recorded by and uploaded to GitHub.

Second Base: Identify explicitly-defined parameters

This is a real piece of cake with Wireshark. Normally, a certificate will use the name of a standard curve and will not define the curve parameters

A normal certificate with a namedCurve

However, for this exploit attackers need to use a specified curve. We will use the following Wireshark filter “(pkcs1.ECParameters == 0)” to catch it.

Exploit certificate with a specifiedCurve

Note, that if you don’t have the luxury of having Wireshark to reconstruct the TCP session and parse the SSL protocol and certificate, a simpler signature may work. A simple signature that tries to match the hex value of the “prime-field” OID (Object IDentifier) 1.2.840.10045.1.1, on the wire “2a 86 48 ce 3d 01 01” can do a decent job in catching non-default elliptic curve parameters, as suggested in the tweet below (with some extra context to minimize false positives)

Third Base: Identify elliptic curve parameters which only partially match a standard curve

For the exploit to work the certificate must change the standard base point (AKA Generator) of the curve (see our first blog on CurveBall).

Since the parameters of curve are standard and known in advance, we can add a detection rule for the non-standard base points

Standard Parameters for secp384r1

Therefore, we can create such filter for curves supported by SSL and Windows for example secp384r1 (we will see in the next section that checking for secp256r1, secp384r1 is probably sufficient). The filter will match the “a” and “b” parameters of standard curves, with a non-standard base point.

“(pkcs1.ECParameters == 0) && (pkcs1.a == ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe:ff:ff:ff:ff:00:00:00:00:00:00:00:00:ff:ff:ff:fc) && (pkcs1.b == b3:31:2f:a7:e2:3e:e7:e4:98:8e:05:6b:e3:f8:2d:19:18:1d:9c:6e:fe:81:41:12:03:14:08:8f:50:13:87:5a:c6:56:39:8d:8a:2e:d1:9d:2a:85:c8:ed:d3:ec:2a:ef) && (pkcs1.base != 04:aa:87:ca:22:be:8b:05:37:8e:b1:c7:1e:f3:20:ad:74:6e:1d:3b:62:8b:a7:9b:98:59:f7:41:e0:82:54:2a:38:55:02:f2:5d:bf:55:29:6c:3a:54:5e:38:72:76:0a:b7:36:17:de:4a:96:26:2c:6f:5d:9e:98:bf:92:92:dc:29:f8:f4:1d:bd:28:9a:14:7c:e9:da:31:13:b5:f0:b8:c0:0a:60:b1:ce:1d:7e:81:9d:7a:43:1d:7c:90:ea:0e:5f)”

Detecting a non-standard secp384r1 base point

Home run: Include the public key for a trusted certificate

The crux of the exploit is that the rogue certificate public key matches a the public key of an already trusted Win10 certificate (check our second blog on CurveBall). But can we find them all?

Yes we can, and in fact Benjamin Delpy has done so in another CurveBall exploit tool used to sign binaries. (It might be a good opportunity to remind that although the detection rules here are network exploits oriented, I assume they are relevant, with the appropriate changes, to the detection of maliciously signed files)

To do so, we can search the repository of Microsoft supported Certificate Authorities (CAs) for elliptic curve based certificates (by the “Public Key Algorithm” column), download all 35 of them and extract the public key. (additionally you can see that Windows supported CAs only use secp256r1 and secp384r1 curves)

userTrust public key

Then we can add all public keys to the filter:

“(pkcs1.ECParameters == 0) && (x509af.subjectPublicKey == 04:1a:ac:54:5a:a9:f9:68:23:e7:7a:d5:24:6f:53:c6:5a:d8:4b:ab:c6:d5:b6:d1:e6:73:71:ae:dd:9c:d6:0c:61:fd:db:a0:89:03:b8:05:14:ec:57:ce:ee:5d:3f:e2:21:b3:ce:f7:d4:8a:79:e0:a3:83:7e:2d:97:d0:61:c4:f1:99:dc:25:91:63:ab:7f:30:a3:b4:70:e2:c7:a1:33:9c:f3:bf:2e:5c:53:b1:5f:b3:7d:32:7f:8a:34:e3:79:79)”

Exploit certificate with a “trusted” public key

Bonus: Exploit based detection

Detecting a specific exploit is a “Whack-a-mole” game, as the exploit can be easily changed. However, sometimes adding detection for a popular exploit on top of the solid vulnerability based detection (such as the aforementioned) can be worth the while as it can add some certainty to the detection.

A popular CurveBall exploit is using the “degenerate case” in which the private key equals to 1 to avoid elliptic curve arithmetics (see our first blog on CurveBall). As a result, the base point of the exploit certificate is equal to its public key. Using Wireshark you can detect it with the following filter “(pkcs1.base == x509af.subjectPublicKey)”.

Catch the degenerate: base equals public

Note, that it will only catch the exploit of curveballtest.com, as the testcve.kudelskisecurity.com exploit is doing some elliptic curve arithmetics to support non degenerate cases.

The ninth inning: Putting it all together

Are all of these detection elements actually needed? I am not sure. In detection, you don’t need to swing to the fences every time. My personal feeling is that checking for SSL certificates with explicit parameters might be enough.

I would not expect it to generate too many false positives as many implementations do not support explicit parameters (including Windows versions older than Win10) and updated standards (RFC 5480) ban the use of them.

Recently, there was (another) heated debate on publishing exploits. However, I believe that there is a broad consensus that sharing detection rules recipes is a good idea. Therefore, we encourage you to share your results of applying these rules. Please reply in the comments below or in twitter.

Be safe out there!

--

--

Tal Be'ery
Zengo Wallet

All things CyberSecurity. Security Research Manager. Co-Founder @ZenGo (KZen). Formerly, VP of Research @ Aorato acquired by @Microsoft ( MicrosoftATA)