Python Pentesting: Capture & Save TCP/IP Packets in PCAP Files
Hello Readers! Today’s tutorial will cover how to save TCP/IP packets in a PCAP file using Python. Handling and analyzing network packets is a crucial skill for professionals working on network projects. Capturing and storing these packets allows for detailed analysis using tools like Wireshark, which can provide insights and improve network security.
Why Save Raw Network Packets?
In many networking projects and penetration testing tasks, the ability to capture and save raw network packets is invaluable. These stored packets can later be analyzed to uncover vulnerabilities, understand network behavior, or even troubleshoot issues. Wireshark, one of the most popular network protocol analyzers, supports reading PCAP files, making this task easier and more accessible.
How It Works: Writing Packets to PCAP Files
To facilitate the saving of packets into a PCAP file, we’ll develop a Python class that performs the necessary operations. This class will handle creating a valid PCAP file and writing packets with appropriate headers.
Creating a Valid PCAP File
A PCAP file starts with a global header, which contains metadata about the capture. Our Python class will write this global header when initialized. Key components include:
- A magic number identifying the file type.
- The version of the PCAP format is being used.
- Timing details to coordinate packet timestamps.
- Information about the data link type to specify how packets are captured.
Adding Headers to Network Packets
Each packet captured during our network audit must include a simple header with its capture timestamp and length information. This step is crucial for ensuring that the packet data is correctly interpreted by analysis tools like Wireshark.
Global Header Values
Set up the structure and values for the PCAP global header
# import module
import struct
import time
import socket
import struct
# Pcap Global Header Format :
# ( magic number +
# major version number +
# minor version number +
# GMT to local correction +
# accuracy of timestamps +
# max length of captured #packets, in octets +
# data link type)
#
#
PCAP_GLOBAL_HEADER_FMT = "@ I H H i I I I "
# Global Header Values
PCAP_MAGICAL_NUMBER = 2712847316
PCAP_MJ_VERN_NUMBER = 2
PCAP_MI_VERN_NUMBER = 4
PCAP_LOCAL_CORECTIN = 0
PCAP_ACCUR_TIMSTAMP = 0
PCAP_MAX_LENGTH_CAP = 65535
PCAP_DATA_LINK_TYPE = 1
Reference: https://wiki.wireshark.org/Development/LibpcapFileFormat
Defining the Pcap Class
We’ll create a Python class named `Pcap` to manage PCAP data
class Pcap:
def __init__(self, filename, link_type=PCAP_DATA_LINK_TYPE):
self.pcap_file = open(filename, "wb")
self.pcap_file.write(
struct.pack(
PCAP_GLOBAL_HEADER_FMT,
PCAP_MAGICAL_NUMBER,
PCAP_MJ_VERN_NUMBER,
PCAP_MI_VERN_NUMBER,
PCAP_LOCAL_CORECTIN,
PCAP_ACCUR_TIMSTAMP,
PCAP_MAX_LENGTH_CAP,
link_type,
)
)
print("[+] Link Type : {}".format(link_type))
def writelist(self, data=[]):
for i in data:
self.write(i)
return
def write(self, data):
ts_sec, ts_usec = map(int, str(time.time()).split("."))
length = len(data)
self.pcap_file.write(struct.pack("@ I I I I", ts_sec, ts_usec, length, length))
self.pcap_file.write(data)
def close(self):
self.pcap_file.close()
To see the `Pcap` class in action, integrate it with a packet sniffer code.
if __name__ == "__main__":
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
p = Pcap("temp.pcap")
for index in range(50):
# Sniff Packet
pkt = s.recvfrom(65565)
# Save captured packets into pcap file
p.write(pkt[0])
print(f'[{index}] Packet Captured')
# flush data
p.pcap_file.flush()
# close file
p.close()
Full Script.
# import module
import struct
import time
import socket
import struct
# Author: Suraj Singh Bisht
#
# Pcap Global Header Format :
# ( magic number +
# major version number +
# minor version number +
# GMT to local correction +
# accuracy of timestamps +
# max length of captured #packets, in octets +
# data link type)
#
#
PCAP_GLOBAL_HEADER_FMT = "@ I H H i I I I "
# Global Header Values
PCAP_MAGICAL_NUMBER = 2712847316
PCAP_MJ_VERN_NUMBER = 2
PCAP_MI_VERN_NUMBER = 4
PCAP_LOCAL_CORECTIN = 0
PCAP_ACCUR_TIMSTAMP = 0
PCAP_MAX_LENGTH_CAP = 65535
PCAP_DATA_LINK_TYPE = 1
class Pcap:
def __init__(self, filename, link_type=PCAP_DATA_LINK_TYPE):
self.pcap_file = open(filename, "wb")
self.pcap_file.write(
struct.pack(
PCAP_GLOBAL_HEADER_FMT,
PCAP_MAGICAL_NUMBER,
PCAP_MJ_VERN_NUMBER,
PCAP_MI_VERN_NUMBER,
PCAP_LOCAL_CORECTIN,
PCAP_ACCUR_TIMSTAMP,
PCAP_MAX_LENGTH_CAP,
link_type,
)
)
print("[+] Link Type : {}".format(link_type))
def writelist(self, data=[]):
for i in data:
self.write(i)
return
def write(self, data):
ts_sec, ts_usec = map(int, str(time.time()).split("."))
length = len(data)
self.pcap_file.write(struct.pack("@ I I I I", ts_sec, ts_usec, length, length))
self.pcap_file.write(data)
def close(self):
self.pcap_file.close()
if __name__ == "__main__":
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
p = Pcap("temp.pcap")
for index in range(50):
# Sniff Packet
pkt = s.recvfrom(65565)
# Save captured packets into pcap file
p.write(pkt[0])
print(f'[{index}] Packet Captured')
# flush data
p.pcap_file.flush()
# close file
p.close()
Run this script with Sudo Command and let it capture packets in a pcap file.
Then, Open your ‘temp.pcap’ file in Wireshark to explore your captured packets!
Conclusion
As networks and malicious threats evolve, mastering the art of packet capturing with Python can be an invaluable asset. Future enhancements could include implementing more sophisticated filtering mechanisms or developing real-time analysis to identify potential threats as they occur.
I hope you found this tutorial informative and engaging.
Happy Learning!