Packets, Layers, and Fields. Oh My!

Scapy uses Python dictionaries as the data structure for packets. Each packet is a collection of nested dictionaries with each layer being a child dictionary of the previous layer, built from the lowest layer up. Visualizing the nested packet layers would look something like this:
pkt-layers

 

Each field (such as the Ethernet ‘dst’ value or ICMP ‘type’ value) is a key:value pair in the appropriate layer. These fields (and nested layers) are all mutable so we can reassign them in place using the assignment operator. Scapy has packet methods for viewing the layers and fields that I will introduce next.

Packet summary() and show() Methods

Now let’s go back to our pkt and have some fun with it using Scapy’s Interactive mode. We already know that using the summary() method will give us a quick look at the packet’s layers:

 

But what if we want to see more of the packet contents? That’s what the show() method is for:

 

Very cool, that’s some good info. If you’re familiar with Python you have probably noticed the list index, [0], after the pkt variable name. Remember that our sniff only returned a single packet, but if we increase the count argument value, we will get back an list with multiple packets:

 

Getting the value of the list returns a quick glance at what type of packets were sniffed.

 

And we can show the summary or packet contents of any single packet by using the list index with that packet value. So, let’s look at the contents of the 4th packet (Remember, list indexes start counting at 0):

 

Getting the value of a single packet returns a quick glance of the contents of that packet.

The show() method will give us a cleaner print out:

 

Digging into Packets by Layer

Scapy builds and dissects packets by the layers contained in each packet, and then by the fields in each layer. Each layer is nested inside the parent layer as can be seen with the nesting of the < and > brackets:

 

You can also dig into a specific layer using an list index. If we wanted to get to the ICMP layer of pkts[3], we could do that using the layer name or index number:

 

Since the first index chooses the packet out of the pkts list, the second index chooses the layer for that specific packet. Looking at the summary of this packet from an earlier example, we know that the ICMP layer is the 3rd layer.

Packet .command() Method

If you’re wanting to see exactly how to re-create a packet that’s been sniffed or received, Scapy has a packet method for you! Using the .command() packet method will return a string of the command necessary to recreate that packet, like this:

 

You can assign the output of the .command() method to a new packet using Python’s eval() function, although the same results here could also be achieved by directly assigning the packet value to a new variable. These next two statements do the same thing:

 

Digging into Layers by Field

Within each layer, Scapy parses out the value of each field if it has support for the layer’s protocol. Depending on the type of field, Scapy may replace the value with a more friendly text value for the summary views, but not in the values returned for an individual field. Here are some examples:

 

Using Python control statements with Scapy

The awesome thing about Scapy being a module of Python is that we can use the power of Python to do stuff with our packets. Here’s a tip of the iceberg example using a Python for statement along with some new Scapy packet methods:

 

As you can guess, the haslayer() and getlayer() methods will test for the existence of a layer and return the layer (and any nested layers) respectively. This is just a very basic use of Python statements with Scapy and we’ll see a lot more when it comes to packet generation and custom actions.

 

Series Navigation<< Scapy p.03 – Scapy Interactive ModeScapy p.05 – Sending our First Packet; ARP Response >>

This article has 2 comments

  1. Pingback: Seguridad al Día » Juankeando con la Pitón (9) – AP Scanner con scapy

Leave a Reply

Your email address will not be published. Required fields are marked *