Scapy is a powerful Python library used for packet manipulation. It allows network engineers and security professionals to capture, create, and manipulate network packets with ease. Scapy supports a wide range of network protocols and provides a flexible framework to perform tasks such as network scanning, tracerouting, probing, unit tests, attacks, and network discovery. This flexibility and power come from its ability to handle various packet layers and protocols seamlessly.
Using Scapy to Create Packets
To create packets using Scapy, you need to understand the structure of network packets, which are composed of multiple layers. Each layer adds specific information required for network communication. Scapy simplifies the process of creating these layers and allows stacking them to form complete packets.
Installation
First, install Scapy using pip:
pip install scapy
Creating Layers in Packets
Ethernet Layer: The Ethernet layer is the link layer used for local network communication. The
Ether
class in Scapy provides several options to configure the Ethernet frame.from scapy.all import Ether eth = Ether(dst="ff:ff:ff:ff:ff:ff", src="00:11:22:33:44:55", type=0x0800) print(eth.show())
Options:
dst
: Destination MAC address.src
: Source MAC address.type
: EtherType field, indicating the protocol encapsulated in the payload (e.g., 0x0800 for IPv4).
IP Layer: The Internet Protocol (IP) layer is responsible for addressing and routing packets across networks. The
IP
class provides various fields to configure the IP header.from scapy.all import IP ip = IP(dst="8.8.8.8", src="192.168.1.100", ttl=64, tos=0x10, id=54321, flags="DF", proto="tcp") print(ip.show())
Options:
dst
: Destination IP address.src
: Source IP address.ttl
: Time-to-Live.tos
: Type of Service.id
: Identification field.flags
: Flags (e.g., "DF" for Don't Fragment, "MF" for More Fragments).proto
: Protocol (e.g., "tcp", "udp", "icmp").
TCP Layer: The Transmission Control Protocol (TCP) layer ensures reliable communication through error checking and retransmission. The
TCP
class allows you to configure TCP segment fields.from scapy.all import TCP tcp = TCP(sport=12345, dport=80, seq=1000, ack=1001, dataofs=5, reserved=0, flags="S", window=8192, urgptr=0, options=[('MSS', 1460)]) print(tcp.show())
Options:
sport
: Source port.dport
: Destination port.seq
: Sequence number.ack
: Acknowledgment number.dataofs
: Data offset.reserved
: Reserved bits.flags
: Control flags (e.g., "S" for SYN, "A" for ACK, "F" for FIN).window
: Window size.urgptr
: Urgent pointer.options
: TCP options (e.g.,('MSS', 1460)
for Maximum Segment Size).
UDP Layer: The User Datagram Protocol (UDP) layer provides a lightweight, connectionless communication protocol. The
UDP
class allows you to configure UDP segment fields.from scapy.all import UDP udp = UDP(sport=12345, dport=53, len=8, chksum=0) print(udp.show())
Options:
sport
: Source port.dport
: Destination port.len
: Length of the UDP segment.chksum
: Checksum (can be left as 0 for automatic calculation).
ICMP Layer: The Internet Control Message Protocol (ICMP) layer is used for sending error messages and operational information. The
ICMP
class provides various types and codes for different ICMP messages.from scapy.all import ICMP icmp = ICMP(type=8, code=0, id=0x1234, seq=1) print(icmp.show())
Options:
type
: ICMP type (e.g., 8 for Echo Request, 0 for Echo Reply).code
: ICMP code (depends on the type).id
: Identifier.seq
: Sequence number.
Combining Layers to Form Complete Packets
Scapy allows you to combine these layers to form complete packets. You can stack the layers using the /
operator.
from scapy.all import Ether, IP, TCP
# Combining Ethernet, IP, and TCP layers
packet = Ether(dst="ff:ff:ff:ff:ff:ff", src="00:11:22:33:44:55") / IP(dst="8.8.8.8", src="192.168.1.100") / TCP(dport=80, flags="S")
print(packet.show())
Sending Packets
Once you have created the packet, you can send it over the network using Scapy’s sendp
function for Ethernet-layer packets or send
for IP-layer packets.
from scapy.all import send, sendp
# Sending the packet
sendp(packet) # Use sendp for Ethernet-layer packets
# send(packet) # Use send for IP-layer packets
Full Example: Creating and Sending a Packet
Below is a complete example that demonstrates how to create and send a custom packet with Ethernet, IP, and TCP layers using Scapy.
from scapy.all import Ether, IP, TCP, sendp
# Define Ethernet layer
eth = Ether(dst="ff:ff:ff:ff:ff:ff", src="00:11:22:33:44:55", type=0x0800)
# Define IP layer
ip = IP(dst="8.8.8.8", src="192.168.1.100", ttl=64, tos=0x10, id=54321, flags="DF", proto="tcp")
# Define TCP layer
tcp = TCP(sport=12345, dport=80, seq=1000, ack=1001, dataofs=5, reserved=0, flags="S", window=8192, urgptr=0, options=[('MSS', 1460)])
# Combine layers to form a complete packet
packet = eth / ip / tcp
# Display packet details
print(packet.show())
# Send the packet
sendp(packet)
Conclusion
Scapy is an indispensable tool for network engineers and security professionals. It offers a versatile framework for creating and manipulating network packets at various layers. By understanding the structure of network packets and how to use Scapy to build them, you can perform a wide range of network tasks efficiently. Whether you are conducting network tests, probing, or developing custom network tools, Scapy provides the functionality you need.
Key takeaways:
Scapy allows detailed manipulation of network packets.
You can create and stack layers such as Ethernet, IP, TCP, UDP, and ICMP with extensive customization options.
Scapy simplifies network tasks through its flexible and powerful framework.
By leveraging Scapy, you can enhance your network automation and security testing capabilities, making it an essential skill in the NetDevOps toolkit.