Skip to content
photodoc1960Public

About

πŸ‰ Passive, read-only home-network sentinel that detects AI-driven adaptive computer worm (Toronto AI worm) signatures. scapy + dpkt + Flask.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

77 Commits

Folders and files

Repository files navigation

πŸ‰ Wyvern β€” Passive AI-Worm Network Sentinel

CI Docker License: MIT Python Tests Coverage

Wyvern is a passive, read-only network monitor and anomaly detector for home and small-office LANs. It watches internal traffic, tracks every device, learns what "normal" looks like, and raises threat-scored alerts when it sees the behavioural signatures of an AI-driven adaptive computer worm β€” the "Toronto AI worm" characterised by Guan et al., AI Agents Enable Adaptive Computer Worms (arXiv:2606.03811).

It is built with scapy (capture), dpkt (analysis) and Flask (dashboard), exactly as a defensive blue-team tool should be.


Where you run it decides what it can detect. Home networks are switched, so a sensor on your main PC sees that PC plus broadcasts β€” and four of the ten detectors cannot fire at all from there. On such a deployment an absence of alerts is not evidence your network is clean. Wyvern reports its own blind spots (curl -s localhost:8787/api/stats | jq .visibility) so you never have to guess. Read Β§2 of the deployment guide before trusting a quiet dashboard.

βš–οΈ What Wyvern will and won't do

Wyvern only observes, alerts, and recommends. By design it will never:

  • modify any device, kill a process, or delete a file;
  • change network settings, firewall rules, or credentials;
  • transmit attack traffic or actively probe hosts.

Every remediation it suggests is a manual action for you to take. The single state-changing operation it exposes is letting you flag a device as "suspicious" for closer monitoring. Run it only on networks you own or are authorised to monitor.


Why this tool exists

In 2026, researchers at the University of Toronto, the Vector Institute, Cambridge and ServiceNow demonstrated the first self-sustaining, AI-driven adaptive computer worm β€” and explicitly named the network signatures it leaves behind as "concrete targets for network monitoring and intrusion detection." The vendor-side safety controls that guard cloud LLMs are structurally irrelevant to a worm that runs an open-weight model on stolen GPUs, and commercial EDR is out of reach for most households. Home and small-office networks β€” flat, unmonitored, full of weak IoT devices β€” are the soft underbelly.

Wyvern exists to give those owners a fighting chance: a free, passive, read-only sentinel that watches for exactly those signatures and tells you, in plain language, what to do. Read the full threat model.

β–Ά 60-second walkthrough: python -m wyvern simulate --web fabricates a full worm outbreak, detects it, and opens the dashboard β€” the fastest way to see what Wyvern does. (A screen-recorded video walkthrough will be linked here.)

The threat, in one paragraph

A traditional worm ships a fixed set of exploits; patch them and it stops. The AI worm instead carries an LLM-backed agent that reasons about each target at runtime β€” it discovers hosts, picks an exploit, gains a foothold, escalates, and replicates, hopping across Linux, Windows and IoT devices. Crucially, the proof-of-concept is not built to hide, so it leaves concrete network signatures (the paper, Β§5): beacon callbacks on non-standard ports, automated SSH-public-key injection, and systematic credential reuse across hosts β€” plus, from its architecture, port/host scanning, lateral movement, LLM inference proxied from non-GPU devices to compromised GPU hosts, and code execution on normally-idle devices (printers, cameras, NAS, ICS sensors). Wyvern detects each of these and fuses them into a single AI-worm verdict.

Quick start

pip install -r requirements.txt        # scapy, dpkt, Flask, flask-cors, PyYAML

# Safe, no-privileges demo: synthesises a full worm outbreak and detects it
python -m wyvern simulate

# Same, but open the live dashboard
python -m wyvern simulate --web        # http://127.0.0.1:8787

# Analyse a capture you already have
python -m wyvern replay capture.pcap --web

# Live monitoring (needs capture privileges)
sudo python -m wyvern monitor -i eth0

Run it permanently β€” Docker, Compose, a hardened systemd unit, a one-line installer, and Prometheus /metrics are documented in docs/DEPLOYMENT.md:

docker build -t wyvern . && docker run -d --net=host \
  --cap-drop=ALL --cap-add=NET_RAW --cap-add=NET_ADMIN \
  -e WYVERN_INTERFACE=eth0 -v wyvern-data:/data wyvern
# ...or:  curl -fsSL https://raw.githubusercontent.com/photodoc1960/wyvern/main/install.sh | sudo bash

The simulate demo prints a report like:

  THREAT LEVEL: CRITICAL
  Critical threat: AI-worm propagation signatures on 2 device(s)
  Likely compromised device: 192.168.1.50

  β€’ 192.168.1.50 (workstation) β€” Critical score=100 [WORM SUSPECT]
      stages: beacon_callback, credential_reuse, discovery, lateral_movement, ssh_key_injection
      β†’ Isolate 192.168.1.50 from the network immediately ...
  β€’ 192.168.1.30 (printer) β€” Critical score=100 [WORM SUSPECT]
      stages: ... idle_device_exec, inference_proxy ...

