Home
Writeups Misc About
Curveball

Curveball

The name of the challenge is the name of the vulnerability CVE-2020-0601 on the crypto32.dll utility on the Microsoft Windows operating system. This vulnerability only targets ECC, and that an adversary can specify their own generator, private key and curve used, as Windows allows for this specifying arbitrary curve behavior.

The same idea applies for this challenge. From the source code of the challenge,

The server does not check all parameters of the certificate correctly. In fact, it does not check the generating point used to generate the public points. Hence, we can send our own generator G' and d' so it passes the check in search_trusted, or in other words, the points signed has the same value as the value of www.bing.com stored in self.trusted_certs.

There are multiple approaches to this. We can look up the specifications of secp256r1 and get the same curve as the one used in the challenge. My idea is to use the public_key as the generator and find the appropriate private key d' such that d * public_key = public_key. Denote the order of the curve as O, we have d = O + 1. Denote the actual private key used to generate public_key with the original generator as n and public_key as p. This above works because

p=nG
(O+1)p=n(O+1)G

As O is the order of the group, we have (O+1)G=G, hence

(O+1)p=nG=p

Hence, the signed point will have the same coordinates as the "new" generator used public_key. Send the correct parameters to the server and we should be able to retrieve the flag.

Sage Implementation:

Another solution, from Robin_Jadoul on Cryptohack is the same idea but slightly different. Instead of supplying the target public key as the generator, he supplied a multiple x of the public key. Then the private key is the modular inverse of x with the modulo as the order of the group. From the above notation, the private key d is derived by d=inv(x,O). The math to show that this indeed works is the same as the above.