netforensicai 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. netforensicai-0.3.0/LICENSE +21 -0
  2. netforensicai-0.3.0/PKG-INFO +418 -0
  3. netforensicai-0.3.0/README.md +340 -0
  4. netforensicai-0.3.0/netforensicai/__init__.py +1 -0
  5. netforensicai-0.3.0/netforensicai/agents/__init__.py +27 -0
  6. netforensicai-0.3.0/netforensicai/agents/base.py +226 -0
  7. netforensicai-0.3.0/netforensicai/agents/coordinator.py +150 -0
  8. netforensicai-0.3.0/netforensicai/agents/roles.py +90 -0
  9. netforensicai-0.3.0/netforensicai/cli.py +2421 -0
  10. netforensicai-0.3.0/netforensicai/core/__init__.py +0 -0
  11. netforensicai-0.3.0/netforensicai/core/ai_assistant.py +534 -0
  12. netforensicai-0.3.0/netforensicai/core/attack.py +93 -0
  13. netforensicai-0.3.0/netforensicai/core/audit.py +157 -0
  14. netforensicai-0.3.0/netforensicai/core/capture.py +705 -0
  15. netforensicai-0.3.0/netforensicai/core/case.py +256 -0
  16. netforensicai-0.3.0/netforensicai/core/chat.py +560 -0
  17. netforensicai-0.3.0/netforensicai/core/config.py +179 -0
  18. netforensicai-0.3.0/netforensicai/core/correlation.py +275 -0
  19. netforensicai-0.3.0/netforensicai/core/ctf.py +398 -0
  20. netforensicai-0.3.0/netforensicai/core/detections.py +807 -0
  21. netforensicai-0.3.0/netforensicai/core/diagnostics.py +133 -0
  22. netforensicai-0.3.0/netforensicai/core/entities.py +122 -0
  23. netforensicai-0.3.0/netforensicai/core/event.py +152 -0
  24. netforensicai-0.3.0/netforensicai/core/evidence.py +220 -0
  25. netforensicai-0.3.0/netforensicai/core/export.py +167 -0
  26. netforensicai-0.3.0/netforensicai/core/finding.py +216 -0
  27. netforensicai-0.3.0/netforensicai/core/investigate.py +114 -0
  28. netforensicai-0.3.0/netforensicai/core/ioc.py +730 -0
  29. netforensicai-0.3.0/netforensicai/core/narrative.py +360 -0
  30. netforensicai-0.3.0/netforensicai/core/pipeline.py +115 -0
  31. netforensicai-0.3.0/netforensicai/core/report.py +653 -0
  32. netforensicai-0.3.0/netforensicai/core/search.py +350 -0
  33. netforensicai-0.3.0/netforensicai/core/store.py +901 -0
  34. netforensicai-0.3.0/netforensicai/core/streams.py +304 -0
  35. netforensicai-0.3.0/netforensicai/core/threat_intel.py +100 -0
  36. netforensicai-0.3.0/netforensicai/core/timeline.py +162 -0
  37. netforensicai-0.3.0/netforensicai/dashboard.py +41 -0
  38. netforensicai-0.3.0/netforensicai/integrations/__init__.py +9 -0
  39. netforensicai-0.3.0/netforensicai/integrations/wireshark.py +576 -0
  40. netforensicai-0.3.0/netforensicai/intel/__init__.py +0 -0
  41. netforensicai-0.3.0/netforensicai/intel/virustotal.py +101 -0
  42. netforensicai-0.3.0/netforensicai/parsers/__init__.py +38 -0
  43. netforensicai-0.3.0/netforensicai/parsers/base.py +70 -0
  44. netforensicai-0.3.0/netforensicai/parsers/credentials.py +254 -0
  45. netforensicai-0.3.0/netforensicai/parsers/evtx.py +243 -0
  46. netforensicai-0.3.0/netforensicai/parsers/generic.py +189 -0
  47. netforensicai-0.3.0/netforensicai/parsers/pcap.py +866 -0
  48. netforensicai-0.3.0/netforensicai/parsers/pcap_engine.py +204 -0
  49. netforensicai-0.3.0/netforensicai/parsers/pcap_tshark.py +804 -0
  50. netforensicai-0.3.0/netforensicai/parsers/suricata.py +232 -0
  51. netforensicai-0.3.0/netforensicai/web/__init__.py +0 -0
  52. netforensicai-0.3.0/netforensicai/web/app.py +1220 -0
  53. netforensicai-0.3.0/netforensicai/web/static/app.js +3627 -0
  54. netforensicai-0.3.0/netforensicai/web/static/index.html +63 -0
  55. netforensicai-0.3.0/netforensicai/web/static/style.css +751 -0
  56. netforensicai-0.3.0/netforensicai.egg-info/PKG-INFO +418 -0
  57. netforensicai-0.3.0/netforensicai.egg-info/SOURCES.txt +111 -0
  58. netforensicai-0.3.0/netforensicai.egg-info/dependency_links.txt +1 -0
  59. netforensicai-0.3.0/netforensicai.egg-info/entry_points.txt +2 -0
  60. netforensicai-0.3.0/netforensicai.egg-info/requires.txt +41 -0
  61. netforensicai-0.3.0/netforensicai.egg-info/top_level.txt +1 -0
  62. netforensicai-0.3.0/pyproject.toml +135 -0
  63. netforensicai-0.3.0/setup.cfg +4 -0
  64. netforensicai-0.3.0/tests/test_agent_coordinator.py +139 -0
  65. netforensicai-0.3.0/tests/test_agent_roles.py +132 -0
  66. netforensicai-0.3.0/tests/test_agents.py +145 -0
  67. netforensicai-0.3.0/tests/test_ai_assistant.py +507 -0
  68. netforensicai-0.3.0/tests/test_ai_ssrf.py +48 -0
  69. netforensicai-0.3.0/tests/test_attack.py +136 -0
  70. netforensicai-0.3.0/tests/test_audit.py +243 -0
  71. netforensicai-0.3.0/tests/test_bulk_insert.py +140 -0
  72. netforensicai-0.3.0/tests/test_capture.py +219 -0
  73. netforensicai-0.3.0/tests/test_case_delete.py +225 -0
  74. netforensicai-0.3.0/tests/test_cases.py +144 -0
  75. netforensicai-0.3.0/tests/test_chat.py +589 -0
  76. netforensicai-0.3.0/tests/test_cli.py +584 -0
  77. netforensicai-0.3.0/tests/test_cli_doctor.py +61 -0
  78. netforensicai-0.3.0/tests/test_config.py +137 -0
  79. netforensicai-0.3.0/tests/test_correlation.py +288 -0
  80. netforensicai-0.3.0/tests/test_credentials.py +226 -0
  81. netforensicai-0.3.0/tests/test_ctf.py +331 -0
  82. netforensicai-0.3.0/tests/test_detections.py +387 -0
  83. netforensicai-0.3.0/tests/test_entities.py +165 -0
  84. netforensicai-0.3.0/tests/test_evidence.py +158 -0
  85. netforensicai-0.3.0/tests/test_evtx.py +195 -0
  86. netforensicai-0.3.0/tests/test_export.py +200 -0
  87. netforensicai-0.3.0/tests/test_false_positives.py +146 -0
  88. netforensicai-0.3.0/tests/test_findings.py +190 -0
  89. netforensicai-0.3.0/tests/test_hashing.py +37 -0
  90. netforensicai-0.3.0/tests/test_investigate.py +133 -0
  91. netforensicai-0.3.0/tests/test_ioc.py +415 -0
  92. netforensicai-0.3.0/tests/test_narrative.py +272 -0
  93. netforensicai-0.3.0/tests/test_normalization.py +129 -0
  94. netforensicai-0.3.0/tests/test_parser_fuzz.py +96 -0
  95. netforensicai-0.3.0/tests/test_parser_fuzz_deep.py +220 -0
  96. netforensicai-0.3.0/tests/test_parsers.py +817 -0
  97. netforensicai-0.3.0/tests/test_pipeline.py +203 -0
  98. netforensicai-0.3.0/tests/test_reports.py +278 -0
  99. netforensicai-0.3.0/tests/test_sample_incident.py +183 -0
  100. netforensicai-0.3.0/tests/test_search_streams.py +352 -0
  101. netforensicai-0.3.0/tests/test_smoke.py +24 -0
  102. netforensicai-0.3.0/tests/test_store.py +149 -0
  103. netforensicai-0.3.0/tests/test_store_resources.py +52 -0
  104. netforensicai-0.3.0/tests/test_suricata.py +116 -0
  105. netforensicai-0.3.0/tests/test_threat_intel.py +94 -0
  106. netforensicai-0.3.0/tests/test_timeline.py +175 -0
  107. netforensicai-0.3.0/tests/test_virustotal.py +108 -0
  108. netforensicai-0.3.0/tests/test_web.py +830 -0
  109. netforensicai-0.3.0/tests/test_web_auth.py +52 -0
  110. netforensicai-0.3.0/tests/test_web_dig.py +354 -0
  111. netforensicai-0.3.0/tests/test_web_home.py +175 -0
  112. netforensicai-0.3.0/tests/test_web_static_cache.py +28 -0
  113. netforensicai-0.3.0/tests/test_wireshark.py +813 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Sh3n0bi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,418 @@