How detection works

Each detector targets one worm behaviour and tags its alert with a stage. All operate on normalised, immutable events β€” never raw packets β€” so they are pure and fully unit-tested.

Detector Worm behaviour (paper) Fires when…
port_scan network/host discovery a host opens SYNs to >50 ports / 5 min
lateral_movement lateral movement a host contacts >10 internal IPs / hour
credential_spray credential reuse across hosts (Β§5) auth (SSH/SMB/RDP/WinRM) to many hosts, or rapid retries
ssh_key_injection SSH public-key injection (Β§5) SSH fan-out from an idle / never-SSH device
inference_api reasoning proxy (Fig. 1) LLM inference (/v1/chat/completions, vLLM/ollama ports) from a non-GPU device
stream_timing reasoning proxy over encrypted HTTPS a long-lived 443 response stream to a non-GPU device shows the inter-packet token-streaming rhythm β€” a weak corroborating hint, timing metadata only
beacon beacon callbacks on non-standard ports (Β§5) regular callbacks to a non-standard port β€” near-constant cadence alerts on its own, jittered-but-periodic cadence only corroborates
idle_exec self-replication / code exec a printer/router/NAS/camera starts originating connections
dns_anomaly C2 lookups query spikes, NXDOMAIN bursts, DGA-looking domains

stream_timing closes the gap where a worm routes its reasoning proxy over standard HTTPS to an external API β€” port 443, encrypted, so inference_api's port/URL matching sees nothing. Following Alhazbi et al. (2025, IEEE OJ-COMS), it passively measures the inter-packet cadence LLM autoregressive generation leaves on the streamed response (no TLS interception, no payload inspected). It never alerts on its own: the worm_signature correlator only lets the rhythm raise confidence in an inference_api finding for the same device. Defaults are deliberately conservative to avoid false positives on ordinary long-lived HTTPS (video, downloads, websockets). This addresses the "inference_api blind to LLM inference routed over HTTPS" limitation in docs/THREAT_MODEL.md.

beacon grades its jitter test over two bands instead of demanding a metronomic cadence, because adding jitter to a callback interval is the cheapest possible evasion of a single tight cutoff and requires no change to the attacker's design:

  • CoV ≀ beacon_tight_cov (0.20) β€” near-constant callbacks: the classic beacon signature, alerting at full strength as before.
  • CoV ≀ beacon_max_cov (0.50) β€” jittered but still periodic: a deliberately weak, LOW-severity signal (beacon_jittered_confidence, decaying across the band). It contributes a beacon_callback stage to worm_signature but never carries a verdict alone, since moderately-jittered benign polling (update checks, vendor telemetry, keep-alives) also lives in this band.

The wider bound is the empirical autonomous-agent dispersion band: Li (2026, The Moltbook Illusion) separates autonomous (CoV < 0.5) from human-driven (CoV > 1.0) activity across 55,932 agents and notes that agent-framework heartbeats are jittered rather than metronomic, and Luo (2026, Behavioral Grammar) measures CoV 0.31 for an agent actively mimicking benign cadence against 9.79 for benign activity. Both place a jittering beacon far from benign traffic yet outside a 0.20 cutoff. Mo et al. (2026, PFDetector, IEEE Access) independently confirm inter-arrival dispersion as the right primitive at network-flow level. Tighten beacon_max_cov back towards 0.20 if your network's benign periodic traffic proves noisy in this band.

The composite signature

The worm_signature correlator is the centrepiece. No single behaviour proves a worm β€” but one device exhibiting several stages together does. It tracks the distinct stages seen per device within a window and escalates:

  • β‰₯ 2 stages β†’ HIGH "AI-worm propagation" verdict
  • β‰₯ 3 stages β†’ CRITICAL, naming the likely-compromised device

It also encodes the worm's exploit fingerprint from the paper's Table 1 (SMB 445, Docker 2375, Redis 6379, ActiveMQ 61616, Exim 25, Jupyter 8888, PrintNightmare, Modbus 502, Marimo 2718, …) to recognise the worm's actual exploit traffic.

Baseline learning

For each device, Wyvern learns "normal" over a 24-hour window (configurable): the ports it initiates to, internal peers, domains, packet-rate envelope, active hours, and whether it ever makes inference calls or auth fan-outs. Detectors use this to turn raw activity into deviation from this device's own normal and to suppress false positives. Baselines persist across restarts.

Threat assessment & remediation

Alerts are aggregated per device into a Low / Medium / High / Critical level with a 0-100 score, the worm stages observed, and manual remediation steps:

Isolate [device] Β· Change credentials on [targets] Β· Reboot [device] Β· Run a process scan Β· Check [device]'s recent connections in system logs.

