|April 1, 2014 11:09 UTC
|1.0.1 to 1.0.1f
|April 7, 2014
Heartbleed is a vulnerability in the OpenSSL implementation - OpenSSL implemented the widely used protocols: SSL (Secure Sockets Layer) and TLS (Transport Layer Security). The flaw in OpenSSL gives an attacker the ability to extract encrypted data from TLS/SSL secured networks.
The vulnerability is essentially in the heartbeat that's sent between two systems communicating over TLS/SSL. Let's say we are system 1 and Google is system 2. The heartbeat is there to check if the connection between us and Google is still alive, in case there is no activity on the connection for a longer period of time. The heartbeat itself is an encrypted packet sent from us to Google, with a maximum size of 64KB. Let's say we send a heartbeat packet with size 32KB to Google, the packet tells the Google server to expect a 32KB message, so the Google server allocates 32KB of memory, to store the encrypted data from the heatbeat packet, then it reads it back out of memory and sends the heartbeat packet with size 32KB back to our browser.
How do we exploit this, you might wonder? In order to read encrypted data from the TLS/SSL connection we need to trick the receiving server, in this case Google, in thinking it's receiving more data than we are actually sending in the heartbeat. What we're gonna do is forge a malicious heartbeat packet that is gonna tell Google: "Hey, get ready for 64KB of data!", but in reality we are only sending a heartbeat packet of 16KB to Google. This causes Google to allocate 64KB in its memory, and only store 16KB of data in it, since we only sent Google 16KB. Now the flaw in the system is that the receiving end (Google) doesn't check if it has actually received 64KB of data. Google has allocated 64KB in its memory, and will also send back 64KB of data it reads from its own memory, even though we only sent 16KB. This means that Google will return 16KB of data + 48KB of data that is currently present in memory. Now we have extracted 48KB of information that we actually have no access to!
The information you receive could either be nothing but random crap, or you could receive SSL private keys, usernames, passwords or other sensitive data. Below is an example of such output:
The vulnerability comes forth from a single line of code in OpenSSL.
memcpy(bp, pl, payload);
This line of code is a programming mistake that broke the interwebs. But what does this line mean? The function memcpy copies data, and requires three values to copy this data. The first variable 'bp' is the destination of the data that needs to be copied, so this is a place inside memory on the Google server. The second variable 'pl' is the location of the data that needs to be copied, which means it's the data we sent as a heartbeat to Google (with size 16KB). The third variable 'payload' is a value that indicates how big 'pl' is. In our case this is 64KB.
Copying data on a computer is not as straight forward as you think, because there is no such thing as empty memory. This means that 'bp', the location where 'pl' is going to be copied, isn't empty, but full of data that has been marked for deletion, waiting to be overwritten, by 'pl' for example.
How it should work is that when memcpy takes our 16KB heartbeat data from 'pl' and copies it to location 'bp' with payload = 16KB in Google's memory, the location in memory will overwrite the old data that has been marked for deletion, with our new 16KB of data. It will be a perfect fit since according to the payload value, 16KB has been reserved in Google's memory.
I can hear you thinking already: "Yeah so what if i change the 'payload' value to 64KB while our 'pl' data size is only 16KB?". That is exactly how we can extract extra data from Google memory. memcpy will make a 64KB reservation on the Google server's memory but only 16KB of data will be overwritten, leaving 48KB of still intact (marked for deletion) data available in the reservation. The server will return the full 64KB of data back to us, including the 48KB of random data.
If you want to check your server for the heartbleed vulnerability, you can do this in a couple of ways.
Via nmap you can test your system with the following command:
nmap -p [port] --script ssl-heartbleed [target]
nmap -p 443 --script ssl-heartbleed 10.10.10.79
You could enter your IP/Domain on a site such as Comodo SSL Analyzer to check if your system is vulnerable.
Due to the nature of this exploit, it will not leave any traces on the target computer. The exploit can be done very easily with a default metasploit module, to start, open up the metasploit CLI:
** Disclaimer: The following steps are done in Kali 2018.1 **
Next, load the module:
You could display the options, but initially most of the options are fine by default. The only things we have to set are RHOSTS, VERBOSE, and optionally THREADS:
set RHOSTS 10.10.10.79
set THREADS 50
set VERBOSE true
With every heartbeat you send, 64KB of data will be returned in the output. Note that if you do not set the VERBOSE parameter to true, you will not directly receive this printable output. You should also notice that with every chunk of data you receive, the data is different. That's because you're always retrieving a different part of the targets' memory - always the +64KB of where our heartbeat is allocated in memory.
Manually probing the target system, heartbeat after heartbeat is pretty boring, so that's why there are some wonderful people who wrote heartbleed.py. This is a script that automates the heartbeats, and even lets you extract the RSA private key if it's found in the 64KB chunk. Download the script by clicking on the link above or via wget:
To run the script, it could be that you'll have to install a missing module. This can be done with pip:
sudo pip install [module]
sudo pip install gmpy
To run the script, you can specify the following parameters:
python heartbleed.py -p [port] -n [amount of retries] -e [ip]
python heartbleed.py -p 443 -n 2000 -e 10.10.10.79
The parameters do the following:
-p : Specifies the port.
-n : Specifies the number of times to repeat the heartbeat.
-e : Attempt to extract the RSA private key and exit the script when it's found.
If you want extra help with this script, you can always just type in:
python heartbleed.py -h
To protect yourself against the heartbleed bug, you can update OpenSSL to version 1.0.1g or later.
After patching the vulnerability, you should treat your private key, passwords and certificates as compromised. This means that it's highly recommended to regenerate new keypairs, reissue your certificates, and change your passwords. The reason being is because when an attacker used the heartbleed bug against your systems, he could've pulled any information that's in that system's memory at that point.
** For more information, check out the extra links and sources. **