Heartbleed Assignment

Due: March 27, 2022 @9PM Eastern via Gradescope

Team Size: 2 Students Per Team (You may submit either a single submission or independent submissions). You may work in the same groups as for the first homework.

Assignment Overview

In this assignment you are going to be two main tasks: a DNS spoofing lab designed by Wenliang Du at Syracuse University, and exploiting an Apache web server running a version of Openssl that is vulnerable to the heartbleed vulnerability (CVE-2014-160). The Seed Labs assignment runs in a virtual machine and you are going to be given a docker instance running the webserver, so you don’t have to worry about connecting to live systems and the legality of doing so.

We would like to strongly encourage you to write your heartbleed exploit using the scapy library in Python 3. We are giving you the tools to test your code on your local machine. To grade your assignments, we will be downloading your code and running it within a python virtual environment.

Resources

Heartbleed Reading Starting Point

Docker

Scapy Documentation

Seed Labs

Tasks

Review Questions (20 pts.)

  1. What is a certificate and what role do they play in the TLS ecosystem? How do certificates help make TLS more scalable?

  2. What is the difference between Key Encapsulation and Key Exchange in TLS1.2? Describe why Key Encapsulation was removed from TLS1.3 and the kind of attacks or vulnerabilities this change was intended to prevent.

  3. Summarize the major changes between TLS1.2 and TLS1.3. Choose one of the improvements implemented in TLS1.3 (Besides removing Key Encapsulation) and describe why it was included in TLS1.3.

DNS Spoofing Lab (30 pts.)

(Reminder: DO NOT ATTACK SYSTEMS THAT YOU DO NOT MANAGE!)

In this task, you are going to be using another lab created by Wenliang Du at Syracuse University. You should have already st up the SEED Labs environment produced by Syracuse University for the Network Security Homework. We include the the setup instructions for the VM here for completeness.

We are going to be doing the Local DNS spoofing lab that they have created. It is available for download here. You should complete the first four tasks for the 30 points for this question.

Quick-start Instructions

SEED labs has very good, in-depth documentation for setting everything up. For troubleshooting, please refer to their documentation. Below is a quick-start way of setting things up, with some notes of traps that I fell into when setting things up.

  1. Download VirtualBox. There are problems with using older versions of VirtualBox, so if you have version 5.x lying around on your computer, I suggest updating to 6.x. I have tested on 6.1.16.

  2. Download the SEED labs virtual machine image. I got it from here. Be sure to check the MD5 hash of the file (if you don’t practice good computer hygine, who will?) The hash should be c579dcfc1bb623cc3472064ba204ff7a.

  3. Follow the instructions here to create a run a new copy of the VM.

  4. Boot into the VM. The password for the user account is dees.

  5. Open Firefox within the VM, navigate to this website and download the Labsetup files.

  6. Open a terminal window, navigate to the file with the Lab Setup files and run dcup which is an alias they have created for docker-compose up. This will prepare the network and bring up the docker instances you will need for the lab. Note that when you run dcup it will block, so you can leave that running in the background as you work on the rest of the lab.

This should take you up to Task 1 in the task list.

Reading up on Heartbleed and how it was patched (15 pts.)

Please write short answer the following questions. Where applicable, make sure you cite your sources:

  1. What RFC specifies the Heartbeat extension? What is the reason to include the Heartbeat extension?

  2. What should happen when when a server receives a malformed heartbeat request? Where is this specified in the RFC?

  3. What was the practical impact of the heartbleed attack? How many servers were effected? (cite any sources you find)

  4. Find the git commit in the OpenSSL code that fixed the Hearbleed bug. What is the commitment hash? How long did it take to patch the vulnerability?

  5. How many parts of the OpenSSL Codebase needed to be patched to prevent the Heartbleed bug? What is DTLS and how is it different than TLS?

Exploiting Heartbleed (35 pts.)

Setup

You are going to start by making sure you have docker installed and running. Then, download the dockerfile from this assignment and build the docker container.

$ git clone https://github.com/gkaptch1/cs558heartbleed
$ cd cs558heartbleed
$ docker build -t heartbleed .

You can check to see if the image has been created, run the following:

$ docker images

You should see that there is a docker image named “heartbleed.” To run the docker instance, run

$ docker run -d -p 8443:443 heartbleed 

This command starts docker instance and runs the apache server. The flag -p 8443:443 binds your local port 8443 to port 443 of the docker instance, where the server is listening. You can test to make sure the server is running by connecting to https://127.0.0.1:8443 or making a webrequest to the server

curl --insecure -v https://127.0.0.1:8443

Note that the server is sending a self-signed certificate. As your goal is to attack the server, you dont have to worry about verifying the certificate.

Task

Write a script or program that exploits the apache server running on the docker instance. Your code should be able to extract the maximum amount of information from the server (see reports on the bug for length). Your code should be able to operate in two modes: scanning mode or ex-filtration mode. In scanning mode, your code should determine if the server is vulnerable to the heartbleed attack or not. If the server is vulnerable, the program should output VULNERABLE to stdout and termindate. If the server is not vulnerable, the program should output SECURE instead. In ex-filtration mode, you code should dump the retreived bits from the server to stdout, formatted as a continuous hex string. You will need to include a script to run your code called heartbleed with the following interfaces:

