Hello again, in this blog post, I will be detailing how I used Scapy to gain more analysis from my .pcap captures. Please see my prior post where I captured wireless packet information using Mac’s built-in WiFi sniffer.
Scapy is a powerful Python library for packet manipulation. It allows you to create, send, capture, and analyze network packets. While it’s commonly used for crafting custom packets and network exploration, it doesn’t directly edit existing PCAP files. Instead, Scapy enables you to build packets from scratch or modify their fields programmatically.
Using Scapy
To use Scapy you need to first have python3 installed. Scapy can then be installed by the following command:
pip install scapy
I will be utilizing the packet processing feature to read in the packets I captured in my previous post. This script will print the source IP, destination IP, and some other HTTP header info. Attached is the code I used to do that.
from scapy.all import *
import re
def process_packet(packet, output_file, ssid_filter):
"""
Process each packet in the pcap file.
"""
with open(output_file, "a") as file:
# Example: Print the summary of the packet
file.write(packet.summary() + "\n")
# You can access more attributes of the packet and perform analysis here
# Example: Print the source and destination IP addresses
if IP in packet:
file.write("Source IP: " + packet[IP].src + "\n")
file.write("Destination IP: " + packet[IP].dst + "\n")
# Example: Print the source and destination ports for TCP/UDP packets
if TCP in packet:
file.write("Source Port (TCP): " + str(packet[TCP].sport) + "\n")
file.write("Destination Port (TCP): " + str(packet[TCP].dport) + "\n")
# Example: Print TCP flags
file.write("TCP Flags: " + str(packet[TCP].flags) + "\n")
# Example: Look for HTTP requests
if packet.haslayer(Raw):
load = packet[Raw].load.decode(errors='ignore')
if load.startswith("GET") or load.startswith("POST"):
file.write("HTTP Request:\n")
file.write(load + "\n")
# Extracting host from HTTP request
host = re.search(r'Host: (.+?)\r\n', load)
if host:
file.write("Requested Host: " + host.group(1) + "\n")
elif UDP in packet:
file.write("Source Port (UDP): " + str(packet[UDP].sport) + "\n")
file.write("Destination Port (UDP): " + str(packet[UDP].dport) + "\n")
# Look for DNS queries
if DNS in packet:
dns_layer = packet.getlayer(DNS)
if dns_layer and dns_layer.opcode == 0 and dns_layer.qd:
file.write("DNS Query: " + dns_layer.qd.qname.decode() + "\n")
# Look for ARP packets
if ARP in packet:
if packet.op == 1: # ARP request
file.write("ARP Request: Who has " + packet.pdst + "? Tell " + packet.psrc + "\n")
elif packet.op == 2: # ARP reply
file.write("ARP Reply: " + packet.psrc + " is at " + packet.hwsrc + "\n")
# Example: Infer device type based on MAC address
mac_address = packet.hwsrc
if mac_address.startswith("00:50:56"): # VMware virtual machine
file.write("Device Type: VMware Virtual Machine\n")
elif mac_address.startswith("00:1E:8C"): # Cisco device
file.write("Device Type: Cisco Device\n")
elif mac_address.startswith("00:0C:29"): # VMware virtual machine
file.write("Device Type: VMware Virtual Machine\n")
# Add more conditions as needed for other device types
# Filter packets for specific SSID
if packet.haslayer(Dot11) and packet.type == 0 and packet.subtype == 8: # Management frames (type=0, subtype=8)
ssid = packet[Dot11Elt].info.decode()
if ssid == ssid_filter:
file.write("SSID: " + ssid + "\n")
# Look for HTTP requests
if packet.haslayer(Raw):
load = packet[Raw].load.decode(errors='ignore')
if load.startswith("GET") or load.startswith("POST"):
file.write("HTTP Request:\n")
file.write(load + "\n")
# Extracting host from HTTP request
host = re.search(r'Host: (.+?)\r\n', load)
if host:
file.write("Requested Host: " + host.group(1) + "\n")
def main():
#SIOBHAN CHANGE
pcap_file = "~/desktop/long_canisius.pcap"
output_file = "l_canisius.txt"
ssid_filter = "canisius_guest" # Specify the SSID you want to filter for
packets = rdpcap(pcap_file)
# Process each packet
for packet in packets:
process_packet(packet, output_file, ssid_filter )
if __name__ == "__main__":
main()
Scapy allows you to filter packets based on specific criteria. Filtering helps you selectively process only the packets that match certain conditions. This allows for me to filter specifically onto the network that I am looking to target and exclude any nuisance traffic that may also be on the scan. In the instance below I provide an example of how I filtered on my University’s guest wireless network. You can imagine being in any public location with free wifi and doing the same.
What It Tells Us
The output is recorded in a text file that is easier to read. What does this tell us. One item is – where are people connecting to – the Destination IP. Using the NordVPN IP lookup, we see it goes to Google. See the image below – this person was connecting to the Google search site.
All of the HTTP traffic that I was able to collect is on port 443. This means it’s all encrypted. The next hurdle will be tackling to see if I can find ways to leverage the encrypted web traffic.