SEED Labs
1
Transport Layer Security (TLS) Lab
Copyright © 2020 by Wenliang Du.
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. If you remix, transform, or build upon the material, this copyright notice must be left intact, or reproduced in a way that is reasonable to the medium in which the work is being re-published.
1 Overview
Nowadays more and more data transmissions are done through the Internet. However, when data are trans- mitted over such a public network unprotected, they can be read or even modified by others. Applications worrying about the security of their communication need to encrypt their data and detect tampering. Cryp- tographic solutions can be used to achieve this goal. There are many cryptographic algorithms, and even for the same algorithm, there are many parameters that can be used. To achieve interoperability, i.e., allowing different applications to communicate with one another, these applications need to follow a common stan- dard. TLS, Transport Layer Security, is such a standard. Most web servers these days are using HTTPS, which is built on top of TLS.
The objective of this lab is to help students understand how the TLS works and how to use TLS in pro- gramming. The lab guides students to implement a pair of TLS client and server programs, based on which students will conduct a series of experiments, so they can understand the security principles underlying the TLS protocol. Students will also implement a simple HTTPS proxy program to understand the security impact if some trusted CAs are compromised. The lab covers the following topics:
• Public-Key Infrastructure (PKI) • Transport Layer Security (TLS) • TLS programming
• HTTPS proxy
• X.509 certificates with the Subject Alternative Name (SAN) extensions • Man-In-The-Middle attacks
Prerequisite. This lab depends on the PKI lab. Students should do the PKI lab before working on this lab. Readings. Detailed coverage of PKI and TLS can be found in the following:
• Chapters 24 and 25 of the SEED Book, Computer & Internet Security: A Hands-on Approach, 2nd Edition, by Wenliang Du. See details at https://www.handsonsecurity.net.
Lab Environment. This lab has been tested on the SEED Ubuntu 20.04 VM. You can download a pre- built image from the SEED website, and run the SEED VM on your own computer. However, most of the SEED labs can be conducted on the cloud, and you can follow our instruction to create a SEED VM on the cloud.
SEED Labs 2
2 Lab Environment
In this lab, we use three machines, one for client, one for server, and the other for proxy. We will use containers for these machines. Their IP addresses are listed in the following:
Container Setup and Commands. Please download the Labsetup.zip file to your VM from the lab’s website, unzip it, enter the Labsetup folder, and use the docker-compose.yml file to set up the lab environment. Detailed explanation of the content in this file and all the involved Dockerfile can be found from the user manual, which is linked to the website of this lab. If this is the first time you set up a SEED lab environment using containers, it is very important that you read the user manual.
In the following, we list some of the commonly used commands related to Docker and Compose. Since we are going to use these commands very frequently, we have created aliases for them in the .bashrc file (in our provided SEEDUbuntu 20.04 VM).
All the containers will be running in the background. To run commands on a container, we often need to get a shell on that container. We first need to use the "docker ps" command to find out the ID of thecontainer,andthenuse"docker exec"tostartashellonthatcontainer.Wehavecreatedaliasesfor them in the .bashrc file.
client: 10.9.0.5
server: 10.9.0.43
proxy: 10.9.0.143
$ docker-compose build # Build the container image
$ docker-compose up # Start the container
$ docker-compose down # Shut down the container
// Aliases for the Compose commands above
$ dcbuild
$ dcup
$ dcdown
# Alias for: docker-compose build
# Alias for: docker-compose up
# Alias for: docker-compose down
$ dockps // Alias for: docker ps --format "{{.ID}} {{.Names}}"
$ docksh <id> // Alias for: docker exec -it <id> /bin/bash
// The following example shows how to get a shell inside hostC
$ dockps
b1004832e275 hostA-10.9.0.5
0af4ea7a3e2e hostB-10.9.0.6
9652715c8e0a hostC-10.9.0.7
$ docksh 96
root@9652715c8e0a:/#
// Note: If a docker command requires a container ID, you do not need to
// type the entire ID string. Typing the first few characters will
// be sufficient, as long as they are unique among all the containers.
If you encounter problems when setting up the lab environment, please read the “Common Problems” section of the manual for potential solutions.
SEED Labs 3
Volumes. Code editing is more convenient inside the VM than in containers, because we can use our favorite editors. In order for the VM and container to share files, we have created a shared folder between the VM and the container using the Docker volumes. If you look at the Docker Compose file, you will find out that we have added the following entry to some of the containers. It indicates mounting the ./volumes folder on the host machine (i.e., the VM) to the /volumes folder inside the container. We will write our code in the ./volumes folder (on the VM), so they can be used inside the containers.
3 Task 1: TLS Client
In this task, we will incrementally build a simple TLS client program. Through the process, students will understand the essential elements and security considerations in TLS programming. We will run this client program on the client container.
3.1 Task 1.a: TLS handshake
Before a client and a server can communicate securely, several things need to be set up first, including what encryption algorithm and key will be used, what MAC algorithm will be used, what algorithm should be used for the key exchange, etc. These cryptographic parameters need to be agreed upon by the client and the server. That is the primary purpose of the TLS Handshake Protocol. In this task, we focus on the TLS handshake protocol. The following sample code initiates a TLS handshake with a TLS server (the name of the server needs to be specified as the first command line argument).
Listing 1: handshake.py (in Labsetup/volumes)
volumes:
- ./volumes:/volumes
#!/usr/bin/env python3
import socket, ssl, sys, pprint
hostname = sys.argv[1]
port = 443
cadir = ’/etc/ssl/certs’
# Set up the TLS context
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations(capath=cadir)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
# Create TCP connection
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((hostname, port))
input("After making TCP connection. Press any key to continue ...")
# Add the TLS
ssock = context.wrap_socket(sock, server_hostname=hostname,
do_handshake_on_connect=False)
ssock.do_handshake() # Start the handshake
pprint.pprint(ssock.getpeercert())
SEED Labs 4
input("After handshake. Press any key to continue ...")
# Close the TLS Connection
ssock.shutdown(socket.SHUT_RDWR)
ssock.close()
Tasks. Use the code above to communicate with a real HTTPS-based web server. Additional code may need to be added to complete the tasks. Students can find the manual for Python’s SSL module online. Please report the following:
3.2
• • • •
What is the cipher used between the client and the server? Please print out the server certificate in the program. Explain the purpose of /etc/ssl/certs.
Use Wireshark to capture the network traffics during the execution of the program, and explain your observation. In particular, explain which step triggers the TCP handshake, and which step triggers the TLS handshake. Explain the relationship between the TLS handshake and the TCP handshake.
Task 1.b: CA’s Certificate
In the previous task, we use the certificates in the /etc/ssl/certs folder to verify server’s certificates. In this task, we will create our own certificate folder, and place the corresponding certificates in the folder to do the verification.
Please create a folder called client-certs, and change the cadir line in the client program to the following. Run the client program and report your observation.
cadir = ’./client-certs’
To solve this problem, you need to place the corresponding CA’s certificate into your client-certs folder. Please use your client program to find out what CA certificate is needed to verify the www.example.com server’s certificate, and then copy the certificate from the /etc/ssl/certs to your own folder. Run your client program again. If you have done everything correctly, your client program should be able to talk to
the server.
It should be noted that copying CA’s certificate to the "./client-certs" folder is not enough. When TLS tries to verify a server certificate, it will generate a hash value from the issuer’s identify infor- mation, use this hash value as part of the file name, and then use this name to find the issuer’s certificate in the "./client-certs" folder. Therefore, we need to rename each CA’s certificate using the hash value generated from its subject field, or we can make a symbolic link out of the hash value. In the following command, we use opensslto generate a hash value, which is then used to create a symbolic link.
$ openssl x509 -in someCA.crt -noout -subject_hash
4a6481c9
$ ln -s someCA.crt 4a6481c9.0 $ ls -l
total 4
lrwxrwxrwx 1 ... 4a6481c9.0 -> someCA.crt
-rw-r--r-- 1 ... someCA.crt
SEED Labs 5
Additional requirement: Please conduct this task for two different web servers that use different CA certificates.
3.3 Task 1.c: Experiment with the hostname check
The objective of this task is to help students understand the importance of hostname checks at the client side. Please conduct the following steps using the client program.
• Step 1: Get the IP address of www.example.com using the dig command, such as the following (you may want to run this command in your VM or host computers, because the dig command is not installed inside the container):
• Step 2: Modify the /etc/hosts file (inside the container), add the following entry at the end of the file (the IP address is what you get from the dig command).
93.184.216.34 www.example2020.com
• Step 3: Switch the following line in the client program between True and False, and then connect your client program to www.example2020.com. Describe and explain your observation.
context.check_hostname = False # try both True and False
The importance of hostname check: Based on this experiment, please explain the importance of host- name check. If the client program does not perform the hostname check, what is the security consequence? Please explain.
3.4 Task 1.d: Sending and getting Data
In this task, we will send data to the server and get its response. Since we choose to use HTTPS servers, we need to send HTTP requests to the server; otherwise, the server will not understand our request. The following code example shows how to send HTTP requests and how to read the response.
$ dig www.example.com
...
;; ANSWER SECTION:
www.example.com. 403 IN A 93.184.216.34
# Send HTTP Request to Server
request = b"GET / HTTP/1.0
Host: " +
hostname.encode(’utf-8’) + b"
"
ssock.sendall(request)
# Read HTTP Response from Server
response = ssock.recv(2048)
while response:
pprint.pprint(response.split(b"
"))
response = ssock.recv(2048)
SEED Labs 6
Tasks. (1) Please add the data sending/receiving code to your client program, and report your observation. (2) Please modify the HTTP request, so you can fetch an image file of your choice from an HTTPS server (there is no need to display the image).
4 Task 2: TLS Server
Before working on this task, students need to create a certificate authority (CA), and use this CA’s private key to create a server certificate for this task. How to do these is already covered in another SEED lab (the PKI lab), which is the prerequisite for this lab. In this task, we assume that all the required certificates have already been created, including CA’s public-key certificate and private key (ca.crt and ca.key), and the server’s public-key certificate and private key (server.crt and server.key). It should be noted that the common name used in the server certificate must contain the student’s last name and the current year.
We will use the server container to run this TLS server program. Make sure you set up the DNS mapping accordingly, so the name of your TLS server points to the IP address of the server container.
4.1 Task 2.a. Implement a simple TLS server
In this task, we will implement a simple TLS server. We will use the client program from Task 1 to test this server program. A sample server code is provided in the following.
Listing 2: server.py (in Labsetup/volumes)
#!/usr/bin/env python3
import socket
import ssl
html = """
HTTP/1.1 200 OK
Content-Type: text/html
请加QQ:99515681 邮箱:99515681@qq.com WX:codinghelp