____
| _ \ ___ __ _ _ __ _ __ ___ _ __
| |_) |/ __/ _` | '_ \| '_ \ / _ \ '__|
| __/| (_| (_| | |_) | |_) | __/ |
|_| \___\__,_| .__/| .__/ \___|_|
|_| |_|
PCAP triage for IT + OT/ICS, fast enough for the plant floor
Pcapper is a modular PCAP/PCAPNG analysis CLI for fast triage and deep-dive protocol investigations across enterprise IT and ICS/OT traffic.
OT/ICS READY — plant-floor triage in minutes, not hours.
Built for blue teams, DFIR responders, and OT defenders who need fast answers with evidence-rich outputs.
Install and run in under a minute:
pip install -r requirements.txtthenpython -m pcapper capture.pcap --threats --ips --timeline -ip 10.0.0.5
A PCAP tool is only useful if what it prints is true. Every analyzer in pcapper now holds to four rules, each one pinned by a regression test on a synthetic capture:
| Rule | What it means in the report |
|---|---|
| Roles come from the service port, not packet direction | A server's replies never make it a "client"; a client's ephemeral port is never a "top port". A flow from ephemeral 389 to 443 is not LDAP. |
| Windows are per protocol | A one-minute Kerberos exchange in an eight-hour capture reports a one-minute window, and every rate derived from it is right. |
| Padding is not payload | Segment lengths come from the IP/TCP headers, so a padded pure ACK is zero bytes of data, not six NULs in your Telnet transcript or a phantom retransmission. |
| Same capture, same report | Every sort has a total order. Two analysts running the same command get byte-identical output, whatever Python's hash seed did that day. |
And nothing internal leaves the box: reputation lookups (-vt, --ip-geo) only ever see public hostnames and routable addresses, only when you ask, and a config file planted in the evidence directory is never loaded.
| You Need | Pcapper Delivers |
|---|---|
| Fast first-pass triage | One-pass summaries across hosts, services, protocols, and threats |
| Forensic depth when needed | Deterministic checks, pivots, timelines, and risk matrices |
| OT + IT in one workflow | Industrial protocol decoding plus enterprise threat-hunting views |
| Output that can be actioned | Analyst verdicts and evidence lines built for investigations |
- SOC triage for suspicious captures with immediate threat signal extraction.
- IR/DFIR workflows where explainability and deterministic evidence matter.
- OT/ICS incident response for control-plane visibility and safety-oriented context.
- Purple-team and lab validation with ATT&CK mapping and IDS corroboration.
- Analyst-grade reporting: verdict, confidence, deterministic checks, risk matrix, pivots, and false-positive context.
- MITRE ATT&CK mapping: enterprise + ICS TTP alignment with technique heat and host-centric attack paths.
- Suricata integration: local IDS execution with structured metadata, event coverage, and pivots.
- Protocol depth: broad IT plus OT/ICS protocol coverage for mixed-network environments.
- Case-friendly exports: JSON/CSV/SQLite plus case metadata and provenance artifacts.
# 1) Install
pip install -r requirements.txt
# 2) Fast first-pass triage
python -m pcapper capture.pcap --threats --ips --timeline -ip 10.0.0.5
# 3) Deep-dive with ATT&CK + IDS corroboration
python -m pcapper capture.pcap --mitre --suricata --services --protocols
# 4) Export case-ready artifacts
python -m pcapper capture.pcap --json out/results.json --sqlite out/results.db --case-dir case-001# 1) Fast triage (best first command)
python -m pcapper capture.pcap --threats --ips --health
# 2) Host-centric hunt timeline
python -m pcapper capture.pcap --timeline -ip 10.0.0.5 --protocols --services
# 3) ATT&CK + IDS corroboration
python -m pcapper capture.pcap --mitre --suricata
# 4) Exfiltration, file transfer, and messaging/email artifact hunt
python -m pcapper capture.pcap --exfil --files --ftp --http --aim --email
# 5) OT/ICS deep-dive
python -m pcapper capture.pcap --modbus --dnp3 --iec104 --s7 --ot-commands --safetyflowchart LR
A[PCAP / PCAPNG Input] --> B[Packet Decode + Stream Reassembly]
B --> C[IT + OT/ICS Protocol Analyzers]
C --> D[Detections + Correlation]
D --> E[Analyst Verdict + Deterministic Checks]
E --> F[Reports + Exports]
C --> C1[Enterprise: DNS/HTTP/TLS/SMB/LDAP/Kerberos]
C --> C2[Industrial: Modbus/DNP3/IEC104/S7/CIP/Profinet]
D --> D1[MITRE Mapping]
D --> D2[Suricata Corroboration]
F --> F1[CLI]
F --> F2[JSON/CSV/SQLite]
F --> F3[Case Metadata]
| If You Want To... | Start With |
|---|---|
| Get immediate risk triage | --threats --ips --health |
| Hunt C2 or beaconing behavior | --beacon --dns --tls --quic |
| Map findings to ATT&CK | --mitre |
| Corroborate with IDS alerts | --suricata |
| Investigate data theft and transferred artifacts | --exfil --files --ftp --http --aim --email |
| Investigate identity abuse | --kerberos --ldap --ntlm --domain --creds |
| Track lateral movement | --hostnames --services --protocols --tcp --timeline -ip <host> |
| Investigate phone calls (VoIP) | --voip (add --voip-out DIR to recover call audio) |
| Run OT/ICS-specific triage | --modbus --dnp3 --iec104 --s7 --ot-commands --safety |
| Build IR exports and evidence packs | --json --csv --sqlite --case-dir |
ANALYST VERDICT
LIKELY - MULTIPLE CORROBORATING RISK INDICATORS DETECTED (confidence: MEDIUM)
DETERMINISTIC CHECKS
[!] Indicator quality gate: 3
- 203.0.113.44 quality=4 AbuseIPDB score=85 reports=12
[!] Boundary cross-zone contact: 2
- 10.0.0.10->203.0.113.44 TCP packets=600
[!] Intent heuristics: 2
- 10.0.0.10->203.0.113.44 admin ports observed 445,3389
RISK MATRIX
Category Risk Confidence Evidence
Indicator Quality High High 3
Boundary Exposure Medium Medium 2
Critical Asset Contact High High 1
TOP HUNT PIVOTS
- flow=10.0.0.10->203.0.113.44 proto=TCP packets=600 bytes=2.9 MB
reasons=Lateral movement posture score; Cross-zone outbound contact
The goal is actionable signal, not noisy packet dumps.
| Traditional PCAP Workflow | With Pcapper |
|---|---|
| Manually pivot protocol by protocol | Single command gives cross-protocol triage |
| Raw packet dumps with limited context | Deterministic checks + verdict + confidence |
| Ad-hoc analyst notes for evidence | Built-in pivots and evidence-rich summaries |
| Separate OT and IT tooling chains | Unified OT/ICS + enterprise workflow |
| Time-consuming report assembly | Case-ready exports (JSON/CSV/SQLite + metadata) |
- SOC analysts triaging suspicious captures under time pressure.
- Incident responders and DFIR teams building evidence-driven narratives.
- OT/ICS defenders investigating control-network anomalies safely.
- Purple teams validating detections and ATT&CK coverage.
- Security engineering teams building repeatable PCAP triage runbooks.
| Focus | What You Get |
|---|---|
| Speed | First-pass answers in minutes, not hours |
| Depth | Protocol-aware summaries, artifacts, and anomalies |
| OT/ICS | Control-plane context and safety-aware detections |
Capture -> Decoders -> Sessions -> Detections -> Reports
.pcap 300+ RDP/SSH Beaconing CLI/JSON/SQLite
Promotional highlights:
- Remote-access session visibility (RDP/SSH/WinRM/VNC/TeamViewer/Telnet) with endpoints, timing, and data volume.
- Phone-over-IP forensics (
--voip): SIP/SDP, Skinny, MGCP, MEGACO, IAX2 and H.323 signalling; RTP/RTCP/SRTP and T.38 fax media; DTMF keypad digits; recovered credentials; and G.711 call audio to WAV. - OT-aware findings that call out control actions, safety signals, and protocol-specific risks.
- Evidence-first reporting that surfaces context, not just counts.
v2.5.0 is the third pass of the same review, aimed at the roll-ups, the beacon detector and the compromise assessment.
- 📡 Reconnecting beacons are scored again. Since 2.0.0 the flow key dropped the client port before the per-connection key was built, so an HTTP C2 that opens a fresh connection per check-in collapsed into one event and never reached the scorer. Heartbeats inside a single persistent socket (reverse shells, websocket C2) are now scored too, from the client's request cadence.
- 🏭 An HMI polling its PLCs is no longer the most likely compromised host. The OT-baseline branch never fired (it read a port field that is empty for TCP), info-level context weighed like evidence, and the threat engine's own "baseline polling" downgrade came back as a warning, an incident and three Command and Control techniques in
--mitre. Baseline periodicity is now context everywhere. - 🧾 Roll-ups carry every section. A merge check over every
merge_*function found the--hostdetails,--dhcp,--cipand--compromisedroll-ups dropping whole sections, and five roll-ups reporting the sum of durations instead of the window. - 📦 Truncated downloads say so (
TRUNCATED: 1552 of 5000 declared bytes), sizes under a megabyte print in KB and bytes instead of0.00 MB, and numbers in a detection's own prose (score 0.98,interval 90.00s) are no longer domain IOCs that grouped unrelated hosts into phantom campaigns.
v2.4.0 is the "wrong rather than failing" release. Every one of the 120-plus analyzers was read line by line in a two-day production-readiness review, and the pattern that kept turning up was a report that was confidently wrong: a server counted as its own busiest client, a window that spanned the whole capture, a padded frame read as protocol bytes, a heuristic that fired on healthy traffic. The suite grew from 255 to 572 tests, each new one built on a synthetic capture that reproduced the defect.
- 🎭 Roles are right everywhere. UDP, TCP, SNMP, LDAP, Kerberos, NTLM, QUIC, DoT/DoQ, HTTP/2, WinRM, RDP, WMI, PowerShell, Telnet, VNC, TeamViewer, VPN, AIM, syslog, BGP, Modbus, DNP3, safety-system ports, IEC 101/103 (from the FT1.2 PRM bit) and OPC Classic (from the DCE/RPC PDU type) all had the sender as "client". The top-clients table on a normal capture used to list the directory server and the KDC.
- 🎫 Kerberos AS-REP roasting is evidence-based. It used to fire on "five AS-REPs and no pre-auth error", which every healthy domain logon satisfies. It now requires an AS-REP answering an AS-REQ with no pre-authentication data, names the roastable accounts, and points at
hashcat -m 18200. Principal names and realms are read from the ASN.1 — the old SPN regexes only ever matched captures of tool output. - 📬
--ftpno longer reports your mail. AnyNNN textline orUSER/PASSon any port was FTP, so every SMTP and POP3 session appeared in the FTP report with its credentials. A flow off the control ports must now be confirmed by an FTP-specific command or reply. - 📈 Brute force and UDP flood are rates, not totals: twenty SMB sessions over a working day and a resolver's daily 5,000 datagrams are no longer attacks.
- ⏱️ Per-protocol windows in 25 analyzers, and padding-aware segment lengths in Telnet (one keystroke per padded segment), the IT→OT pivot check, the beacon scorer, retransmission counting and the carver.
- 🔒 Nothing internal leaves the box. VirusTotal/OTX/AbuseIPDB passes used to send
fileserver.corp,printer.local, reverse-lookup zones and RFC 1918 addresses. Only public names go out, percent-encoded, under a time budget. Apcapper.tomlin the evidence directory is no longer loaded, a non-capture with a.pcapextension is rejected instead of read as empty,--decodedecompression is bounded, and recovered secrets are owner-only from the moment the file exists. - 🧩 One packet loop, one home for shared helpers. All 81 analyzers with a packet loop use
iter_packets(); the 24 module-local copies of utils helpers are gone and a ratchet test keeps them gone; memoized results are shared rather than deep-copied.
v2.3.0 is the phone-over-IP release, plus the packaging fix that made the previous one installable.
- ☎️
--voip(alias--sip) — the whole call path, not one protocol. Signalling: SIP/SDP on any port over UDP/TCP/TLS, Cisco SCCP/Skinny, MGCP, MEGACO/H.248, IAX2 and H.323 (H.225 + RAS). Media: RTP, RTCP, SRTP and T.38 fax. Plus STUN/TURN/ICE, phone provisioning over TFTP/HTTP, and ENUM. A Cisco shop signals with Skinny, an Asterisk trunk uses IAX2, a video bridge still speaks H.323 — reading only SIP returns "no VoIP traffic" on a capture that is nothing but VoIP traffic. - 🔑 Credentials, keys and keypad digits recovered. SIP Digest emitted as ready
hashcat -m 11400lines, IAX2 MD5 challenge/response pairs, plaintext IAX2 passwords, TURN long-term credentials. Cleartext SRTP master keys froma=crypto ... inline:— if the signalling was not itself encrypted, every "encrypted" call in the capture is decryptable. DTMF digits from all four carriers they use (RFC 4733 RTP, SIP INFO, SkinnyKeypadButton, MGCP observed events): routinely IVR PINs, calling-card numbers and card data. - 🎧 Call audio to WAV with
--voip-out DIR— G.711 decoded, written owner-only.audioopwas removed from the stdlib in 3.13, so the codecs are hand-written and reference-checked. - 📦 The wheel is installable again.
pcapper/reporting/became a subpackage in the reporting split, but[tool.setuptools] packagesstill listed onlypcapper, so the built wheel shipped zero renderers and a pip-installed pcapper died onimport pcapper.cli.twine checknever opens the archive, so CI stayed green. CI now installs the wheel into a clean venv, imports every module and runs the CLI. - 🔢 One version, not two.
pcapper/__init__.pyandpyproject.tomleach carried a literal and drifted — pip said 2.2.0 while the banner printed v2.1.0.pyproject.tomlnow derives the version from the package. - 🧱
reporting.pysplit: 29,989 lines in one module became 120, one per analyzer, verified byte-identical by source hashing and a 350-run CLI differential. - 🔁
--compromisedis reproducible. Its host sort was not a total order, so ties fell through to hash randomisation and the same capture produced two different reports.
v2.2.0 is the correctness-and-assurance release. No new analyzers — instead, the reassembly and decryption paths were audited, three silent failure modes were fixed, and the project gained the test suite and CI that would have caught them.
- 🧵 TCP sequence wraparound is handled. Both the carving and stream-following reassemblers sorted segments by raw 32-bit sequence number, so any stream whose initial sequence number sat near
2**32was mis-assembled once it wrapped — and carving then found nothing and reported nothing. Roughly 1 ISN in 43 on a 100 MB transfer, which is exactly the large-file-exfil case--carveexists for. - 🕳️ A carve taken across a gap no longer carries a confident SHA-256. Missing bytes used to be closed by concatenation, producing a spliced artifact with an authoritative-looking hash. Gaps are now zero-filled so offsets stay true to the stream, counted on every hit, and flagged in the rendered table, the note and the detection evidence.
- ⏱️
--decryptcannot hang forever. Every tshark call now has a timeout; a stalled stream is recorded and skipped instead of taking the run with it. Stream labelling was also rebuilt — it was inert (-c 1caps packets read, not matched) and mislabelled every IPv6 stream — and now costs one pass instead of two per stream, so--decryptwent from 2N+1 capture reads to N+1. - 🔐 A filename off the wire no longer reaches the filesystem as a path. Containment always held, but the probe itself was a problem: on Windows a UNC name in a capture turned an
exists()check into an outbound SMB connection to a host the adversary named. Names are now reduced to a bare local component first. - 🔎
--smbstopped dropping names with spaces —Domain Admins,Backup Operators,Program Filesand friends were being filtered out of client inventory previews. - ✅ 190 tests, and CI on Python 3.9 and 3.13, with golden rendered output pinned per analyzer. The lint gate's first act was to find a Python 3.12-only f-string that had been breaking the package on 3.9–3.11.
See CHANGELOG.md for the full detail.
v2.1.0 is the identity, asset-intelligence & OT-accuracy release. pcapper now reads the wire the way an analyst does — who is this host, what does it announce itself as, and is this actually notable — and it stops crying wolf on quiet industrial segments.
- 🪪 Full NetBIOS Browser (MS-BRWS) dissection — the browser Mailslot is decoded, not counted. Every announcement hands you a host's name, OS, server ROLES (Domain Controller / SQL / print / master browser), comment, and domain — passive asset inventory + OS fingerprinting with zero probing. Plus a scored verdict and browser attack detections: rogue master browser / forced-election takeover, PDC role conflict, NETLOGON user-enumeration — mapped to MITRE T1557 / T1046 / T1087 and rolled up in
--threatsand--mitre. - 🧠 Browser intelligence wired into 8 analyzers — hostname / OS / roles / domain / DC identity now light up
--hostdetails,--domain,--hostnames,--ips,--overview,--compromised,--threats, and--mitre.--domainmaps your Active Directory (domain + DC roster) with no Kerberos or LDAP traffic at all, and a compromised DC is escalated as a crown-jewel. - 🔬
--hostdetailsis now a full host-forensics dossier — one-ipgives you identity + roles, usernames, services, web requests, remote services out (with C2/remote-access flagging), remote access in (inbound RDP/SSH/VNC/WinRM/SMB with the connecting peer), authentication activity, TLS/JA3 fingerprints, SMB share access, email, peer geo/ASN/IOC intel, DNS, and downloaded files with hashes. - 🎯 Systematic OT/DCS false-positive kill — a benign Foxboro-DCS baseline (broadcast ARP + browser Mailslot, two DCs, no TCP) used to trip nearly every verdict engine.
--scan,--arp,--beacon,--protocols,--overview,--threats, and--mitreare now segment-hub-, broadcast/multicast-, and rate-aware — a gateway/DC ARPing its subnet is baseline, not an "Nmap sweep" or "CRITICAL C2 beacon."
Full detail in CHANGELOG.md.
$ python -m pcapper capture.pcap --netbios
Announced Hosts & Roles (Browser / MS-BRWS)
Host IP OS Domain Roles Comment
0001DC 10.217.34.1 Windows 7 / Server 2008 R2 (6.1) FOX Server, Domain Controller (PDC), DFS Root Domain Controller
0002DC 10.217.34.2 Windows 7 / Server 2008 R2 (6.1) FOX Server, SQL Server, Backup DC, DFS Root -
$ python -m pcapper capture.pcap --hostdetails -ip 10.217.34.1
Host Identity
Hostname : 0001DC
Inferred OS / Device : Windows 7 / Server 2008 R2 (6.1)
Announced Roles (Browser): Server, Domain Controller (PDC), Time Source, DFS Root, Terminal Server
Domain / Workgroup : FOX
v2.0.0 is the threat-hunt / incident-response release — pcapper graduated from "PCAP analysis" to a full threat-hunting, forensics, and IR/triage platform for IT and OT/ICS. Every analyzer was reviewed function-by-function so it now reads like an analyst's notebook: a verdict, the evidence, and the ATT&CK technique — never a raw packet dump.
- 🎯 IT→OT pivot detection — the #1 industrial intrusion pattern, caught automatically. A remote login (SSH/RDP/WinRM/…) that lands on a host which then issues an OT command to another device is flagged CRITICAL across
--threats,--overview,--compromised, and shown inline on the--timeline. - 🛰️ "Remote IN" timeline events — inbound remote-access sessions to your focus host, colored by risk (external = CRITICAL, internal = HIGH), so the foothold shows up before the control action it enabled.
- 🔐 Encrypted-traffic hunting — JA3/JA4 malware-fingerprint matching, Cobalt Strike default-cert IOCs, DoH-over-TLS via resolver SNI, and crackable Net-NTLM hash reconstruction (Hashcat-ready).
- 🏭 OT/ICS firepower — ~15 new/expanded industrial analyzers (Synchrophasor/C37.118, BSAP, Genisys, EtherCAT, Modicon UMAS, MELSEC, …), accurate ATT&CK-for-ICS mapping with evidence, and full OT output by default.
- 🧹 Big correctness + FP audit — revived several silently-dead detectors (PsExec admin-share/pipe, WMI persistence, Modicon CPU start/stop) and cut a swath of false positives, all validated against ground-truth captures.
- ⚡ Faster & leaner — sub-analyzer memoization (~13%+ faster on OT captures, byte-identical output) and ~2,000 lines of de-duplication.
See the full breakdown in CHANGELOG.md.
$ python -m pcapper attack.pcap -ip 10.0.0.10 --timeline
Activity Timeline
Time | Category | Summary
2023-11-14T22:13:20.200000Z | Remote IN | [CRITICAL] Inbound SSH remote access (external/public source)
| | 45.137.21.9 -> 10.0.0.10:22 (SSH) established
2023-11-14T22:13:25.300000Z | Modbus | [OT Control] Modbus Write Single Register
| | 10.0.0.10 -> 10.0.0.20:502 unit 1 Write Single Register
$ python -m pcapper attack.pcap --threats
Most Likely Scenarios
Sev Source Detection Top Source Top Destination
CRIT Pivot IT->OT pivot: remote access then OT command 45.137.21.9(1) 10.0.0.20(1)
Host 10.0.0.10 accepted inbound SSH remote access from 45.137.21.9 (external/public
source) and subsequently issued a Modbus command to 10.0.0.20. [ATT&CK T0859 / T0855]
Headline changes in this release:
- Beacon detection works for reconnecting and persistent C2 again, and routine OT polling is context rather than compromise evidence in
--compromisedand--mitre. - Every roll-up carries every section, checked mechanically over every merge function; truncated downloads and sub-megabyte sizes are labelled honestly.
- Every analyzer reviewed for reports that were wrong rather than failing — client/server roles, per-protocol windows, padding-aware lengths and total-order sorts across the board, each pinned by a test. 584 tests, CI on Python 3.9 and 3.13.
- Detection heuristics that fire on attacks, not on Tuesday — evidence-based AS-REP roasting, FTP that ignores SMTP, brute force and UDP floods as rates, domain exposure limited to domain-control protocols, syslog that ignores HTML.
- Nothing internal leaves the box — reputation lookups restricted to public names, percent-encoded and time-budgeted; no config from the evidence directory; bounded decompression; owner-only secrets.
Carried forward from v2.3.0:
--voip/--sip— phone-over-IP forensics across SIP/SDP, SCCP, MGCP, MEGACO, IAX2, H.323, RTP/RTCP/SRTP, T.38 fax, STUN/TURN, provisioning and ENUM; recovered credentials, SRTP keys and DTMF digits; G.711 call audio to WAV via--voip-out.- The distribution actually installs — the wheel was shipping no
reportingpackage at all; CI now installs and runs the built artifact rather than only checking its metadata. reporting.pysplit into 120 per-analyzer modules, with no behaviour change.
Carried forward from v2.2.0:
- Three silent failure modes in reassembly and decryption fixed — sequence wraparound, gaps published with an authoritative hash, and an unbounded tshark call. See CHANGELOG.md.
- A test suite and CI — 190 tests with golden rendered output, run on Python 3.9 and 3.13.
- Wire-derived filenames are neutralised before touching the filesystem, and a disclosure route exists in SECURITY.md.
Carried forward from v2.1.0:
- Full NetBIOS Browser (MS-BRWS) protocol dissection in
--netbios— announced host names, OS, server roles (DC/SQL/print/master browser), comments and domain, a scored verdict, and browser attack detections (rogue master browser, election storm, PDC conflict, NETLOGON enumeration) mapped to MITRE T1557 / T1046 / T1087. - Browser-derived host intelligence propagated to 8 analyzers (
--hostdetails,--domain,--hostnames,--ips,--overview,--compromised,--threats,--mitre) — passive AD/DC discovery with no Kerberos/LDAP required. --hostdetailsexpanded into a full host dossier — inbound + outbound remote access (with C2/remote-access flagging), authentication activity, TLS/JA3, SMB share access, email, and peer geo/ASN/IOC intelligence, alongside the existing identity/services/web/DNS/files.- Systematic OT/DCS false-positive elimination — a shared unicast/broadcast gate plus segment-hub-role and rate awareness across
--scan,--arp,--beacon,--protocols,--overview,--threats, and--mitreso a gateway/DC's routine ARP and Mailslot broadcast reads as baseline, not recon or C2. --scanand--overviewnow always render at full depth (no-vneeded, no truncation footer);--overview"Notable Flows" is notability-aware instead of top-by-volume.
Previous milestone (v2.0.x): IT→OT pivot detection and "Remote IN" timeline events, CIP/EtherNet-IP timeline entries, DoH-over-SNI detection, per-analyzer Analyst Verdict + ATT&CK mapping, revived dead detectors, and sub-analyzer memoization performance work.
Industrial networks are first-class here: deep protocol coverage, safety-conscious detections, and context that reads like an OT incident timeline instead of a raw packet dump.
Signal > noise for substations, plants, and mixed IT/OT environments.
What you get:
- Dedicated OT protocol analyzers (IEC-104, DNP3, S7, Profinet, EtherNet/IP, MMS, and more).
- OT-aware timing/jitter insights for control traffic.
- Analyst-friendly outputs tuned for plant floors, substations, and mixed IT/OT environments.
- Control-command visibility for safety/availability impacts (writes, downloads, starts/stops).
- Control-loop validation on Modbus/DNP3 value changes (rate-of-change, oscillation, outliers).
- Safety PLC/SIS protocol detection (Triconex/TriStation heuristics).
- OT/ICS-centric threat and anomaly rollups with evidence lines for fast triage.
- Device fingerprinting across IT/OT/IoT traffic (vendor/model/OS/firmware/software) for asset-aware triage.
- Remote-access session visibility (RDP/SSH/WinRM/VNC/TeamViewer/Telnet) with endpoints, timing, and data volume.
- Phone-over-IP forensics (
--voip): SIP/SDP, Skinny, MGCP, MEGACO, IAX2 and H.323 signalling; RTP/RTCP/SRTP and T.38 fax media; DTMF keypad digits; recovered credentials; and G.711 call audio to WAV. - Deeper OT protocol decoding for DNP3, IEC 61850 GOOSE/SV, Modbus, BACnet, OPC UA, CoAP, MQTT, and CIP/ENIP.
- Routing protocol forensics (OSPF/BGP/IS-IS/PIM) with route-change, auth, and control-plane health visibility.
pip install -r requirements.txtFor development (tests and lint):
pip install -e .[dev]
ruff check pcapper tests
pytest -q # 584 tests; add -m "not slow" to skip the subprocess onesThe suite runs on synthetic captures generated by tests/make_fixtures.py; no real traffic is committed, and the repository's .gitignore is an allow-list so carved files, decrypted streams, key logs and case exports cannot be added by accident.
--bpffiltering depends on libpcap. On Windows, install Npcap and ensure Scapy can access it. If BPF is unavailable, Pcapper will fall back to non-BPF packet parsing.- Colored output is enabled only for TTYs. Use
--no-coloror setNO_COLOR=1to disable ANSI colors.
python -m pcapper <target> [options]target accepts one or more values:
- a single file (
capture.pcap) - a directory (
~/Downloads/pcaps/) - wildcard patterns (
~/Downloads/pcaps/Un*) - multiple explicit targets (for example shell-expanded wildcards)
Examples:
python -m pcapper ~/Downloads/pcaps/MIME11.pcap --ips
python -m pcapper ~/Downloads/pcaps/ --arp
python -m pcapper ~/Downloads/pcaps/ --dhcp --no-status
python -m pcapper ~/Downloads/pcaps/Un* --arp
python -m pcapper "~/Downloads/pcaps/Un*" -summarize --ips
python -m pcapper one.pcap two.pcapng ~/Downloads/pcaps/ -summarize --timeline -ip 10.182.207.28========================================================================
RDP ANALYSIS :: sample.pcap
========================================================================
Total Packets : 214,993
RDP Packets : 18,876
Total Bytes : 133.42 MB
Client -> Server : 21.07 MB
Server -> Client : 112.35 MB
Duration : 2h 13m 14.2s
Sessions : 14
TCP Sessions : 9
UDP Sessions : 5
Unique Clients : 3
Unique Servers : 3
------------------------------------------------------------------------
Top RDP Clients & Servers
Clients Servers
10.51.142.55(17481) 10.180.81.111(17481)
10.51.137.116(1560) 10.180.81.123(1560)
10.182.106.47(8) 10.180.81.139(8)
------------------------------------------------------------------------
RDP Sessions
Client Server Start End Duration Packets Size
10.51.142.55:51332 10.180.81.111:3389 2026-02-19T09:12:42Z 2026-02-19T11:25:54Z 2h 13m 12s 17481 104.2 MB
10.51.137.116:55190 10.180.81.123:3389 2026-02-19T12:01:04Z 2026-02-19T12:27:33Z 26m 29s 1560 12.7 MB
========================================================================
Secrets/credentials are displayed in reports by default.
Exports (JSON/CSV/SQLite) include full values by default.
Use -v/--verbose to include additional evidence lines in summaries (for example file artifacts, LDAP anomalies, and OT/ICS command details).
The per-feature reference — every analysis mode, its flags and a worked example — lives in docs/reference.md:
- Summarize behavior
- Decryption
- Stream Carving
- Obfuscation Heuristics
- Control-Loop Validation
- Safety PLC Detection
- Kill-Chain Timeline Tags
- LOLBAS Recognition
- Correlation
- Case Metadata
- Baselines
- Rules
- IOC Enrichment
- Configuration
- Logging
- Plugins
- CLI Flag Groups
- Phone Over IP (VoIP)
- Notes
See also CHANGELOG.md (current releases), CHANGELOG-archive.md (2.0.2 and earlier) and SECURITY.md.
MIT