Dshell: The US Army’s Network Forensics Framework for Post-Incident PCAP Analysis
Hook
When the US Army Research Lab released their network forensics framework, they revealed a tool built not for real-time intrusion detection, but for the painstaking work of reconstructing what happened after an incident—analyzing captured PCAP files with specialized plugins rather than monitoring live traffic.
Context
Network forensics sits at the intersection of incident response and evidence collection. When a security breach occurs, teams capture network traffic in PCAP files and face a daunting question: what actually happened? Traditional packet analysis tools like Wireshark excel at interactive exploration, but they don’t scale well for programmatic analysis across thousands of packets. Network security monitors like Zeek focus on real-time detection, not retrospective investigation.
Dshell emerged from the US Army Research Lab to fill this gap. The framework treats network forensics as a batch processing problem where you chain together specialized decoders to extract specific protocol behaviors from captured traffic. Rather than alerting on threats as they happen, Dshell reconstructs application-layer conversations from raw packets, handles stream reassembly for both IPv4 and IPv6, and provides a plugin architecture that lets analysts write custom Python code to extract exactly the data they need. It’s the difference between watching live security camera feeds versus carefully reviewing footage after an incident to piece together a timeline.
Technical Insight
Dshell’s architecture centers on a plugin system where each decoder acts as a specialized protocol analyzer. The framework reads PCAP files through pcapy-ng, parses packets with pypacker, and routes them through a chain of decoders that can be combined using the + operator. This chainability is Dshell’s distinguishing feature—you can run decode -p dns+http to simultaneously analyze DNS queries and HTTP requests in the same traffic, correlating behaviors across protocols without writing integration code.
The stream reassembly engine deserves particular attention. Network traffic arrives as fragmented packets that need reconstruction before application-layer analysis makes sense. Dshell handles TCP stream reassembly automatically, tracking connection state and reordering packets so that plugins receive complete, sequential data. This is critical for protocols like HTTP or TLS where headers span multiple packets. The framework maintains separate reassembly contexts for IPv4 and IPv6, properly handling the different fragmentation semantics of each protocol.
Here’s what a basic usage pattern looks like from the documentation:
# List all available decoders
decode -l
# Run DNS analysis on a capture file
decode -p dns ~/pcap/dns.cap
# Chain DNS and HTTP decoders together
decode -p dns+http ~/pcap/mixed-traffic.pcap
# Run live on an interface (requires privileges)
decode -p dns -i eth0
The output from the DNS decoder shows the framework’s approach to presentation:
[DNS] 2005-03-30 03:49:18 192.168.170.8:32795 -- 192.168.170.20:53 ** ID: 30144, A? www.netbsd.org., A: 204.152.190.12 (ttl 82159s) **
[DNS] 2005-03-30 03:49:35 192.168.170.8:32795 -- 192.168.170.20:53 ** ID: 61652, AAAA? www.netbsd.org., AAAA: 2001:6f8:4:7:2e0:81ff:fe52:9a6b (ttl 86400s) **
Each line provides timestamp precision, bidirectional connection details, and protocol-specific fields extracted from the reassembled stream. The framework handles multiple output formats beyond stdout, including a built-in elasticsearch handler for integrating with ELK stacks.
For large captures, Dshell supports parallel processing that divides the workload across multiple Python processes. This addresses processing bottlenecks by spawning separate interpreters rather than using threads, allowing the framework to leverage multiple CPU cores for faster analysis of large PCAP files.
Plugin development follows a straightforward pattern. Each decoder inherits from base classes that provide packet access and connection tracking. The Dshell Developer Guide (included as a PDF) documents the core classes and data flow, showing how to register handlers for specific packet types and access reassembled stream data. Plugins can define custom command-line arguments, output formats, and filtering logic. The external plugin pack system allows organizations to maintain separate repositories of proprietary decoders without modifying the core Dshell installation—important for environments where custom protocol analysis needs to remain internal.
The framework integrates optional geoIP lookups through MaxMind’s GeoLite2 databases, mapping IP addresses to country codes and ASN information. This requires manual database file placement in the dshell/data/GeoIP/ directory. Similarly, MAC address OUI lookups need the IEEE oui.txt file manually placed in the data directory. These manual steps reflect a deployment model that assumes controlled installation environments rather than automated dependency management.
Gotcha
Dshell’s Linux-only requirement immediately eliminates Windows and macOS environments, despite Python’s cross-platform nature. The dependency on specific packet capture libraries ties it to Linux networking stacks, and there’s no clear path to porting it without significant rework. For teams running mixed operating systems or analysts on MacBooks, this is a non-starter.
The documentation strategy reflects an institutional approach to software distribution. Both the User Guide and Developer Guide ship as PDFs rather than as markdown files or modern documentation sites like Read the Docs. This makes searching harder, prevents community contributions to docs via pull requests, and means you’re downloading and opening separate files rather than browsing integrated help. The lack of inline code documentation or Sphinx-generated API references means understanding plugin development requires reading through PDF examples rather than exploring interactive docs.
Manual GeoIP database setup adds friction that modern dependency management could eliminate. You need to visit MaxMind’s website, download three separate .mmdb files (GeoLite2-ASN.mmdb, GeoLite2-City.mmdb, GeoLite2-Country.mmdb), and place them in the correct site-packages subdirectory. The oui.txt file for MAC address lookups requires similar manual intervention. Compare this to tools that bundle databases or auto-download them on first run, and Dshell appears designed for curated deployment rather than quick experimentation. The elasticsearch output requires installing the Python client separately, and the TLS plugin’s JA3 fingerprinting functionality needs pyJA3 manually added—another indication that Dshell assumes managed installation rather than self-service setup.
Verdict
Use Dshell if you’re conducting network forensics investigations where you need programmable, deep protocol analysis of PCAP files with custom decoder logic. The chainable plugin architecture shines when you’re correlating behaviors across multiple protocols, and the stream reassembly handles the messy work of reconstructing application-layer conversations from fragmented packets. It’s ideal for security teams analyzing malware traffic, incident responders building timelines from packet captures, or researchers developing custom protocol decoders. The parallel processing makes it viable for large capture files where single-threaded tools struggle. Skip Dshell if you need cross-platform support, real-time intrusion detection (use Suricata or Zeek), or interactive packet exploration (use Wireshark). Avoid it for Windows-centric workflows, quick ad-hoc analysis where installation overhead matters, or environments where PDF documentation is a dealbreaker. If you want batteries-included setup without manual GeoIP configuration, look elsewhere. The framework makes sense for dedicated forensics workstations in security operations centers, but it’s overkill for developers who occasionally need to inspect HTTP traffic during debugging.