# Scanning Mode
$ ./heartbleed --mode scan --server 127.0.0.1 --port 8443
# Ex-filtration Mode
$ ./heartbleed --mode exfil --server 127.0.0.1 --port 8443 --bytes 1000

Assume that the machine on which we will be testing is a standard Ubuntu virtual machine. We will have Scapy and Python 3.8 installed. We suggest that to reduce the pain, you should test your scripts in a python virtual environment. We will be setting up the virtual environment with the following libraries: tinyec, cffi, argparse, cryptography, cryptography, Cython, scapy[complete], futures.

If you require other dependencies not on this list, please let us know and via a private post on Piazza and we will get back to you as to whether we will add the library. Additionally, please include in your submission a write-up that explains how your code works and how you designed your code. Why did you choose the approach that you did? This should be no more than 300 words.

Deliverables, Checklist

You should submit a PDF along with a zip containing your code. Be sure that you submission includes:

Manual for CS558’s Heartbleed!

Credit for putting this manual together to Rakin Munim.

Scapy and sockets are a powerful combination that can allow you to control various critical processes of your machine. In this assignment by attacking a server vulnerable to heartbleed you will be able to learn how to use these two separate libraries to exploit a critical bug. Keep in mind how relatively easy it is to turn a high level attack into a software prototype that actually works. [Maybe you can try exploiting newer vulnerabilities with these two libraries, but of course only on systems that you own.]

Sockets

The first library that will be of value to you is the sockets library. In OS/networking we often refer to this instances of software as processes. For example a Zoom instance is a process. Processes may often want to communicate with each other, either through the same machine or even through different machines. sockets is a library built for python that allows you to handle interprocess communication regardless of process location.

Link to sockets documentation is available here.

Here is an example usage of sockets:

import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket.connect('1.1.1.1'; 80 )

Using these 3 lines of code we now have established a basic TCP connection. Now we can send data reliably over this socket and we can worry about only sending layers above TCP. This snippet creates and connects a TCP socket to device at 1.1.1.1 at port 80.

If you want to learn some more about AF_INET and SOCK_STREAM, check out this.

Scapy

The next library we will cover is scapy. This library allows us to construct packets easily using python code. The subpackage we are specifically interested in is the TLS sub package which allows us to construct various TLS layer structs.

First let’s import the TLS layer:

from scapy.all import *
load_layer('tls')

Now let’s construct a simple TLS ClientHello:

Here’s a link to scapy’s TLS ClientHello Documentation.

We see here that to declare a ClientHello struct we can simply instantiate the TLSClientHello class and fill up the packets with the fields we want. But looking at this documentation doesn’t tell us much about what goes into the different fields. Due to Scapy being a tool made around the specs of TLS, the information about what to actually put in these fields are found the RFCs.

Here is the link to TLS 1.2 RFC: https://www.ietf.org/rfc/rfc5246.txt. The area around pages 37-50 are quite helpful for ClientHello.

After reading the RFC, we can find what data actually needs to go into the fields. For example, for the ‘random’ field, we are provided with a description of the field. We can do a Cmd + f search to find the Random struct definition as well:

With that being said here is a line of code showing a simple TLSClientHello struct.

clienthellopayload = TLSClientHello(complen=1, version = 0x302, comp=[0])

Now we can’t just send this packet over the socket we had created, instead we need to encapsulate this inside of a TLS Record Layer struct. See page 18 of the RFC for what the record layer struct fields need. Here is a link to scapy’s documentation for a record layer struct.

Here’s an example of a construction of the TLS Record struct that encapsulates our packet from ClientHello struct from above:

clienthello = TLS(type=22, version = 0x0302, len=len(clienthellopayload)) / clienthellopayload

Notice how the length of the payload of the record struct was simply attached on using a ‘/‘ symbol. This way of stacking packets is how you can encapsulate structs within other structs for scapy. Also getting the length was very simple as I just used the len() function on the struct’s name.

Now that we have both the record layer and payload we are ready to send our ClientHello! We can simply send it into the socket we created before by using the function send(). Here’s an example:

s.send(raw(clienthello))

To receive the response from this socket we can simply use the recv() function with the amount of bytes we want as our parameter. Additionally we can just supply the received bytes into the TLS() class to organize the data into a struct. Here’s an example.

serverhelloserialized = s.recv(5000) #Receiving 5000 bytes
serverhello = TLS(serverhelloserialized)

Here’s a link to the recv and send functions for sockets.

At this point you should now have a basic understanding of how to use the documentation of Scapy and Sockets as well as how to use the RFC to construct structs, encapsulate them, and send them along. Heartbleed’s exploit will require you to use extensions in the ClientHello. Consult the RFC and Scapy documenation to see how to apply this. (It is just another layer of encapsulation). Good luck!

Link to the HeartBeat Extension.