Use scapy with npcap on Windows - scapy

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().

Related

Unable to compute checksum for igmpv3 using scapy

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.

Scapy show packet content after sniffing it - UnicodeEncodeError

I want to sniff ProfiNet Connect Messages and print them to console every time i receive them. Herefore i used the Scapy sniff method. Every time a Connect-Frame is received the following error is displayed. The Connect-Message is in correct format and is visible in Wireshark. The sniff-method aborts every time such a frame is received. If i export the frame with wireshark and read the .pcap-file with scapy the frame is correctly displayed. Do you have any suggestions? I'm currently using Python 3.8.10 and scapy version 2.4.5rc1.dev205. Thanks!
UnicodeEncodeError: 'latin-1' codec can't encode character '\u0797' in position 595: ordinal not in range(256)
def update_connect_load(pkt):
pkt.show2()
def stopFilter(x):
return False
sniff(
filter=f"ether src {mac_address}",
store=0,
count=-1,
prn=update_connect_load,
iface=iface,
stop_filter=stopFilter,
)`
Tried encoding the paket in the prn-function, but that didn't work. Also tried parsing the packet with DceRpc() but that also didn't work.
Just update the Python Version to 3.9 and everything works!

Read a dtoverlay controlled device via Python3?

How to read a dtoverlay controlled device, i.e. sensor via pyhon3?
I can read the device via a simple cat, for example...
# cat /sys/bus/i2c/devices/1-0077/iio\:device0/in_temp_input
27130
So I know the basic setup and such is good, sensor is at address 0x77, it is a BME280 sensor, etc.
I can also read the sensor via the various python3 libraries for such sensors, say the python library from Adafruit.
But I want to use the dtoverlay method of sensor control, i.e. read, and read the sensor from python3. This seemed obvious and straight forward, but apparently not, tried the following code and got the following error.
#!/usr/bin/python3
#
#
import os
#
theSensor=os.open('/sys/bus/i2c/devices/1-0077/iio\:device0/in_temp_input', os.O_RDONLY)
os.lseek(theSensor, 0, os.SEEK_SET)
print(os.read(theSensor, 2))
theSensor.close()
And the error...
# python3 BME280-OverLay.py
Traceback (most recent call last):
File "/root/BME280-OverLay.py", line 17, in <module>
theSensor=os.open('/sys/bus/i2c/devices/1-0077/iio\:device0/in_temp_input', os.O_RDONLY)
FileNotFoundError: [Errno 2] No such file or directory: '/sys/bus/i2c/devices/1-0077/iio\\:device0/in_temp_input'
Is there some trick to reading this specific device path via python3? The simple cat works.
In your initial cat command, you noticed that there's a \ inside the URL. That's an escape character. It might be there because you used autocompletion with the Tab key ; in this case bash adds it automatically, even though in fact cat doesn't need it, but deals with it.
python doesn't (deal with it). You'll have to feed open() with the clear path syntax.
By the way you can use a plain open() call and the with syntax :
with open('/sys/bus/i2c/devices/1-0077/iio:device0/in_temp_input', 'r') as fd:
temp = fd.read()
print(temp)
This way, the file gets closed before the print() call.
PS: the fact that the file you are trying to read is on a virtual filesystem would have no impact.

LIBUSB_ERROR_BUSY [-6] Sending a basic packet with Python 3.9 using LibUSB1

I am developing some software in python 3.9 and I am at the point where I have a device connected to my USB port and would like to send a basic packet to test the interface before I proceed. I am using this example to try and get my interface to work. I am not bothered about speed or byte count. I would like to see any response on the interface (But on reflection Im wondering if usb speed could be the issue):
import usb1
import usb.util
import os
import sys
import libusb
import usb.core
from usb import util
import math
dev = usb.core.find(idVendor=0x11ac,idProduct=0x317d)
with usb1.USBContext() as context:
handle=context.openByVendorIDAndProductID(
0x11ac,
0x317d,)
handle.claimInterface(0)
handle.setInterface(0)
data = bytearray(b"\\xf0\\x0f"* (int(math.ceil(0xb5db91/4.0))))
handle.controlWrite(0x40, 0xb0, 0xb5A6, 0xdb91, b"")
handle.bulkWrite(2,data,timeout=5000)
`
https://github.com/vpelletier/python-libusb1/issues/21
I have had a look in various forums for several days and cannot seem to get an answer that works. Here is the trace: Its worth noting that from time to time, this py file does run without error but does nothing, and I see no traffic traveling to the USB interface.
Can someone please help me configure a working example of how to send a packet to the interface? I have tried various things like detaching the kernel, setting configuration, etc.
For 4 days I have struggled with libusb01 & 10, after discovering libusb1, I have changed my wrapper and got a lot more success
I also see a lot of examples in forums like this one, and I always get the same response. Also Im curious as to where it appears that 0x40 is the endpoint(out)
Traceback (most recent call last):
File "/home/jbgilbert/Desktop/Packets/Backend_replace.py", line 16, in <module>
handle.claimInterface(0)
File "/usr/lib/python3/dist-packages/usb1/__init__.py", line 1213, in claimInterface
libusb1.libusb_claim_interface(self.__handle, interface),
File "/usr/lib/python3/dist-packages/usb1/__init__.py", line 133, in mayRaiseUSBError
__raiseUSBError(value)
File "/usr/lib/python3/dist-packages/usb1/__init__.py", line 125, in raiseUSBError
raise __STATUS_TO_EXCEPTION_DICT.get(value, __USBError)(value)
usb1.USBErrorBusy: LIBUSB_ERROR_BUSY [-6]
My device is a laptop, using lsmod reveals all devices linked to that particular end point, in this case because if the presence of a webcam I was unable to write to an available end point. Despite disabling the driver I had no avail and had to try to code on a machine that had less onboard accessories that proved more successful

