Skip to content

About

Blue-team DFIR platform for PCAP triage - YARA scanning, protocol-state attack detection, C2/webshell/miner hunting, GeoIP mapping, and AI-assisted analysis.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

32 Commits

Folders and files

Repository files navigation

Pcap-Analyzer DFIR Triage Platform

image

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.


Contents


Features

Triage

  • 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.

Detection

  • 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 .yar files in and reload.
  • Active Directory coverage - Kerberoasting, AS-REP roasting, SMB lateral movement (admin shares, PsExec-style svcctl, DCSync via drsuapi).

Investigation

  • 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-Disposition or the URL), FTP transfers (named from the control channel's RETR/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.

Context & output

  • 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.

Screenshots

Overview - verdict at a glance

Overview page: severity-coloured verdict banner, capture summary, severity breakdown and top talkers

Findings - severity-ranked detections

Findings page: MITRE-mapped detections with evidence and confirmed / attempt classification

Follow TCP Stream image

Attack timeline

Timeline: every finding time-anchored to the packets that produced it

Connections

Connections: per-conversation breakdown of endpoints, ports and byte counts

GeoIP attack map

GeoIP attack map

Protocol Analysis

Protocol Analysis

Traffic Flow

Traffic Flow

HTTP Transactions

HTTP Transactions

TLS/JA3 & Certificates

TLS/JA3 & Certificates

IOC

IOC

Sessions & Files

Sessions & Files

AI Support assessment image


Quick start

Docker (recommended)

git clone https://github.com/geezsecurity/Pcap-Analyzer.git
cd Pcap-Analyzer
docker compose up --build

Open 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? Use docker 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).

Local development

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 8000

Frontend (Node 20.19+ or 22.12+ - required by Vite 8):

cd frontend
npm install
npm run dev          # http://localhost:5173, proxies /api → :8000

GeoIP database (optional)

The 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.


Sample captures

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.py

The 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.


Cyber Threat Map

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.


Optional integrations

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.


Detection coverage

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.


How the analysis works

upload → parse (scapy) → analyze → detect → persist → explore
  1. Upload creates a job; analysis runs as a background task, so the UI never blocks.
  2. Analysis computes capture metadata, protocol/flow statistics, and the GeoIP report.
  3. 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 info finding rather than killing the run.
  4. Time anchoring - after the rules run, any finding without timestamps gets them from the packets it cites, so every finding lands on the timeline.
  5. 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.


Architecture

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.


Configuration

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.


Development

# 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 build

Sample 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.


Known limitations

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 that MAX_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.

Credits

License

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.

About

Blue-team DFIR platform for PCAP triage - YARA scanning, protocol-state attack detection, C2/webshell/miner hunting, GeoIP mapping, and AI-assisted analysis.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages