Detect Compromised Devices Before They Become Breaches

Vigilo learns what "normal" looks like for every device on your network from Zeek connection metadata (conn.log) — who talked to whom, when, and how much. When a device starts scanning ports, beaconing to a C2 server, or participating in a flood, Vigilo flags it without signatures, without cloud dependencies, and without sending traffic off your network. Payload contents (e.g. HTTPS bodies) are not inspected.

Status: v0.1.0 research prototype — IoT-23 lab benchmarks are documented; field validation on home/enterprise networks is ongoing.

75% Detection rate @ 1% FPR
~1.3M Parameters (runs on CPU)
20 Malware families tested
0 Data sent to cloud

How Vigilo Works

1

Ingest

Vigilo reads Zeek conn.log files or converts pcap captures via tshark/Zeek. Works with passive taps (switch SPAN/mirror), gateway Zeek (pfSense/OPNsense), or lab MITM capture scripts.

2

Featurize

Traffic is grouped into 5-minute behavioral windows per device. Each window captures 15 features: connection counts, byte volumes, port distributions, protocol ratios, and timing patterns.

3

Forecast

A ~1.3M parameter Mamba-2 state-space model predicts the next behavioral window based on the device's history. The model is trained only on benign traffic — it learns "normal."

4

Score

Anomaly is measured as forecast error. If the device's actual behavior is far from what the model predicted, the surprise score is high — indicating abnormal behavior.

5

Ensemble

A dedicated beaconing detector identifies stealthy periodic C2 channels that volume-based detection might miss. Results from both detectors are combined for the final verdict.

Benchmark Results — IoT-23 Dataset

Trained on benign honeypot captures (29 benign devices). Evaluated on every malware family in IoT-23 including Mirai, Okiru, Torii, Gagfyt, Hajime, and Kenjiro. IoT-23 is lab data — not yet validated on live home or enterprise networks.

Detection Performance

MetricValue
Detection @ ~1% FPR75% (15/20 infected devices)
Benign baseline (device peak)p95 = 1.93, max = 1.97
Training dataBenign traffic only, 29 devices
Model size~1.3M params, CPU, fully local

What It Catches

All loud attacks — port scans, DDoS/flooding, noisy botnet C&C. These score far above the benign ceiling:

  • Anomaly scores of 1444, 65, 5.3 (vs. benign max 1.97)
  • Mirai variants, Okiru, Gagfyt flooding detected immediately
  • Port scanning activity flagged with high confidence

Honest Limitations

5 of 20 infected devices were missed — all stealthy, low-volume C&C:

  • One capture: only 16 malicious flows among 3,193 benign
  • These sit right at the benign ceiling threshold
  • Per-device baselining and flow-level inspection are on the roadmap

Data Experiment Findings

  • Run-to-run variance: Same setup gave 75% @ 1% FPR one run, 40% @ 1% / 75% @ 5% another. Loud attacks always caught, stealthy always missed — threshold calibration is the variable.
  • PC traffic hurts: Adding general-host captures dropped detection 75% → 20%. PCs are too noisy; train on IoT-like traffic only.
  • Implication: Per-asset baselining is the path to "works with any device" and stable thresholds.

Technical Architecture

Mamba-2 SSM Core

The forecaster uses a Mamba-2 Structured State Space model — O(1) memory per step, hardware-optimized scan, ideal for streaming time-series data on resource-constrained devices.

Zeek / pcap Ingestion

Native Zeek conn.log parsing with automatic pcap-to-conn.log conversion via tshark. Works with existing network taps and monitoring infrastructure.

15-Feature Behavioral Windows

Each 5-minute window captures connection counts, byte volumes, port entropy, protocol distribution, and timing patterns per device.

Beaconing Detector

Measures inter-connection interval regularity (coefficient of variation) to detect periodic C2 beaconing — stealthy callback patterns that volume-based detection may miss.

Flask Dashboard

Local web UI with per-device verdicts and scores. JSON API at /api/results for integration; refresh re-analyzes the configured log file.

Docker Deployment

One-command deployment via Docker Compose. Configurable via environment variables for log paths, checkpoints, worker counts, and bind addresses.

Deployment

Recommended production path: passive capture via switch SPAN/mirror or gateway Zeek. Optional Bettercap MITM scripts exist for lab testing on networks you own (disruptive; not recommended for production). Full wiring guide: SPAN / gateway deployment docs on GitHub.

Demo (no hardware)

pip install -e .
python scripts/generate_demo_data.py
vigilo serve
# http://127.0.0.1:8088

Passive SPAN / mirror

cp .env.span.example .env
# CAPTURE_IFACE=eth1 (mirror NIC)
docker compose --profile span up -d

Step-by-step SPAN guide →

Docker (analyze existing logs)

cp .env.example .env
make build && make up
# Dashboard at http://127.0.0.1:8088

Train on your network

vigilo train --logs data/benign.conn.log \
--output-dir checkpoints/vigilo
vigilo detect --log suspect.conn.log \
--ckpt checkpoints/vigilo/vigilo.pt

Configuration

VariableDefaultDescription
VIGILO_LOGdata/demo/sample.conn.logPath to the conn.log to analyze
VIGILO_CKPTcheckpoints/demo/vigilo.ptTrained model checkpoint
VIGILO_HOST0.0.0.0Dashboard bind address
VIGILO_PORT8088Dashboard port
VIGILO_WORKERS2Gunicorn worker count
VIGILO_TIMEOUT120Request timeout (seconds)

Open Source

Vigilo is free and open source under the Apache 2.0 license. Clone the repository, run the demo locally, and audit the code — connection metadata stays on your network.

100% on-device · no cloud, ever · your traffic never leaves your network

Interested in IoT Security?

Read our research on the Mamba-2 architecture powering Vigilo, or learn more about IoT threats on our blog.