Upload a packet capture and get an immediate answer to the question every incident responder asks first: was there an attack, did it succeed, and where did it come from?
Pcap-Analyzer parses a .pcap / .pcapng / .cap, runs 28 detection rules and a YARA
engine over it, correlates indicators across every capture you have analysed, reconstructs
the attack chain on a timeline, carves transferred files, plots every external endpoint on
a world map, and exports an incident report as PDF or DOCX.
docker compose up --build → http://localhost:8182
Rewrite notice. This is a ground-up rewrite of HatBoy/Pcap-Analyzer (Flask / Python 2). The original's analysis ideas are preserved and credited; the code is now a FastAPI backend with a React + TypeScript frontend, and the detection engine is substantially expanded. See Credits.
- Features
- Screenshots
- Quick start
- Sample captures
- Cyber Threat Map
- Optional integrations
- Detection coverage
- How the analysis works
- Architecture
- Configuration
- Development
- Known limitations
- Credits
- Verdict at a glance - Overview page with a severity-coloured verdict banner, capture summary (time window, duration, rate, link layer, snaplen truncation), severity breakdown, top categories and top talkers.
- Attack timeline - every finding is time-anchored to the packets that produced it, so the chain reads in order: recon → exploitation → backdoor ports → credential theft.
- Did the attack actually work? Web-attack findings are classified by the server's HTTP response - Confirmed (2xx), Server error (5xx), Attempt (4xx) - and the Findings page can filter on that. A confirmed hit and a blocked probe are not the same incident.
- 28 detection rules, each MITRE ATT&CK-mapped, with evidence and drill-down packets.
- YARA engine - 45 bundled rules scanned over reassembled TCP streams and carved
files: webshells (plaintext and encrypted - Behinder, Godzilla, AntSword, reGeorg),
modern C2 (Sliver, Havoc, Mythic, Empire, Covenant, Brute Ratel), tunnelling (chisel,
ngrok, cloudflared, frp), cryptomining (Stratum, XMRig), infostealers, AD tooling
(Rubeus, SharpHound, impacket, DCSync), and payload/credential artefacts. Drop your own
.yarfiles in and reload. - Active Directory coverage - Kerberoasting, AS-REP roasting, SMB lateral movement
(admin shares, PsExec-style
svcctl, DCSync viadrsuapi).
- Follow TCP Stream - Wireshark-style, with a Decoded view that de-chunks and gunzips HTTP bodies, so a compressed response reads as text instead of binary noise. Text / Raw / Hex modes; hex is a proper offset·hex·ASCII dump.
- File carving - HTTP objects (named from
Content-Dispositionor the URL), FTP transfers (named from the control channel'sRETR/STOR), and PE/ELF binaries found at any offset inside a stream, with header validation and true on-disk sizing so the SHA-256 matches the real artifact. Flags masquerading files whose extension contradicts their magic bytes. - Sessions & credentials - reassembled HTTP / FTP / Telnet / Mail, harvested cleartext credentials.
- Packet explorer - paginated, filterable, with a layer-by-layer detail drawer.
- GeoIP attack map - external endpoints plotted with attacker→victim arcs, on a real street map (Street / Satellite / Dark basemaps, English labels).
- Threat intel - AbuseIPDB (abuse score, ISP, Tor) and VirusTotal (IP + file hash), proxied server-side and cached to respect rate limits.
- Reports - export a full incident report as PDF or DOCX: verdict, capture summary, findings overview, attack timeline, per-finding detail with MITRE, external threat endpoints, top talkers.
- AI Support (optional) - have an LLM read the findings and write a DFIR assessment: attack chain, likely false positives, impact, and prioritised next steps. Works with Anthropic Claude, OpenAI, or Google Gemini - each via its official SDK.
Overview - verdict at a glance
Findings - severity-ranked detections
Attack timeline
Connections
GeoIP attack map
Protocol Analysis
Traffic Flow
HTTP Transactions
TLS/JA3 & Certificates
IOC
Sessions & Files
git clone https://github.com/geezsecurity/Pcap-Analyzer.git
cd Pcap-Analyzer
docker compose up --buildOpen http://localhost:8182 and drop a capture on the upload page.
Everything runs in two containers (FastAPI backend + nginx-served React frontend). The
backend is only reachable inside the compose network; the browser talks to it through the
frontend's /api proxy, so it's all same-origin on one port.
Re-running after a
git pull? Usedocker compose up --build- without--build, Compose reuses the cached image and you'll be looking at old code. See DOCKER.md for troubleshooting (including slow-network build timeouts).
Backend (Python 3.12+):
cd backend
python3 -m venv .venv
./.venv/bin/pip install -r requirements.txt
./.venv/bin/uvicorn app.main:app --reload --port 8000Frontend (Node 20.19+ or 22.12+ - required by Vite 8):
cd frontend
npm install
npm run dev # http://localhost:5173, proxies /api → :8000The MaxMind GeoLite2 database is not bundled - it's licensed and can't be redistributed. Without it the app works normally; only the map and geo columns stay empty.
To enable geolocation, sign up for a free MaxMind account, download GeoLite2-City.mmdb (and optionally GeoLite2-ASN.mmdb for ASN/org data), and place them here:
backend/geoip/GeoLite2-City.mmdb
backend/geoip/GeoLite2-ASN.mmdb # optional
GET /api/health reports whether the database was found.
pcaps/ ships six small captures, one per attack class. Upload any of them to see the
tool work end to end without hunting for test data.
| Capture | Scenario | Fires |
|---|---|---|
01-web-attacks.pcap |
SQLi, XSS, traversal, LFI, command injection - mixed 200/403/404/500 responses | 9 findings; exercises the attack-outcome filter (which payloads actually landed) |
02-ssh-bruteforce.pcap |
30 SSH connection attempts, then a successful login | brute_force (high) |
03-ftp-attack.pcap |
FTP password spraying (18× 530), cleartext creds, backdoor upload |
brute_force, cleartext_credentials, insecure_protocol, YARA reverse-shell match (critical) |
04-malware-download.pcap |
PE executable pulled over HTTP + encoded PowerShell stager | malware_download ×2, YARA; carves 3 files incl. a valid PE |
05-data-exfiltration.pcap |
5.25 MB pushed to an external host, minimal traffic back | data_exfiltration (medium tier) |
06-ddos-synflood.pcap |
3,000 SYNs from ~1,160 sources across 5 countries | dos (high); populates the GeoIP attack map |
Together: 19 findings, 0 rule errors, every finding time-anchored.
These captures are entirely synthetic. They are generated with scapy - nothing was recorded from a real network, and no real system was contacted or scanned. The external addresses are fabricated for the scenario and imply nothing about their actual owners; routable ranges are used only because RFC 5737 documentation ranges are classified as private, which would stop the internal→external rules from ever firing.
Regenerate them (output is deterministic) with:
python backend/tests/fixtures/generate_samples.pyThe generator doubles as a regression fixture - each capture is built to trip specific rules, so a rule that silently stops matching shows up as a missing finding.
Attack origins plotted on a real basemap, with animated arcs running from each hostile source to the target.
- Attack origins - hostile addresses rolled up by country and ranked, so a 1,000-source flood collapses into a handful of rows. Click a country to filter the map to it.
- Travelling attack arcs - an arrow runs along each path from source to target, coloured by severity and weighted by that origin's share. Pause from the toolbar.
- Ripple markers - hostile endpoints pulse; the target sits under an expanding ring.
- Vector world map - country outlines from Natural Earth (public domain, bundled), so the map needs no tile server and renders fully offline.
Requires the GeoLite2 database (see Quick start); without it the map is empty and the rest of the tool is unaffected.
Set your location. The monitored host is normally a private address with no geolocation of its own, so by default the target is drawn at the centroid of observed endpoints - which frequently lands mid-ocean. Set Settings → Threat map → Latitude/Longitude to your site and re-run analysis; Reset to automatic restores the centroid.
All optional - the analyzer is fully functional without any of them. Configure from the
Settings page (stored server-side, never returned to the browser) or via
backend/.env (see backend/.env.example).
| Integration | What it adds | Where to get a key |
|---|---|---|
| AbuseIPDB | IP abuse score, ISP, Tor exit detection | abuseipdb.com |
| VirusTotal | IP reputation + carved-file hash lookup | virustotal.com |
| AI Support | LLM-written DFIR assessment | Anthropic · OpenAI · Google AI |
For AI Support, pick a provider in Settings and paste that provider's key. Once a key is saved the model dropdown is populated live from the provider's API, so it always reflects the models your account can actually use - there's also a free-text box for a specific model id.
28 rules, all MITRE ATT&CK-mapped and time-anchored.
| Category | Detections | MITRE |
|---|---|---|
| Reconnaissance | Port scan (SYN volume + distinct ports), stealth scans (NULL/FIN/Xmas), scanner user-agents | T1046, T1595 |
| Web attacks | SQL injection, XSS, path traversal, LFI/RFI, command injection, webshells, Log4Shell - 15 signatures, outcome-classified by HTTP status | T1190, T1059, T1505.003, T1083 |
| Credential attacks | FTP / Telnet / HTTP brute force (failure counting), SSH / RDP / SMB / DB brute force (connection churn), cleartext credentials | T1110, T1040 |
| Active Directory | Kerberoasting (RC4 TGS), AS-REP roasting, SMB lateral movement - admin shares, PsExec svcctl, DCSync drsuapi |
T1558.003, T1558.004, T1021.002, T1569.002, T1003.006 |
| Kerberos auth outcome | Password spray (breadth across accounts), single-account brute force, account enumeration, lockouts - classified by what the KDC returned: an AS-REP means the credential worked, KDC_ERR_PREAUTH_FAILED means it did not |
T1110.003, T1110.001, T1087.002, T1531 |
| Command & control | Beaconing (interval jitter analysis), DNS tunneling, DGA scoring, fast-flux DNS, malicious JA3, suspicious TLS certs, trojan/backdoor ports | T1071, T1568, T1573, T1571 |
| Exfiltration & transfer | Data exfiltration (one-way volume + ratio), ICMP tunneling, HTTP malware delivery (PE/encoded PowerShell) | T1048, T1095, T1105 |
| Denial of service | SYN flood - volume against one service, source diversity, and handshake-completion ratio must all agree before firing | T1498.001, T1499.002 |
| Hygiene | Insecure protocols in use (Telnet, FTP, HTTP Basic, cleartext LDAP, SNMP v1/v2c) | T1040 |
| YARA | 45 bundled rules over streams and carved files - webshells (incl. China Chopper), Mimikatz, Meterpreter, Cobalt Strike, reverse shells, private keys, cloud credentials, ransom notes | rule-defined |
Thresholds for brute force, port scan, DNS tunneling, beaconing, and exfiltration are tunable from the Settings page.
upload → parse (scapy) → analyze → detect → persist → explore
- Upload creates a job; analysis runs as a background task, so the UI never blocks.
- Analysis computes capture metadata, protocol/flow statistics, and the GeoIP report.
- Detection runs every rule in a single pass over a shared context (sessions, TLS
fingerprints, Kerberos/SMB events are computed once and reused). A rule that raises is
isolated - it becomes an
infofinding rather than killing the run. - Time anchoring - after the rules run, any finding without timestamps gets them from the packets it cites, so every finding lands on the timeline.
- Results are cached on the job (SQLite), so revisiting a capture is instant.
Attribution is direction-aware: the client (initiator) is the attacker and the server is the target, determined by the well-known port rather than by guessing which host the capture was taken on.
backend/ FastAPI + scapy
app/analysis/ protocol stats, flow, geoip, sessions, TLS/JA3, AD (Kerberos/SMB),
file carving, stream reassembly, HTTP body decoding
app/detection/ rule engine, signatures, YARA engine, scoring
app/intel/ AbuseIPDB + VirusTotal clients with TTL cache
app/reporting/ shared report model → PDF (ReportLab) + DOCX (python-docx)
app/ai/ multi-provider LLM analyst (Anthropic / OpenAI / Gemini)
app/api/routes/ upload, analysis, extract, detection, report, ai, settings
config/ protocol/port lookups, trojan ports, file magics, JA3 blacklist,
yara/*.yar rules
frontend/ React 18 + TypeScript + Vite + Tailwind
src/pages/ Upload, Overview, Findings, Timeline, GeoMap, Connections, Hosts,
Protocols, Flow, Packets, HTTP, DNS, TLS, IOCs, Sessions, Settings
src/components/ Layout, FollowStream, PayloadView (text/hex), IpIntel, ui
Stack: FastAPI · scapy 2.7 · SQLAlchemy 2 · SQLite · cryptography · yara-python · ReportLab · python-docx - React 18 · TanStack Query · Recharts · React-Leaflet · Tailwind.
Settings are layered: database (Settings page) overrides .env overrides defaults.
| Setting | Default | Purpose |
|---|---|---|
MAX_UPLOAD_MB |
512 | Upload size limit |
BRUTE_FORCE_THRESHOLD |
10 | Auth failures before a brute-force finding |
PORT_SCAN_PORT_THRESHOLD |
15 | Distinct ports before a scan finding |
DNS_TUNNEL_QNAME_LENGTH |
50 | Query length that looks like tunneling |
BEACON_MIN_EVENTS |
8 | Connections needed for interval analysis |
EXFIL_MIN_UPLOAD_MB |
1 | Outbound volume before an exfil finding |
INTEL_CACHE_TTL_HOURS |
24 | Threat-intel cache lifetime |
CORS_ORIGINS |
localhost:8182 |
Allowed browser origins |
API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, ABUSEIPDB_API_KEY,
VIRUSTOTAL_API_KEY) can be set the same way. Copy backend/.env.example to
backend/.env to use the file route - it's git-ignored.
# backend
cd backend && ./.venv/bin/uvicorn app.main:app --reload --port 8000
# interactive API docs at http://localhost:8000/docs
# frontend
cd frontend && npm run dev # :5173
npx tsc -b # typecheck
npm run build # production buildSample captures live in pcaps/ - see Sample captures. They are
generated, not recorded, and each one targets specific rules, so they work as a quick
regression check after changing detection logic.
Adding a detection rule: write a function (ctx) -> list[RawFinding] in
app/detection/rules_dfir.py and add it to DFIR_RULES. Include
evidence["packet_ids"] and you get timeline placement, stream drill-down, and packet
evidence for free.
Adding YARA rules: drop a .yar file into backend/config/yara/ and hit Reload
rules in Settings. Use meta.severity and meta.mitre to control how findings surface.
Each file is compiled independently, so a broken rule file is skipped rather than
disabling the engine.
Worth knowing before you rely on it:
- Detections are heuristic. They surface leads, not verdicts. Response-side signature matches in particular are down-weighted because ordinary web content can trip them - always confirm via Follow Stream or the packet evidence.
- Capture size has a practical ceiling. Parsed captures are cached in memory (LRU,
~1 GB by default,
CAPTURE_CACHE_MB), so repeated views of the same capture are instant rather than re-parsing it each time. But the whole capture still has to fit in RAM at roughly 10x its file size, and a capture larger than the cache budget is re-parsed on every request as before. Comfortable up to ~50 MB / ~100k packets; usable to ~150 MB; beyond that you want a streaming/indexed backend, which does not exist yet. Note thatMAX_UPLOAD_MB(512) is far above what the engine can process comfortably. - Encrypted traffic stays encrypted. There's no TLS decryption - TLS analysis is limited to handshake metadata (SNI, JA3, certificates).
- The AI assessment is advisory. It can be wrong or confidently miss things; treat it as a second opinion, not a conclusion.
- Timestamps are rendered in the server's local timezone.
- No authentication. Anyone who can reach the port can upload and read captures - run it on a trusted network or put your own auth in front of it.
- Original project: HatBoy/Pcap-Analyzer -
the protocol/flow/session analysis approach and the
config/lookup tables come from there. - scapy for packet parsing, MaxMind GeoLite2 for geolocation, YARA for signature matching, AbuseIPDB and VirusTotal for threat intelligence.
GNU General Public License v3.0 - see LICENSE. This is inherited from the upstream project and carries forward to this rewrite: you may use, modify, and redistribute it, but derivative works must also be GPLv3 and ship their source.
GeoLite2 data and any third-party API use are governed by their own terms.