1
+ Metadata-Version: 2.4
2
+ Name: netforensicai
3
+ Version: 0.3.0
4
+ Summary: Local-first DFIR investigation and evidence correlation platform
5
+ Author: Sh3n0bi
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025-2026 Sh3n0bi
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/Sh3n0bi/NetForensicAI
29
+ Project-URL: Repository, https://github.com/Sh3n0bi/NetForensicAI
30
+ Project-URL: Issues, https://github.com/Sh3n0bi/NetForensicAI/issues
31
+ Keywords: dfir,forensics,incident-response,pcap,security,evtx,sysmon,mitre-attack
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: Information Technology
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.9
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Topic :: Security
43
+ Requires-Python: >=3.9
44
+ Description-Content-Type: text/markdown
45
+ License-File: LICENSE
46
+ Requires-Dist: typer<1.0,>=0.12
47
+ Requires-Dist: pydantic<3.0,>=2.6
48
+ Requires-Dist: duckdb<2.0,>=1.0
49
+ Provides-Extra: pcap
50
+ Requires-Dist: scapy<3.0,>=2.5; extra == "pcap"
51
+ Requires-Dist: pandas<3.0,>=2.0; extra == "pcap"
52
+ Requires-Dist: scikit-learn<2.0,>=1.3; extra == "pcap"
53
+ Provides-Extra: intel
54
+ Requires-Dist: requests<3.0,>=2.31; extra == "intel"
55
+ Provides-Extra: ai
56
+ Requires-Dist: anthropic<2.0,>=1.0; extra == "ai"
57
+ Requires-Dist: requests<3.0,>=2.31; extra == "ai"
58
+ Provides-Extra: ai-openai
59
+ Requires-Dist: openai<4.0,>=1.40; extra == "ai-openai"
60
+ Provides-Extra: ai-gemini
61
+ Requires-Dist: google-genai<3.0,>=1.0; extra == "ai-gemini"
62
+ Provides-Extra: evtx
63
+ Requires-Dist: python-evtx<0.9,>=0.8; extra == "evtx"
64
+ Provides-Extra: web
65
+ Requires-Dist: flask<4.0,>=3.1.3; extra == "web"
66
+ Requires-Dist: werkzeug<4.0,>=3.1.6; extra == "web"
67
+ Requires-Dist: waitress<4.0,>=3.0; extra == "web"
68
+ Provides-Extra: dashboard
69
+ Requires-Dist: dash<5.0,>=3.0; extra == "dashboard"
70
+ Requires-Dist: plotly<8.0,>=5.15; extra == "dashboard"
71
+ Provides-Extra: dev
72
+ Requires-Dist: pytest<9.0,>=8.0; extra == "dev"
73
+ Requires-Dist: ruff==0.16.9; extra == "dev"
74
+ Provides-Extra: build
75
+ Requires-Dist: build>=1.0; extra == "build"
76
+ Requires-Dist: twine>=5.0; extra == "build"
77
+ Dynamic: license-file
78
+
79
+ <div align="center">
80
+
81
+ # NetForensicAI
82
+
83
+ **Turn packet captures and endpoint logs into one correlated, evidence-cited investigation — entirely on your own machine.**
84
+
85
+ [![Tests](https://github.com/Sh3n0bi/NetForensicAI/actions/workflows/tests.yml/badge.svg)](https://github.com/Sh3n0bi/NetForensicAI/actions/workflows/tests.yml)
86
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
87
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
88
+ [![Wireshark: optional](https://img.shields.io/badge/wireshark-optional-informational.svg)](docs/wireshark.md)
89
+
90
+ [Use cases](#use-cases) · [Install](#installation) · [How it works](docs/architecture.md) · [Worked example](docs/walkthrough.md) · [Commands](docs/commands.md) · [Deploy & sizing](docs/deployment.md) · [Limitations](#limitations)
91
+
92
+ </div>
93
+
94
+ ---
95
+
96
+ ## Contents
97
+
98
+ - [Overview](#overview) · [Use cases](#use-cases) · [Why it exists](#why-it-exists)
99
+ - [Installation](#installation) · [Quick start](#quick-start)
100
+ - [Limitations](#limitations) · [Testing](#testing) · [Contributing](#contributing)
101
+
102
+ **Reference:** [Capabilities](docs/capabilities.md) · [Commands](docs/commands.md) · [HTTP API](docs/api.md) · [Wireshark](docs/wireshark.md) · [Architecture & performance](docs/architecture.md) · [Deployment, sizing & compliance](docs/deployment.md) · [Worked example](docs/walkthrough.md) · [Validation](docs/validation.md)
103
+
104
+ ---
105
+
106
+ ## Overview
107
+
108
+ NetForensicAI takes raw digital evidence — packet captures, JSON/CSV logs, Windows Event Logs including Sysmon — and turns it into a single correlated investigation: normalized events, extracted entities, a unified timeline, an entity relationship graph, deterministic detections, and investigator-owned findings you can export as a report.
109
+
110
+ It runs entirely on your machine. **No cloud backend, no daemon, no database server, and no step that touches the network unless you explicitly opt into one.** A case is one DuckDB file plus a directory of JSON manifests and read-only evidence copies.
111
+
112
+ | | |
113
+ |---|---|
114
+ | **Input** | `.pcap` / `.pcapng` · `.json` · Suricata `eve.json` · `.csv` · `.evtx` · live network capture |
115
+ | **Output** | Timeline · entity graph · detections · ATT&CK mapping · findings · Markdown / JSON / HTML reports |
116
+ | **Interfaces** | CLI (`netforensic`) and a local web UI — both over the same core |
117
+ | **Requires** | Python 3.9+. Wireshark optional but recommended. |
118
+
119
+ ---
120
+
121
+
122
+ ## Use cases
123
+
124
+ **Triage a suspicious capture from an alert.** Point it at the pcap, run one command, and read the timeline. Protocol-level events — DNS lookups, HTTP requests and their status codes, TLS SNI, recovered file transfers — come out already normalized, so you start at "what happened" rather than at packet 1.
125
+
126
+ ```bash
127
+ netforensic evidence add ./alert-2026-08-28.pcap --case INC-0001 && netforensic analyze --case INC-0001
128
+ ```
129
+
130
+ **Tie network activity to what happened on the host.** Add a pcap *and* a Sysmon EVTX export to the same case. Because entity IDs are derived deterministically from normalized values, the same IP or hostname in both sources resolves to the same ID and joins automatically — which is the whole reason the two are worth having in one case.
131
+
132
+ **Investigate one indicator across everything you hold.** Given an IP, domain, hash, user, host, process, or file, get its first/last seen, a scoped timeline, ranked related entities, a one-hop relationship graph, and deterministic next-step leads.
133
+
134
+ ```bash
135
+ netforensic investigate --case INC-0001 --domain suspicious.example.com
136
+ ```
137
+
138
+ **Check a threat-intel feed against the evidence.** Import a vendor feed — plain text, CSV, STIX 2.1 or MISP — and every indicator the case touches becomes a finding at the top of the story. Defanged values from a PDF are accepted, and the feed's hash goes into the chain of custody.
139
+
140
+ ```bash
141
+ netforensic ioc import ./campaign-feed.txt --case INC-0001
142
+ ```
143
+
144
+ **Run lightweight live monitoring on a segment.** Rotating capture auto-ingests each finished window through the same pipeline, detection rules included — so a match surfaces as an alert without any separate "watch" mode.
145
+
146
+ **Analyse a web attack from server-side capture.** Aggregate rules are built for this: they summarize a 41,000-request scan into a handful of findings rather than 41,000 rows, and separately surface *the paths that actually returned success* — what the scan found, not just that it happened.
147
+
148
+ **Produce a defensible report.** Every claim cites the `evidence_id` and `event_id` it rests on. Evidence is hashed on ingest and never modified; every action is recorded in a hash-chained custody log you can verify. Export the whole case to a zip with a per-file manifest and hand it to someone else.
149
+
150
+ > **Not a NIDS, not a SIEM.** There is no rule marketplace, no alert queue, no multi-user server, no retention tier. It is an investigator's workbench for evidence you already have.
151
+
152
+ ---
153
+
154
+
155
+ ## Why it exists
156
+
157
+ Real investigations span evidence formats that share no schema, no identifiers, and no notion of which events relate to which. Answering *"is the IP in this pcap the same host as the one in that log line?"* by hand is slow and error-prone, and the reasoning usually lives in someone's head rather than in the case.
158
+
159
+ NetForensicAI does that stitching mechanically and keeps every resulting claim traceable to the specific evidence file and event it came from.
160
+
161
+ ### Design principles
162
+
163
+ | Principle | What it means in practice |
164
+ |---|---|
165
+ | **Deterministic first** | Parsing, correlation, timeline, and detections involve no AI and no network. Identical input produces identical output. |
166
+ | **Everything cites evidence** | No claim appears without the `evidence_id` / `event_id` it rests on. |
167
+ | **Never overstate certainty** | Correlation says `related` or `possible_relationship`, never "caused". Detections are flags, not verdicts. |
168
+ | **The investigator decides** | Nothing auto-creates a finding. AI proposes; a human confirms. |
169
+ | **Local-first, no infrastructure** | One DuckDB file plus a directory per case. No queue, no graph DB, no daemon. |
170
+ | **Honest about limits** | Known weaknesses are documented [here](#limitations) and in code, not hidden. |
171
+
172
+ ---
173
+
174
+
175
+ ## Installation
176
+
177
+ **From source**
178
+
179
+ ```bash
180
+ git clone https://github.com/Sh3n0bi/NetForensicAI.git
181
+ cd NetForensicAI
182
+ python3 -m venv .venv
183
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
184
+ pip install -e ".[pcap,intel,web]"
185
+ ```
186
+
187
+ **From PyPI** *(once a release is published — see [CONTRIBUTING.md](CONTRIBUTING.md))*
188
+
189
+ ```bash
190
+ pip install "netforensicai[pcap,intel,web]"
191
+ ```
192
+
193
+ **With Docker** — no Python, scapy or Wireshark to install; the image bundles **tshark**, so pcap parsing uses the fast engine automatically.
194
+
195
+ ```bash
196
+ docker build -t netforensicai .
197
+ docker run --rm -p 8000:8000 -v netforensic-data:/data netforensicai
198
+ ```
199
+
200
+ The container prints a one-time access token and a `http://localhost:8000/?token=…` URL (the web UI requires a token when it isn't on loopback). Set your own with `-e NETFORENSIC_WEB_TOKEN=…` to keep it stable. Cases and saved settings persist in the `/data` volume. Any CLI command works too, e.g. `docker run --rm -v netforensic-data:/data netforensicai case list`.
201
+
202
+ Once images are published, you can skip the build with `docker pull ghcr.io/sh3n0bi/netforensicai`.
203
+
204
+ ### Python extras
205
+
206
+ Everything beyond case management and the CLI core is optional.
207
+
208
+ | Extra | Pulls in | Needed for |
209
+ |---|---|---|
210
+ | `pcap` | scapy, pandas, scikit-learn | pcap/pcapng parsing, live capture, anomaly scoring |
211
+ | `evtx` | python-evtx | Windows Event Log / Sysmon parsing |
212
+ | `intel` | requests | VirusTotal lookups |
213
+ | `ai` | anthropic, requests | AI assistant — Anthropic and Ollama providers |
214
+ | `ai-openai` | openai | AI assistant — OpenAI provider |
215
+ | `ai-gemini` | google-genai | AI assistant — Google Gemini provider |
216
+ | `web` | flask | Local web UI |
217
+ | `dashboard` | dash, plotly | Legacy `netforensic scan` visualization |
218
+ | `dev` | pytest | Test suite |
219
+ | `build` | build, twine | Packaging a release (maintainers) |
220
+
221
+ Only `intel`, `ai`, `ai-openai`, and `ai-gemini` can reach the network, and only when you explicitly invoke the feature that uses them. Ollama's traffic stays on your machine.
222
+
223
+ ### Wireshark (optional, external)
224
+
225
+ Wireshark is **not** a pip extra — it is a separate program, and NetForensicAI uses three binaries from it. All are optional; install none and the pure-Python path handles everything.
226
+
227
+ | Binary | Used for | Without it |
228
+ |---|---|---|
229
+ | **`tshark`** | Dissection, display filters, slices, object export | Falls back to the built-in scapy engine |
230
+ | **`dumpcap`** | Live capture | Falls back to the scapy sniffer |
231
+ | **`Wireshark`** *(GUI)* | The `wireshark open` pivot only | `--print` still gives you the command to run elsewhere |
232
+
233
+ **`tshark` is the one that matters.** It carries the whole analysis path, so a server, container, or CI runner only needs that — no GUI, no Qt, no desktop stack:
234
+
235
+ ```bash
236
+ sudo apt install tshark # Debian / Ubuntu
237
+ sudo dnf install wireshark-cli # Fedora / RHEL
238
+ brew install wireshark # macOS (CLI tools; add --cask for the GUI)
239
+ ```
240
+
241
+ On a Windows analyst workstation the [standard Wireshark installer](https://www.wireshark.org/download.html) provides all three. It does not add itself to `PATH`, which is fine — NetForensicAI checks `C:\Program Files\Wireshark` directly.
242
+
243
+ ```bash
244
+ netforensic wireshark status
245
+ ```
246
+
247
+ ```
248
+ Wireshark: 4.6.8
249
+ tshark: C:\Program Files\Wireshark\tshark.exe
250
+ dumpcap: C:\Program Files\Wireshark\dumpcap.exe
251
+ GUI: C:\Program Files\Wireshark\wireshark.exe
252
+ Parse engine: tshark (requested: auto)
253
+ Capture engine: dumpcap
254
+ ```
255
+
256
+ See [Wireshark integration](docs/wireshark.md) for what each one changes.
257
+
258
+ ### Verify the environment
259
+
260
+ ```bash
261
+ netforensic doctor
262
+ ```
263
+
264
+ `doctor` is read-only: it reports the Python version, the DuckDB case store, each
265
+ optional evidence engine (scapy, scikit-learn, python-evtx, tshark/dumpcap), the
266
+ active pcap engine, and whether an AI provider or VirusTotal key is configured.
267
+ A missing *optional* capability is shown as a note with its fallback, not a
268
+ failure — the command exits non-zero only when a core dependency is broken. Add
269
+ `--json` for a machine-readable report. `netforensic --version` prints the
270
+ installed version.
271
+
272
+ ---
273
+
274
+
275
+ ## Quick start
276
+
277
+ ### Command line
278
+
279
+ ```bash
280
+ netforensic case create --name "Test Incident"
281
+ netforensic evidence add ./capture.pcap --case INC-0001
282
+ netforensic analyze --case INC-0001
283
+ netforensic detections list --case INC-0001
284
+ netforensic investigate --case INC-0001 --ip 192.168.1.10
285
+ netforensic report generate --case INC-0001 --format html
286
+ ```
287
+
288
+ ### Try it without evidence of your own
289
+
290
+ `samples/generate_incident.py` builds a synthetic capture containing a complete incident — a lookup of a cheap-TLD domain, an executable pulled over cleartext HTTP, a credential posted in the clear, a private key retrieved, the same password reused on FTP, a customer CSV uploaded in chunks, then eight beacons — plus ordinary browsing, so the capture is not made entirely of findings.
291
+
292
+ ```bash
293
+ python samples/generate_incident.py -o incident.pcap
294
+ netforensic case create --name "Demo incident"
295
+ netforensic evidence add ./incident.pcap --case INC-0001
296
+ netforensic analyze --case INC-0001
297
+ netforensic story --case INC-0001
298
+ ```
299
+
300
+ ```
301
+ 7 distinct findings (5 high severity) across 2 hosts.
302
+
303
+ Assessment [critical]: Evidence is consistent with data leaving this network
304
+ after a credential was exposed.
305
+
306
+ CREDENTIAL ACCESS
307
+ [high] 22:14:19 One credential used across several protocols
308
+ The same password was observed on FTP, HTTP. Reuse turns a single
309
+ cleartext disclosure into access everywhere that credential is accepted.
310
+ evidence: EVT-EV-0001-000009
311
+ ```
312
+
313
+ A generator rather than a checked-in `.pcap`, deliberately: a binary in a repository is something you take on trust, and this is the same capture expressed as something you can read and diff. The traffic is fabricated end to end — no real host is contacted and nothing is captured from a real network. Every act is detected identically by both dissection engines, so this works with or without Wireshark installed.
314
+
315
+
316
+ ### Browser
317
+
318
+ ```bash
319
+ netforensic web --cases-dir cases # then open http://127.0.0.1:8000
320
+ ```
321
+
322
+ 1. **Settings** *(top right)* — optionally add VirusTotal / AI keys and press **Test**. Everything except threat intel and the AI assistant works with no keys at all.
323
+ 2. **New investigation** — name the case, drop in your evidence (pcap, pcapng, evtx, JSON, CSV) and press **Create and analyze**. It uploads, hashes, analyzes and opens on the story in one step.
324
+ 3. **What happened** — read the account of the case before the counts: the assessment, the stages
325
+ it passed through, and each finding with the events it rests on.
326
+ 4. Review **Timeline**, **Entities**, **Detections**, **ATT&CK**, **Custody**; record **Findings**; export a **Report**.
327
+
328
+ ---
329
+
330
+
331
+ ## What it does
332
+
333
+ Each of these is covered properly in [the capability reference](docs/capabilities.md); this is the map.
334
+
335
+ | | |
336
+ |---|---|
337
+ | **Evidence integrity** | Copied in, SHA-256 hashed from the stored copy, set read-only, recorded in a manifest. |
338
+ | **Chain of custody** | Every action appended to a hash-chained log. `case audit --verify` reports whether it has been altered. |
339
+ | **Parsers** | `.pcap`/`.pcapng` (tshark or scapy), `.json`, Suricata `eve.json`, `.csv`, `.evtx` — all normalized into one Common Event Model. |
340
+ | **Search** | Content search over a capture's raw bytes: text, regex, or hex. ~6s across 1,000,000 packets. |
341
+ | **Streams** | Conversations reassembled by Wireshark, ranked by volume. |
342
+ | **Triage** | The first questions worth asking an unfamiliar capture: protocols, flags, credentials, secrets, recoverable files. |
343
+ | **Entities & correlation** | Deterministic IDs join the same real-world thing across evidence sources. Links are `related` or `possible_relationship`, never "caused". |
344
+ | **Detections** | Eight offline rules — no AI, no network — run automatically on every `analyze`. |
345
+ | **ATT&CK** | Deterministic, evidence-cited technique suggestions with an investigator-settable status. |
346
+ | **Assistant** | Retrieves evidence through read-only tools; every claim is checked against what it retrieved, and an answer citing anything else is refused. |
347
+ | **Findings & reports** | Investigator-owned findings citing evidence/event pairs; Markdown, JSON and HTML output. |
348
+ | **Web UI** | A dashboard over the same core the CLI uses. No build step, no CDN, works offline. |
349
+ | **Live capture** | Rotating windows auto-ingested through the same pipeline, detection rules included. |
350
+ | **Portability** | Export a case to one zip with a per-file SHA-256 manifest; import verifies every file first. |
351
+
352
+ ---
353
+
354
+ ## Limitations
355
+
356
+ Stated plainly, because a forensics tool that hides its weaknesses is worse than one that has them.
357
+
358
+ > **Maturity and evidentiary use.** NetForensicAI is Beta software (`0.2.x`). It is built to *support* sound evidence-handling practice — read-only evidence copies, a tamper-evident custody chain, deterministic detections — but it is **not accredited or validated against any forensic standard**, and nothing here is a claim that its output is admissible or court-ready. Treat it as an investigator's analysis aid; have a qualified examiner validate any finding you intend to rely on formally.
359
+
360
+ - **The correlation link count is a ceiling, not a total.** It caps at 50,000 pairs, and on a dense capture it will reach that: tens of thousands of shared-host pairs inside a five-minute window genuinely exist. The budget is now spent on signal first — ports are not correlated on, no entity may take more than a tenth of it, and `related` is never displaced by `possible_relationship` — and both the CLI and the API say when the number is a ceiling. Shorten `--time-window` on a dense case; detections and the timeline are the better entry points either way.
361
+ - **Anomaly detection is disabled above ~20,000 packets.** IsolationForest's `contamination` is a *proportion*, so on a large capture it flags a fixed percentage of everything by construction — a quantile, not a finding. It stays on for smaller captures where an outlier means something.
362
+ - **HTTP request/response pairing is FIFO per flow.** Correct for ordinary keep-alive traffic; genuinely pipelined requests could mis-pair, so a response's URL is a reference rather than a certainty.
363
+ - **Correlation memory is reduced but not constant** — it still holds one entity-link map proportional to the case.
364
+ - **ATT&CK coverage is deliberately small** (four techniques). Each was chosen because the signal is specific, not to pad a matrix.
365
+ - **EVTX covers five Sysmon event types richly**, everything else generically.
366
+ - **The custody hash chain** detects corruption and casual editing, not an attacker who owns the machine.
367
+ - **Live capture needs Npcap/libpcap and elevated privileges**, which this tool does not install or grant.
368
+ - **Ingest is the scaling limit, not dissection.** tshark reads a 1M-packet capture in 46 seconds; putting those events and their entity links into the store takes about fourteen minutes, and throughput degrades with case size (4,497 events/s at 100k against 1,907/s at 1M) because every entity-link insert probes a growing index. For very large captures the workflow is to **search and slice first, then ingest the slice** — search and `wireshark slice` read the capture file and scale to gigabytes.
369
+ - **The assistant has not been exercised against a live provider in this repository's testing.** Its rendering, its tool loop and its refusal path are covered against a scripted model; the HTTP round trip to Anthropic, OpenAI, Gemini or Ollama is not.
370
+ - **The two pcap engines do not produce identical output.** That is the point — tshark sees protocols the scapy engine cannot — but it means a case re-analyzed under a different engine will not have identical events. Each event records the engine that produced it, and `--engine` pins one when reproducibility matters.
371
+ - **tshark object export runs as a second pass** over the capture. It keeps the streaming parse's memory profile intact, at the cost of reading the file twice when an output directory is given.
372
+ - **Exported objects carry no timestamp.** tshark's object export reports the recovered file but not the frame it completed on, so `file_transfer` events from it sort at the end of the timeline as `unknown` rather than in position. A wrong timestamp on forensic evidence is worse than an absent one, so none is invented — the parent flow's events carry the timing.
373
+ - **The web UI has no per-user accounts.** On `127.0.0.1` (the default) it is unauthenticated by design. Binding it off loopback now *requires* a shared token (`--auth-token` / `NETFORENSIC_WEB_TOKEN`) and the CLI refuses to start without one — but that single token is all the access control there is; still front it with TLS. See [docs/deployment.md](docs/deployment.md).
374
+
375
+ ---
376
+
377
+
378
+ ## Testing
379
+
380
+ ```bash
381
+ pip install -e ".[dev,pcap,intel,evtx,ai,ai-openai,ai-gemini,web]"
382
+ pytest
383
+ ```
384
+
385
+ **770+ tests**, run in CI against Python 3.9 and 3.12 on Linux and against 3.12 on Windows and macOS (the analyst-workstation platforms), plus a dedicated job that installs tshark so the Wireshark integration is genuinely exercised rather than skipped, a `ruff` lint gate ([tool.ruff] in `pyproject.toml`), and a packaging check that installs the built wheel into a clean environment and confirms the web UI's assets are actually bundled.
386
+
387
+ Lint locally with the same rules CI enforces:
388
+
389
+ ```bash
390
+ ruff check .
391
+ ```
392
+
393
+ The suite favours real fixtures over mocks: pcaps built with scapy, EVTX from hand-crafted XML matching the real schema, cases from `tmp_path`, and real tshark invocations wherever Wireshark is present. Mocks are reserved for what genuinely cannot be exercised in CI — external APIs, and opening a live network interface.
394
+
395
+ Several classes of bug were found only by running against real evidence and real tooling rather than synthetic fixtures — silently-dropped IPv6, HTTPS payloads skipped because scapy re-dissects them, DNS missed off port 53, a quadratic insert that made a 30 MB file take over 15 minutes, and a live-capture counter that reported the session total in the per-window field. Each is now pinned by a regression test.
396
+
397
+ ---
398
+
399
+
400
+ ## Contributing
401
+
402
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, the parser plugin interface, and the release process. Release history is in [CHANGELOG.md](CHANGELOG.md).
403
+
404
+ The shape of a good contribution here: a new `BaseParser` subclass for a format, a detection rule with a specific and defensible signal, or a regression test for a bug found against real evidence.
405
+
406
+
407
+ ## Security policy
408
+
409
+ This is defensive tooling for evidence you are authorized to analyze. It does not exploit, attack, or scan anything.
410
+
411
+ Nothing leaves your machine unless you explicitly invoke threat intel or a hosted AI provider. Live capture requires privileges the tool does not grant itself. To report a vulnerability, please follow [SECURITY.md](SECURITY.md) (private disclosure via GitHub Security Advisories) rather than opening a public issue.
412
+
413
+
414
+ ## License
415
+
416
+ [MIT](LICENSE).
417
+
418
+