I want to replace the IP addresses in a given PCAP file with Scapy.
The PCAP file (e.g. eth0.pcap
) contains captures by Wireshark.
My message is not code, it shows the data flow between 2 IP addresses. I want to replace the original 2 addresses with another 2 addresses.
Given before:
message1: 192.168.10.10-->192.168.20.20
message2: 192.168.20.20-->192.168.10.10
I want to replace for all packages within the file:
192.168.10.10
(source of first package) with 8.8.8.8
192.168.20.20
(destination of first package) with 1.1.1.1
So that afterwards there are:
message1: 172.10.10.10-->172.10.20.20
message2: 172.10.20.20-->172.10.10.10
How can I do this with?
So you want to modify packet capture output, like in PCAP file format. This format is used by libpcap library to record captured packets to a file.
Scapy can read and write PCAP files, see the Scapy docs for PCAP.
To replace the IP addresses within this file, you have to read its packets into an object-model using the rdpcap()
function.
Then you can print the IP addresses for each packet (with desired replacement).
Or you can also replace the IP within the object-model in memory.
Then write the complete model back using the wrpcap()
function.
I used the example PCAP file dhcp.pcap
from PCAP to Mermaid parser on GitHub:
from scapy.all import *
# load the PCAP file using rdpcap
packets = rdpcap('dhcp.pcap')
# Let's iterate through every packet
for packet in packets:
source_ip = packet.getlayer(IP).src
destination_ip = packet.getlayer(IP).dst
print(f"{source_ip} --> {destination_ip}")
# TODO: replace in model and write to PCAP file using wrpcap
Update:
Refined talentldk's solution with some simplification and debug-prints:
all
imports all)wrpcap
to write the read modelreplace
function where dict entry (a tuple) is passed to function using the unpack-operator *
as prefix resulting in 2 separate arguments (key is replaced by value)iter
over the dict's items to process all replacements (here 2 entries) where the next item can be drawn by next
functionfrom scapy.all import *
# rdpcap loads in our pcap file
packets = rdpcap('dhcp.pcap')
# define search
first_src_ip = packets[0][IP].src
first_dst_ip = packets[0][IP].dst
# define new ip address to use as replacement
ip_replacement = {f"{first_src_ip}" : '8.8.8.8', f"{first_dst_ip}" : '1.1.1.1'}
print(f"replacement: {ip_replacement}")
# Let's iterate through every packet
for i, packet in enumerate(packets):
source_ip = packet.getlayer(IP).src
destination_ip = packet.getlayer(IP).dst
print(f"[{i:3}] original: {source_ip} --> {destination_ip}")
# replace in model
replacement = iter(ip_replacement.items())
source_ip = source_ip.replace(*next(replacement))
destination_ip = destination_ip.replace(*next(replacement))
print(f"[{i:3}] replaced: {source_ip} --> {destination_ip}")
wrpcap("dhcp_replaced.pcap", packets)
Prints:
replacement: {'0.0.0.0': '8.8.8.8', '255.255.255.255': '1.1.1.1'}
[ 0] original: 0.0.0.0 --> 255.255.255.255
[ 0] replaced: 8.8.8.8 --> 1.1.1.1
[ 1] original: 192.168.0.1 --> 192.168.0.10
[ 1] replaced: 192.168.0.1 --> 192.168.0.10
[ 2] original: 0.0.0.0 --> 255.255.255.255
[ 2] replaced: 8.8.8.8 --> 1.1.1.1
[ 3] original: 192.168.0.1 --> 192.168.0.10
[ 3] replaced: 192.168.0.1 --> 192.168.0.10