Capturing and Editing Packets with PyDivert

Aidan Walz
3 min readJan 13, 2021

PyDivert is a python wrapper for a library called WinDivert that allows users to hook the Windows socket API (WinSock). Once hooked, the user has access to the packet send/receive buffer, and may filter or edit packets before sending them out. Below is a diagram of the packet receipt process, showing how packets are enqueued into the buffer at the socket layer.

Source: http://www.cs.cmu.edu/afs/cs/academic/class/15441-f01/www/assignments/P2/htmlproj2_split/node5.html
Figure 0 :: Packet receipt diagram

Installing PyDivert:

pip install pydivert

Here is the basic structure of a PyDivert program:

import pydivert// Use WinDivert packet buffer
with pydivert.WinDivert() as buffer:
// Iterate the buffer
for packet in buffer:
// Do something...
// Send packet
buffer.send(packet)

Our next step is to begin editing packets, this is made easy with the PyDivert API. Before editing packets it is important to know exactly what we are editing. If you are not familiar with the structure of packets, Figure 1 shows the basic structure of a packet header.

Figure 1 :: Packet header diagram

Following the header is something called a payload which is what we generally refer to as the ‘data’ stored in a packet. The PyDivert API allows us to edit many of these packet fields by referencing them. Some fields, such as the checksum and length may be calculated automatically and are not easily edited through the PyDivert API. Although if you wish to change these you may edit the raw bytes of the packet instead of using the PyDivert API.

Here is an example of changing the payload of a packet:

import pydivert// Use WinDivert packet buffer
with pydivert.WinDivert() as buffer:
// Iterate the buffer
for packet in buffer:
packet.payload = "Hello world!"
// Send packet
buffer.send(packet)

This program will change the payload of all packets in the buffer (every packet coming in or out of your computer) to the string “Hello world!”, or as bytes 0x48656c6c6f20776f726c6421. Suppose we do not want to change the payload of all packets, perhaps we simply want to change the payload of a single packet:

import pydivert// Use WinDivert packet buffer
with pydivert.WinDivert() as buffer:
// Iterate the buffer
for packet in buffer:
payload = packet.payload
if bytes("foo", "utf-8")in payload:
packet.payload = "bar"
buffer.send(packet)

Here we check the bytes of our payload to see if they contain the string “foo”, and if so that packet’s payload is changed to the string “bar”. As you can see, PyDivert gives us quite a bit of freedom when it comes to editing packets. We may also edit the source and destination IP addresses and ports to redirect packets or to spoof their origin. I encourage you to play around with the options that the PyDivert API provides and remind you that modifying network traffic on networks other than your own without permission is not legal and should not be done under any circumstances.

--

--