Building a Vulnerable Box – Heartbleed

Patchwork may have wrapped this series up in his last post, but I’ve got one more to add.

The Heartbleed bug (CVE-2014-0160) received a lot of press when it was discovered and disclosed in April of 2014, and deservedly so.  The vulnerability was severe not only because of the sensitivity of the information it could leak, but also because of its prevalence across the internet.  No doubt its snazzy graphic and catchy name helped the media pick up and circulate the story.

It’s true, many high-traffic, public-facing websites with the vulnerability were rapidly patched, owing in part to the media attention and the abundance of Heartbleed-checking sites that allowed users to test their favorite webpages for the vulnerability. Now, a little more than one year on, the Heartbleed bug may seem like a distant memory.  However, according to a report released in April by Venafi,

“Of the Fortune 2000, 1,639 companies have systems that were vulnerable to Heartbleed, and 1,223—or 74 percent—have not completely remediated the issue, as of April 2015…more than 40 percent of Fortune 2000 companies in the United States and Germany believe themselves to have remediated the issue…”

As such, it is important that pentesters and scanners alike continue to test for Heartbleed and understand how to exploit it effectively.

Most of the media attention focused on the idea of exploiting the vulnerability to acquire a server’s private key.  While that is certainly a crucial aspect of the exposure, it shouldn’t be overlooked that a server vulnerable to Heartbleed will dump the contents of its RAM, regardless of what they are.  This could include not just the PKI, but credentials entered by users or their session tokens.

In fact, not long after the Heartbleed disclosure, Mandiant employees described investigating an incident wherein an attacker exploited the Heartbleed vulnerability to steal session tokens from a VPN appliance, thereby bypassing the need for two-factor authentication.

Couple that example with the fact that organizations are often much slower to patch or update internal systems (such as administrative consoles for network appliances), and you’re left with the fact that Heartbleed remains a relevant vulnerability.  As such, it’s something that penetration testers and security professionals should be on the lookout for, perhaps especially on internal penetration tests.

This post covers how to build a machine vulnerable to Heartbleed, and some of the tools (most of which you probably already have) that you can use to test for and exploit it.

Building the Machine

Rather than trying to download and build an older, unpatched version of OpenSSL, it’s easier to just grab an older Linux distribution.  Ubuntu 12.04 was released with a vulnerable version of OpenSSL, and is still available from Ubuntu’s website as either a torrent or an .iso.

Once your vintage Ubuntu machine is up and running, you’ll need to install a web server and configure it to serve up pages over SSL.  I generally followed the steps outlined by Andrew Kennedy, who beat me to this by about a year.

Download a web server and generate your SSL key and certificate:

sudo apt-get install nginx

Generate your self-signed ssl key and certificate:

openssl req -new -x509 -days 365 -sha1 -newkey rsa:1024 \
-nodes -keyout heartbleed.key -out heartbleed.crt \
-subj '/O=YourCompany/OU=YourDepartment/CN=www.yoursite.com'

Configure the nginx default file.  Again, I grabbed this from here with some minor changes.  Remember to point the certificate and certificate key to the correct path, and to create the access and error log if you so desire.

server {
  listen 443;
  server_name heartbleed;

  root /usr/share/nginx/www;
  index index.html index.htm;

  ## SSL
  ssl on;
  ssl_certificate /path/to/your/heartbleed.crt;
  ssl_certificate_key /path/to/your/heartbleed.key;

  ## SSL caching/optimization
  ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers RC4:HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers on;
  keepalive_timeout    60;
  ssl_session_cache    shared:SSL:10m;
  ssl_session_timeout  10m;

  ## SSL log files
  access_log /var/log/nginx/heartbleed_access.log;
  error_log /var/log/nginx/heartbleed/ssl_error.log;

  location / {
    proxy_set_header        Accept-Encoding   "";
    proxy_set_header        Host              $http_host;
    proxy_set_header        X-Forwarded-By    $server_addr:$server_port;
    proxy_set_header        X-Forwarded-For   $remote_addr;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_set_header        X-Real-IP         $remote_addr;
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
  }
}

With your server and SSL configured, you’ll need a simple website that allows for user input:

<html>
<head>
<title>Heartbleed: Still Bleeding</title>
<script>
document.cookie="heartbleed";
</script>
</head>
<body>
<br /><br />
<form name="input" action="index.html" method="get">
Username: <input type="text" name="username">
<br />
Password: <input type="password" name="password">
<br /><br />
<input type="submit" value="Submit">
</form>
</body>
</html>

From there, spin up your nginx server and get to the fun part.

Testing and Exploiting Heartbleed

There’s no shortage of tools we can use to test for and exploit Heartbleed. You are no doubt familiar with some of them which means testing for Heartbleed should be easy to integrate into your existing methodology.

One such method is to make use of the Nmap Scripting Engine (NSE) by using the ssl-heartbleed script.  There’s a decent chance you’re already using nmap for network discovery and enumeration; its scripts are an often overlooked feature that truly expand the tool’s capabilities.  To run the Heartbleed check script, simply issue the command:

nmap -p 443 --script -ssl-heartbleed <target IP>

If your target is vulnerable, nmap prints that result along with a helpful summary and some references:

 

nmap_heartbleed_results

 

A second common method to test for Heartbleed is to (of course) use a Metasploit module.  The /auxiliary/scanner/ssl/openssl_heartbleed scanner allows for either checking for the vulnerability or attempting to exploit it.  The range of options available in the Metasploit module, along with Metasploit’s database capabilities, make it an obvious choice for identifying and exploiting Heartbleed.  The screenshot below shows a check:

 

msf_heartbleed_check

 

Finally, the heartbleed-poc.py on SensePost’s git repository is a simple, yet effective, tool for exploiting Heartbleed.  It may take a couple tries to run the script successfully.  The first screen capture below shows the initial output:

 

python_heartlbleed_exploit

 

This second snippet shows where the credentials I entered were exposed by the vulnerability:

 

python_heartbleed_exploit_results

 

Make sure to experiment with the various tools out there to see which work best for you and your methodology.  Having your very own vulnerable Heartbleed box affords you the opportunity to do this in a way that is both safe and responsible.  It’s also worth seeing how different browsers affect the results you’ll get from the Heartbleed exploit, and setting up the vulnerable server yourself gives some insight into the process of patching the vulnerability.  The important thing to remember is that, even though it’s a whole year old, Heartbleed is still hiding out there, and worth seeking out.