pcap file viewing library in python 3

I'm looking at trying to read pcap files from various CTF events.
Ideally, I would like something that can do the breakdown of information such as wireshark, but just being able to read the timestamp and return the packet as a bytestring of some kind would be welcome.
The problem is that there is little or no python 3 support with all the commonly cited libraries: dpkt, pylibpcap, pcapy, etc.
Does anyone know of a pcap library that works with python 3?
to my knowledge, there are at least 2 packages that seems to work with Python 3: pure-pcapfile and dpkt:
pure-pcapfile is easy to install in python 3 using pip. It's very easy to use but still limited to decoding Ethernet and IP data. The rest is left to you. But it works right out of the box.
dpkt doesn't work right out of the box and needs some manipulation before. They are porting it to Python 3 and plan to have a Python 2 and 3 compatible version for version 2.0. Unfortunately, it's not there yet. However, it is way more complete than pure-pcapfile and can decode many protocols. If your packet embeds several layers of protocols, it will decode them automatically for you. The only problem is that you need to make a few corrections here and there to make it work (as the time of writing this comment).
pure-pcapfile
the only one that I found working for Python 3 so far is pcapfile. You can find it at https://pypi.python.org/pypi/pypcapfile/ or install it by doing pip3 install pypcapfile.
There are just basic functionalities but it works very well for me and has been updated quite recently (at the time of writing this message):
from pcapfile import savefile
file = open('mypcapfile.pcp' , 'rb')
pcapfile = savefile.load_savefile(file,verbose=True)
If everything goes well, you should see something like this:
[+] attempting to load mypcapfile.pcap
[+] found valid header
[+] loaded 1234 packets
[+] finished loading savefile.
A few remarks now. I'm using Python 3.4.3. And doing import pcapfile will not import anything from it (I'm still a beginner with Python) but the only basic information and functions from the package. Next, you have to explicitly open your file in read binary mode by passing 'rb' as the mode in the open() function. In the documentation they don't say it explicitly.
The rest is like in the documentation:
packet = pcapfile.packets[12]
to access the packet number 12 (the 13th packet then, the first one being at 0). And you have basic functionalities like
packet.timestamp
to get a timestamp or
packet.raw()
to get raw data.
The documentation mentions functions to do packet decoding of some standard formats like Ethernet and IP.
dpkt
dpkt is not available for Python 3 so you need to do the following, assuming you have access to a command line. The code is available on https://github.com/kbandla/dpkt.git and you must download it before:
git clone https://github.com/kbandla/dpkt.git
cd dpkt
git checkout --track origin/migrate_py3
git pull
This 4 commands do the following:
clone (download) the code from its git repository on github
go into the newly created directory named dpkt
switch to the branch name migrate_py3 which contains the Python 3 code. As you can see from the name of this branch, it's still experimental. So far it works for me.
(just in case) download again the code
then copy the directory named dpkt in your project or wherever Python 3 can find it.
Later on, in Python 3 here is what you have to do to get started:
import dpkt
file = open('mypcapfile.pcap','rb')
will open your file. Don't forget the 'rb' binary mode in Python 3 (same thing as in pure-pcapfile).
pcap = dpkt.pcap.Reader(file)
will read and decode your file
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
print(eth)
will, for example, decode Ethernet packet and print them. Then read the documentation on how to use dpkt. If your packets contain IP or TCP layer, then dpkt.ethernet.Ethernet(buf) will decode them as well. Also note that in the for loop, we have access to the timestamps in ts.
You may want to iterate it in a less constrained form and doing as follows will help:
(ts,buf) = next(pcap)
eth = dpkt.ethernet.Ethernet(buf)
where the first line get the next tuple from the pcap file. If pcap is False then you read everything.

Resources