MCS-377 Lab 3: Network Layer (Fall 2014)

Due: November 18, 2014

Objective

Working in an assigned team of two or three students, you will explore how with knowledge of the structure of IP datagrams, you can write software that allows one computer to "spoof" another by sending out datagrams that appear to come from a different source. You'll see how this can cause security issues when the spoofed datagrams are targeted at a naively designed application such as our textbook's example UDP server.

Preparing experimental systems

Each team will use three computers I will provide that are running the Ubuntu distribution of Linux. (Each computer can be logged in under the mcs account using the password 377.) The three computers will not be connected to the campus network (or any other external network) during your experimentation. Instead, you will connect each using an Ethernet cable to an Ethernet switch that I will provide, forming a small local network. In the following description I refer to your team's computers as computers A, B, and C.

  1. Connect the Ethernet switch to a power outlet.

  2. Do the following on each computer:

  3. Get the textbook's example running as expected on computers A and B:

Using spoofing to generate a ricochet

In order to have a context in which to try out spoofing, do the following steps:

  1. On computer A, kill off the UDPServer, for example by typing control-C in its terminal window.

  2. On computer B, run the UDPClient and enter a line of text. Using Wireshark, you should see that the UDP packet was sent to computer A, but that no reply came back because the server wasn't running. Continuing with Wireshark, make a note of the source port number on computer B that the client request came from. Leave the UDPClient on B running, waiting for a reply.

  3. On computer A, start the UDPServer back up. Because the request from computer B has already been missed, you should still see the client on B hanging. Leave it that way -- our goal is to show how spoofing can allow computer C to generate a "ricochet" reply from A that goes to the waiting client on B, rather than back to C.

The fundamental tool you will use is the ability to open a "raw socket" that doesn't provide any network- or transport-layer services. Instead, when your program wants to send a packet, you provide the entire array of bytes that starts with the IP header, continues with the transport-layer header (such as UDP or TCP), and then continues on into the payload data. The raw socket passes that array of bytes directly to the link layer (Ethernet) for transmission. This gives you complete control over all of the header contents, including the ability to set a "source address" that isn't actually the address of the computer sending the packet.

Using information from the RFCs, you could figure out exactly what bytes to put where in order to construct IP and UDP headers. However, to make our life easier, the spoofUDP.py code I've given you makes use of a package Kenneth Jiang wrote call pyip which allows you to just specify what should go in each header field; it puts the data in the proper positions and formats.

On computer C, install the pyip module. In a terminal window, change directory into the pyip-0.7 directory that you unpacked from the zip file and then execute the following command:

sudo python setup.py install

Continuing on computer C, edit the file spoofUDP.py. Fill in as the source IP address the address of computer B; although the packet is actually going to come from computer C, it is going to claim to be from B. Likewise, fill in the source port number based on computer B's waiting UDPClient program (as earlier noted in Wireshark). For the destination IP address and port number, fill in the information about computer A's UDPServer.

After doing these edits, change your terminal window's directory to the one containing spoofUDP.py and run the following:

sudo python spoofUDP.py

With any luck, you'll see that the UDPClient on computer B is no longer waiting: it has printed out an upper-case version of the data sent by computer C's spoofUDP program (not an upper-case version of the data previously entered on computer B). Using Wireshark, you should be able to see that what happened is that computer A got a UDP packet that claimed to be from computer B, although actually it was from computer C. Therefore, computer A "replied" to computer B.

If this experiment didn't work, or you don't understand what happened, get whatever help you need before moving on to the next part.

More consequences of spoofing

Make one small change in the spoofUDP.py program: change the source port number so that instead of being the port that was used by computer B's UDPClient (which is no longer running), it is the port used by computer B's UDPServer. Leave the other parameters unchanged and once again run the following in a terminal window:

sudo python spoofUDP.py

Look for signs of what behavior results. One key place to look will be the Wireshark captures you left running. There may be other signs as well. If you don't see anything noteworthy, ask for help.

Your report

Your team should jointly author a report that answers the following questions, each worth 1 point:

  1. What four key fields within the IP and UDP headers are relevant to your experiments?

  2. Of those four, which are in the IP header and which in the UDP header?

  3. Which of the four are relevant to getting a UDP message to a socket?

  4. What are the other ones used for, which can be freely changed without disrupting the ability to reach the destination socket?

  5. What did you observe on the various computers when computer C pretended to be the client waiting on computer B?

  6. What did you observe on the various computers (and perhaps the Ethernet switch) when computer C pretended to be the server running on computer B?

  7. Extra credit: Can you think of any defense against this sort of spoofing? Would it make any difference if the originating computer were on a separate network?

Submission

One student from each team should upload your report to Moodle.


Course web site: https://gustavus.edu/+max/courses/F2014/MCS-377/
Instructor: Max Hailperin <max@gustavus.edu>