DFIR Tooling - Packet Capturing
I wrote a lazy packet capture plugin yesterday. Let's dive in and take a look at how it works!
Last Update: DFIR Tooling - python-tim
A friend of mine asked me to do an "Intro to Wireshark" sort of writeup, but I don't know Wireshark all that well. Instead I wrote a quick and dirty packet capture plugin and drew up some diagrams to visualize how it all works. The Divert plugin (available here) is one I've been tinkering with on and off for a while now, so it came together really quickly. It leverages WinDivert (via pydivert), a dynamically reconfigurable filter driver for Windows.
NDIS Driver Stack
The NDIS driver stack is a beautifully ingenious design that provides Windows with its modular network stack. It's comprised of four different kinds of drivers:
- Miniport drivers have two main functions. They interface directly with hardware (NICs, USB drivers, etc.) and relay traffic to and from the rest of the driver stack.
- Filter drivers sit in the middle of the stack. They exist to allow modification and monitoring of traffic flowing between miniport drivers and protocol drivers.
- Protocol drivers provide an interface between the application layer and the rest of the stack. I think of them as an entry point/exit point for traffic flowing through the driver stack.
- Intermediate drivers are a bit more complex, and not really in the scope of this blog post. Imagine a miniport driver and a protocol driver had a baby.
The Windows kernel instantiates these drivers and stacks the driver instances together to form a coherent network stack. Conceptually, it looks a little something like this.
Where protocol bindings are an instance of a protocol driver, miniport adapters are an instance of a miniport driver, and filter modules are an instance of a filter driver. Windows supports any number of filter modules between a miniport adapter and a protocol driver.
Thanks to the beauty of the NDIS driver stack, all we need to do is insert a filter module somewhere inside of the NDIS stack if we want to capture packets. I chose WinDivert for my first pass because it's super easy to use and incredibly powerful. The Divert plugin looks a little something like this right now, at a high level.
Packets flowing through the NDIS driver stack are diverted by the WinDivert module and passed to the capture worker, which makes a copy of the packet, sticks it in the capture queue, and sends the packet back through the rest of the NDIS stack to its final destination. Packets that enter the capture queue are scooped up by the write worker and written to a file for later analysis. Right now it's one packet per file. Eventually I'll split that out into two files per packet, where one contains metadata about the packet and the other file contains the raw binary for that packet. The file names are the nanosecond Unix timestamp at which the packet was captured. Later on I'll go through and write an analyzer module to turn those disparate files into something a little more coherent, like a pcap file, for analysis in VR.
By default, the Divert plugin captures every single packet going to and from the endpoint. It can be configured to only capture specific packets using a Boolean filter language described in the WinDivert documentation.
Earlier this week I extended the FileSystem plugin to automagically capture MAC times and other filesystem metadata when performing a directory listing. Also, I decided that each plugin is responsible for tracking and managing its own state. That solves a problem I had a couple weeks back in a simple and convenient way.