Unable to compute checksum for igmpv3 using scapy - python-3.x

Following is the snippet of my code.
It opens a pcap file called test.
File : https://easyupload.io/w81oc1
Edits a value called as QQIC.
Creates a new pcap file.
from scapy.all import *
from scapy.utils import rdpcap
from scapy.utils import wrpcap
import scapy.contrib.igmpv3
#Read the pcap file
pkt = rdpcap("test.pcap")
#Edit the value of qqic
pkt[0]['IGMPv3mq'].qqic = 30
# Writ it to the pcap file.
#wrpcap("final.pcap",pkt)
All this works fine.
However, when I check the pcap, I get an error stating that the checksum is invalid.
PCAP
Cant figure out a way to re compute the check sum.

When you edit a packet (particularly an explicit packet, that is, a packet that has been read from a PCAP file or a network capture) in Scapy, you have to "delete" the fields that need to be computed again (checksum fields as here, but also sometimes length fields). For that, you can use the del statement:
from scapy.all import *
load_contrib("igmpv3")
# Read the pcap file
pkt = rdpcap("test.pcap")
# Edit the value of qqic
pkt[0]['IGMPv3mq'].qqic = 30
# Force Scapy to compute the IGMP checksum
# XXX the important line is here XXX
del pkt[0][IGMPv3].chksum
# Write it to the pcap file.
wrpcap("final.pcap", pkt)
I have also simplified the imports.

Related

Unable to save changes inside GTPv2 pcap file using Scapy

Please help with a solution to the following issue. For simplicity I took a capture with several GTPv2 Create Session Request packets inside.
I have the following code:
import scapy.contrib.gtp_v2
from scapy.all import *
packets = rdpcap('zza15.pcap')
for packet1 in packets:
#Modify outer source IP
packet1[IP].src='1.1.1.1'
#Modify IPv4 address inside GTPv2, from PAA section
packet1['IE PAA'].ipv4='10.10.10.10'
#Modify IMSI
packet1['IE IMSI'].IMSI='1234567812345678'
# Changes are visible when running show()
packet1.show()
# Changes are NOT visible when running show2()
packet1.show2()
#New pcap created but NO changes saved
wrpcap('zza15_modif.pcap',packets)
So for the outer source IP address, the change was saved, but the other modifications(ie. PAA IP, IMSI) were not saved. Also, the changes done were visible with show(), but not with show2(). Please let me know what I'm doing wrong.

Use scapy with npcap on Windows

