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.
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.
What is a certificate and what role do they play in the TLS ecosystem? How do certificates help make TLS more scalable?
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.
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.
(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.
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.
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.
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
.
Follow the instructions here to create a run a new copy of the VM.
Boot into the VM. The password for the user account is
dees
.
Open Firefox within the VM, navigate to this website and download the Labsetup files.
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.
Please write short answer the following questions. Where applicable, make sure you cite your sources:
What RFC specifies the Heartbeat extension? What is the reason to include the Heartbeat extension?
What should happen when when a server receives a malformed heartbeat request? Where is this specified in the RFC?
What was the practical impact of the heartbleed attack? How many servers were effected? (cite any sources you find)
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?
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?
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.
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.
You should submit a PDF along with a zip containing your code. Be sure that you submission includes:
heartbleed
that runs your attack code. It should be
able to be run with the interfaces specified above. PLEASE
DOUBLE CHECK TO MAKE SURE YOU ARE ADHEREING TO THE INTERFACES
EXACTLY.
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.]
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
= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s connect('1.1.1.1'; 80 ) socket.
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.
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 *
'tls') load_layer(
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.