In this lab, we first set up three virtual machines that we will use in this lab and later ones. Then, we will learn how to use raw sockets to sniff packets.

Note: Do this lab with your laptop

[20pts] Part 1: Set up three VMs

Please follow the instructions given here to install three VMs.

Deliverables: Show the following works in the lab report (add screenshots as necessary).

[40pts] Part 2: Packet Sniffing

So far, we used TCP/UDP sockets. However, we can create sockets to deal with lower-level layers. For this, we will use raw sockets. The documentation about sockets can be found here

Packet sniffing using a raw socket

To create a raw socket for dealing with Ethernet frames, one can do the following:

from socket import *
ETH_P_ALL = 0x0003
raw_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
Note although it's defined in C header file linux/if_ether.h, ETH_P_ALL is not defined in Python3. So we just created the variable with that name.

Reading packets

Create a file raw.py as follows:

#!/usr/bin/python3
# raw.py

from socket import *
ETH_P_ALL = 0x0003
raw_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

(data, addr) = raw_socket.recvfrom(1024)

print("addr=", addr)
print(" ".join([f"{data[i]:02x}" for i in range(16)]))
print("data=", data)
(If you are not familiar with join(), refer to this tutorial).

Note that the code sniffs a simple packet and prints them. Execute the following command in the terminal to see how it works.

sudo python3 raw.py

Analyzing the output (the first 16 bytes of data)

It will probably output something like this:
~$ sudo python3 raw.py
addr= ('enp0s3', 2048, 0, 1, b'RT\x00\x125\x00')
08 00 27 b3 0c 54 52 54 00 12 35 00 08 00 45 00
data= b"\x08\x00'\xb3\x0cTRT\x00\x125\x00\x08\x00E\x00\x00G\x10\xaf  .... \xb9"
The second line of the output shows the first 16 bytes of the data. Indeed, if you are observant, you will see this is actually an Ethernet frame!
 0                   1                   2                   3   
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|[               Destination MAC Address (6 bytes)              |
+                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              ]|[                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
|                Source MAC Address (6 bytes)                  ]|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|[     Type/Length of Data      |[                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
|              Client Data + padding (46-1500 bytes)            |
|                        ....                                  ]|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    CRC Checksum (4 bytes)                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
08 00 27 b3 0c 54 52 54 00 12 35 00 08 00 


Dst MAC Addr: 08 00 27 b3 0c 54
Src MAC Addr: 52 54 00 12 35 00 
Type of Data: 08 00

45 00?

Then, what is the next two bytes 45 00? It's actually the first 4 bytes of IP header.
 0                   1                   2                   3   
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |R D M|      Fragment Offset    |
|                               |S F F|                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 00


The first 4-bit is 4, which is Version.
The next 4-bit is 5, which is IHL.
The next 8-bit (i.e., one byte) is Type of Service, which is 0x00. 

Your Task (read the instructions very carefully)

Write python code sniff.py that works as follows:
  • Do a netcat chat between it430a and it430b. Use a port number 9000 when a socket listens.
  • Perform packet sniffing at it430a by running the following command:
    sudo python3 sniff.py
  • In sniff.py, make an infinite loop of receiving a packet and analyzing and printing it. Moreover, focus only on the UDP packets for the netcat chat. In particular,
    • Ignore all non-IP packets. Check if the Type field of the Ethernet frame is 0x0800 (i.e., data[12:14]).
    • Ignore all non-UDP packets. Check the Protocol field of the IP header and ignore all non-UDP packets.
    • Keep only the UDP packets whose the src or dst port is 9000. This way, sniff.py should
    • capture the packets in both directions of the netcat chat.
  • Feel free to use the python code in lab02.py to extract and print out relevant parts correctly.
A sample run:
~$ sudo python3 sniff.py
src: 192.168.172.4(9000) [08:00:27:f3:5c:ca]
dst: 192.168.172.5(53205) [08:00:27:6b:ad:50]
b'test\n'

src: 192.168.172.4(9000) [08:00:27:f3:5c:ca]
dst: 192.168.172.5(53205) [08:00:27:6b:ad:50]
b'world\n'

src: 192.168.172.4(9000) [08:00:27:f3:5c:ca]
dst: 192.168.172.5(53205) [08:00:27:6b:ad:50]
b'good\n'

src: 192.168.172.5(53205) [08:00:27:6b:ad:50]
dst: 192.168.172.4(9000) [08:00:27:f3:5c:ca]
b'note\n'

src: 192.168.172.5(53205) [08:00:27:6b:ad:50]
dst: 192.168.172.4(9000) [08:00:27:f3:5c:ca]
b'problem\n'

src: 192.168.172.5(53205) [08:00:27:6b:ad:50]
dst: 192.168.172.4(9000) [08:00:27:f3:5c:ca]
b'test is the\n'

src: 192.168.172.4(9000) [08:00:27:f3:5c:ca]
dst: 192.168.172.5(53205) [08:00:27:6b:ad:50]
b'bla bla bla\n'

Deliverables:

[10pts] Part 3: Sniffing Packets From a Different Machine

Deliverables:

[20pts] Part 4: Reading Assignment

  1. Click here to download chapter 2 of the following book:
    Security Engineering, 3rd ed. by Ross Anderson
  2. Read the following:
    • 2.3 Crooks
    (Eventually, we will finish reading the whole chapter. Expect further reading assignments in later labs.)
  3. In the lab report, give a brief summary of what you read.

[10pts] Lab Report and Submission

Write a lab report by using the provided template.

Your lab report should contain:
~/bin/submit -c=IT430 -p=lab05 *.py lab_report.docx