Scapy
Scapy is a powerful Python-based interactive packet manipulation tool that enables users to forge, decode, send, and sniff network packets. It supports a wide array of protocols and can function as an interactive shell (REPL) or as a library within Python scripts. Scapy runs on Linux, macOS, most Unix-like systems, and Windows (requiring Npcap). The current version is 2.7.0, and it maintains an active release cadence.
Warnings
- breaking The behavior of `StreamSocket` has changed. `TCPSession(app=True)` should no longer be used with `StreamSocket` as custom sessions are now marked unstable. This affects TCP reassembly and other stream-related functionalities.
- breaking The Scapy CLI configuration file location moved from `~/.scapy_startup.py` to `~/.config/scapy/startup.py` to align with XDG variables. Older configuration files in the old location are no longer functional.
- deprecated Using the `iface=` argument with Layer 3 functions (`send`, `sr`, `sr1`) is deprecated due to undefined behavior. It remains valid for Layer 2 functions (`sendp`, `srp`, `srp1`).
- breaking Scapy 2.6.x dropped support for Python 2.7. Additionally, Scapy 2.7.0 is announced as the last version to support Python 3.7 and 3.8.
- gotcha Scapy often requires root or administrator privileges to send and sniff raw packets, as it interacts directly with network interfaces at a low level.
- gotcha Scapy might eagerly send real packets to resolve names or perform other network interactions, even when intended for offline analysis. This can lead to unintended network activity.
Install
-
pip install scapy
Imports
- *
from scapy.all import *
Quickstart
from scapy.all import *
# Craft an IP packet with an ICMP payload
packet = IP(dst="8.8.8.8")/ICMP()
# Send the packet and receive a response
# Note: Requires root/admin privileges to send/receive raw packets
# Use os.environ.get('SCAPY_IFACE', 'eth0') to specify an interface if needed
# For simple testing, can often run as sudo python your_script.py
# sr1 sends one packet and waits for one answer
# timeout is crucial for non-blocking execution in scripts
resp = sr1(packet, timeout=1, verbose=0)
if resp:
print(f"Received response from: {resp.src}")
resp.show()
else:
print("No response received.")
# Example of sniffing packets (run for 2 packets or 5 seconds)
# Sniffing often requires elevated privileges
def print_packet_summary(pkt):
print(pkt.summary())
# sniff(prn=print_packet_summary, count=2, timeout=5)
# print("Sniffing complete.")