I am using scapy 2.4.5 with Python 3.9.5 on Windows 11. I have npcap version 1.55 install.
I have some Wireshark packet captures that I am trying to use scapy's sniff function on the file and filter out various packets.
However, when I use filter="udp" with sniff I get an exception about tcpdump not being available.
Below is the script I am currently trying to use.
from scapy.all import *
conf.use_pcap = True
pcap_file_path = r"C:\8OCT21_DDL_00001_20211008214804"
packets = sniff(offline=pcap_file_path,
count=10,
filter="udp")
packets.summary()
However I get this exception:
File "C:\Python39\lib\site-packages\scapy\sendrecv.py", line 1263, in sniff
sniffer._run(*args, **kwargs)
File "C:\Python39\lib\site-packages\scapy\sendrecv.py", line 1072, in _run
sniff_sockets.update((PcapReader(
File "C:\Python39\lib\site-packages\scapy\sendrecv.py", line 1074, in <genexpr>
tcpdump(fname,
File "C:\Python39\lib\site-packages\scapy\utils.py", line 2095, in tcpdump
raise Scapy_Exception(
scapy.error.Scapy_Exception: tcpdump is not available
Any idea on how to use scapy sniff on Windows with npcap instead of tcpdump?
The problem is not your filter, rather it's the "offline" option in sniff function. You can perform live sniff of packets, or use rdpcap() function to first load pcap in RAM, and then do what you want to do.
from scapy.all import rdpcap
from scapy.layers.inet import UDP
scapy_cap = rdpcap("responses.pcap")
for pck in PCAP:
if pck[UDP]:
print(pck.summary())
This is not a solution to why it throws tcpdump exception, but more of a workaround to get something out of your pcap.
Keep in mind that large pcap files will eat RAM like nothing else if you try to load them with rdpcap().

How to extract the payload of a packet using Pyshark

I am trying to read the payload of all packets in a .pcap file using Pyshark. I am able to open and read the file, access the packets and their other information but I am not able to find the correct attribute/method to use to access the payload of a packet. Any suggestions ? Is there any other way to read packet payloads in .pcap files using python for windows 10 ?
(I tried using Scapy instead of Pyshark, but apparently there is some issue with running Scapy on Windows, it does not work on my system as well)
I found these lines in different code snippets of pyshark projects on the Internet and on StackOverflow. I tried them but none of them work :
import pyshark
cap = pyshark.FileCapture('file.pcap')
pkt = cap[1]
#for other information
print(pkt.tcp.flags_ack) #this works
print(pkt.tcp.flags_syn) #this works
print(pkt.tcp.flags_fin) #this works
#for payload
print(pkt.tcp.data) #does not work, AttributeError
print(pkt.tcp.payload) #does not work, AttributeError
print(pkt.data.data) #does not work, AttributeError
This code will print the value associated with the field name tcp.payload.
capture = pyshark.FileCapture(pcap_file, display_filter='tcp')
for packet in capture:
field_names = packet.tcp._all_fields
field_values = packet.tcp._all_fields.values()
for field_name in field_names:
for field_value in field_values:
if field_name == 'tcp.payload':
print(f'{field_name} -- {field_value}')
# outputs
tcp.payload -- \xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7\xc2\xb7AP\xc2\xb7\xc2\xb7\xc2\xb7
tcp.payload -- 0x00001e2c
tcp.payload -- 113977858
...
In order to use that API you have to pass appropriate parameter into constructor of 'FileCapture' class:
import pyshark
cap = pyshark.FileCapture('file.pcap', include_raw=True, use_json=True)
pkt = cap[1]
print(pkt.data.data) # Will work
'include_raw' is the key here, but 'use_json' is needed when when 'include_raw' is used.
dir cap[].
This one will give you all accessible attributes related to your capture., look there if there is the payload option.

python3 send image via pipe / udp, PIL errors, etc

I'm having a difficult time figuring out how to send and receive an image (and display it, not save it) via UDP socket or named pipe (fifo) on linux.
With UDP sockets the problem I have is the file size exceeds the max buffer size. Conceptually I could iterate over a bytearray of the image in buffer-size chunks, but I'm not sure how to implement this, or how to reconstruct the image on the other side.
With named pipes, below is my code.
p1.py:
fifo_name = "fifoTest"
def Test():
img = cv2.imread("Lenna.png")
data = bytearray(img)
try:
os.mkfifo(fifo_name)
print("made fifo")
except FileExistsError:
print("fifo exists!")
with open(fifo_name, "wb", os.O_NONBLOCK) as f:
f.write(data)
f.close()
print("done!")
Some issues with p1 is that I can't seem to figure out when the writing to the pipe has finished, and often time no matter what happens on the other pipe this gives a BrokenPipeError
p2.py:
import os
import io
from PIL import Image
import cv2
pipe = os.open("fifoTest", os.O_RDONLY, os.O_NONBLOCK)
# img is 117966bytes as given by shell command wc -c < Lenna.png
imgBytes = os.read(pipe, 117966)
#img = Image.open(io.BytesIO(imgBytes))
print(imgBytes)
print(len(imgBytes))
#cv2.imshow("img", img)
input("there?")
With p2 and the commented lines, I have no problems. After input captures my keypress, I get no errors, but as mentioned about p1 errors with broken pipe. When img = Image.open(io.BytesIO(imgBytes)) is uncommented, I get
img = Image.open(io.BytesIO(imgBytes))
File "/usr/local/lib/python3.5/dist-packages/PIL/Image.py", line 2585, in open
% (filename if filename else fp))
OSError: cannot identify image file <_io.BytesIO object at 0x7f21b84b0a98>
I feel like this shouldnt be a hard problem, this is a really basic operation. I need this to happen at about 10fps (which is why I'm not looking at other options). I have also gotten resource temporarily unavailable error a few times, but I think the os.O_NONBLOCK flag fixed that.
Things that I have already looked at (some were helpful, but I need to display an image once its received):
Sending image over sockets (ONLY) in Python, image can not be open
Send image using socket programming Python
File Send by UDP Sockets
Send image using socket programming Python
PIL: Convert Bytearray to Image

Is it possible to extract wep iv fields with Scapy

Is it possible to write a Query with Scapy ? What i want is to extract all iv from all paquets of a pcap file. I do not want to filter packets, i also want to extract IV information and i need to extract ssid in the same time because there are multiple ap
Thanks
For the IV part you could do:
import binascii
from scapy.all import *
for pkt in PcapReader('myfile.cap'):
try:
if (pkt[1].iv):
print(binascii.hexlify(pkt[1].iv))
except:
pass

Resources