Dashboard

--web serves a dark, offline-friendly Flask dashboard (no external CDNs):

  • radial network topology (echoing the paper's propagation tree) β€” radius ∝ threat, pulsing red ring = worm suspect, red edges = worm-service flows;
  • live threat timeline streamed over Server-Sent-Events;
  • device table with OS/vendor/role fingerprints and a one-click "watch / suspicious" toggle;
  • forensic export to JSON or CSV.

CLI reference

wyvern simulate [--web] [--pcap OUT]   # synthetic worm outbreak (safe demo)
wyvern replay PCAP [--web] [--realtime] [--speed N]
wyvern monitor [-i IFACE] [--no-web] [--no-learn]
wyvern report                          # print current assessment from stored data
wyvern export OUT [--format json|csv]  # forensic bundle / alert CSV
wyvern -c config.yaml <command>        # use a config file

Configuration

Copy config.example.yaml, edit, and pass with -c. You can declare known gpu_hosts (to silence inference false-positives), tune every threshold, set internal_cidrs, and configure alerting. Two containment-focused settings are off by default:

  • no_egress_hosts β€” declare isolated/quarantined hosts (IPs or MACs) that must never reach an external network; any egress fires a high-confidence alert.
  • enforce β€” when enabled, high-confidence alerts are POSTed (HMAC-signed) to an external actuator (firewall/egress controller) that can cut the flow. Wyvern stays passive; it only hands off a signed finding β€” it never blocks packets.

Secrets never live in the file β€” the SMTP password and the enforcement signing secret are read only from WYVERN_SMTP_PASSWORD and WYVERN_ENFORCE_SECRET.

Architecture

capture/   scapy live capture + dpkt frame decoding  -> normalised events
models/    immutable Device / Alert / Event / Profile dataclasses
tracking/  device registry + passive OS/role fingerprinting (OUI, TTL, DHCP)
baseline/  24h per-device behavioural learning + persistence
detectors/ 8 stage detectors + the worm_signature correlator
assessment/ threat scoring + manual remediation
storage/   SQLite + append-only JSONL forensic log + exporters
alerting/  desktop notifications + optional email digest (off by default)
engine/    Monitor orchestrator + SSE bus
web/       Flask dashboard (topology, timeline, devices, export)
simulate/  synthetic Toronto-worm trace generator (demo + tests)

The pipeline: capture β†’ decode β†’ track + learn β†’ detect β†’ correlate β†’ assess β†’ store + alert + dashboard. Everything funnels through Monitor.process_event, which is also how replay, the simulator and the tests drive it β€” no live interface or root required for testing.

Testing

make test     # 123 tests
make cov      # coverage report (88% line coverage)

The suite covers decoding (against dpkt-crafted frames), every detector (above/below threshold + negative cases), fingerprinting, baseline learning and persistence, threat scoring, storage, and a full end-to-end integration test that replays the synthetic worm trace and asserts a Critical verdict.

Limitations & honesty

  • Encrypted payloads are opaque; SSH-key-injection and credential detection are behavioural inferences (fan-out patterns), not payload inspection.
  • Passive OS/role fingerprinting is heuristic (OUI + TTL + DHCP + service ports).
  • Thresholds ship with sensible defaults; tune them and declare your gpu_hosts to fit your network and cut false positives.
  • A future, stealth-hardened worm could suppress these signatures β€” the paper notes the PoC deliberately does not. Wyvern targets the signatures that exist.

Documentation

Doc What's in it
Threat model Why this exists, the worm, what Wyvern can/can't see
Deploy in 10 minutes Where to capture, configure, learn, alert
What alerts mean Per-alert playbook + what to do when one fires
Design Architecture, data model, threading, testing
Contributing Dev setup + a guide to writing your own detector
Changelog Release history

Community & contributing

Wyvern is a public, MIT-licensed community blue-team tool β€” detection rules get better with more networks watching.

  • 🟑 Found a false positive? Open a GitHub Discussion so we can tune the defaults for everyone.
  • πŸ›‘οΈ Add your own detection rule β€” the detector architecture is pluggable; CONTRIBUTING.md walks through a complete example end to end.
  • πŸ“¦ Releases are cut roughly monthly, tracking new public threat research (new signatures, fingerprints, tuning). Watch the repo to stay current.

Reference

Jonas Guan, Tom Blanchard, Hanna Foerster, Hengrui Jia, Gabriel Huang, Nicolas Papernot. AI Agents Enable Adaptive Computer Worms. arXiv:2606.03811 (2026). University of Toronto Β· Vector Institute Β· University of Cambridge Β· ServiceNow.

License

MIT β€” see LICENSE. Use responsibly and only on networks you are authorised to monitor.

About

πŸ‰ Passive, read-only home-network sentinel that detects AI-driven adaptive computer worm (Toronto AI worm) signatures. scapy + dpkt + Flask.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages