{"id":49504291,"url":"https://github.com/jmeltz/deadband","last_synced_at":"2026-05-01T14:01:22.150Z","repository":{"id":348402537,"uuid":"1197898767","full_name":"jmeltz/deadband","owner":"jmeltz","description":"Free, offline ICS/OT firmware vulnerability matching against 3,600+ CISA advisories","archived":false,"fork":false,"pushed_at":"2026-05-01T13:13:52.000Z","size":821,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-01T13:26:26.378Z","etag":null,"topics":["cps-security","cyber-physical-systems","industrial-control-systems","ot-security"],"latest_commit_sha":null,"homepage":"https://deadband.org","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jmeltz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-01T01:18:39.000Z","updated_at":"2026-05-01T13:14:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jmeltz/deadband","commit_stats":null,"previous_names":["jmeltz/deadband"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/jmeltz/deadband","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmeltz%2Fdeadband","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmeltz%2Fdeadband/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmeltz%2Fdeadband/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmeltz%2Fdeadband/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmeltz","download_url":"https://codeload.github.com/jmeltz/deadband/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmeltz%2Fdeadband/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32499691,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cps-security","cyber-physical-systems","industrial-control-systems","ot-security"],"created_at":"2026-05-01T14:01:19.053Z","updated_at":"2026-05-01T14:01:22.135Z","avatar_url":"https://github.com/jmeltz.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# deadband\n\nRead-only OT vulnerability scanner. Discovers industrial controllers, fingerprints firmware, matches against the [CISA ICS Advisory](https://www.cisa.gov/news-events/ics-advisories) feed (3,600+ advisories), and produces a self-contained HTML report.\n\nNo agent. No cloud. No telemetry. No writes to OT devices.\n\n## Install\n\n```bash\nmake deadband           # CLI only\nmake deadband-web       # CLI + embedded web UI\n```\n\n## Quick Start\n\n```bash\n# Refresh the advisory database (one-time)\nbin/deadband --update\n\n# Scan a network — auto runs every protocol concurrently\nbin/deadband --cidr 10.0.1.0/24\n\n# Single-protocol scan\nbin/deadband --cidr 10.0.1.0/24 --mode haas\n\n# Check a pre-collected inventory\nbin/deadband -i devices.csv --min-cvss 7.0 --prioritize\n\n# Export an HTML report for a customer engagement\nbin/deadband -i devices.csv \\\n  --site-name \"Acme Manufacturing\" \\\n  --out-format html -o acme.html\n\n# CI gate: exit 1 if anything HIGH-confidence matches\nbin/deadband -i devices.csv --min-confidence high\n```\n\n## Discovery\n\nEvery probe is read-only by construction. None require authentication. Tests assert no unexpected bytes hit the wire.\n\n| Mode | Port | Vendors |\n|---|---|---|\n| `cip` | UDP 44818 | Rockwell Automation |\n| `s7` | TCP 102 | Siemens (S7-300/400/1200/1500) |\n| `modbus` | TCP 502 | Schneider, ABB, Delta, Moxa, Phoenix Contact, WAGO, Emerson, Yokogawa, Eaton |\n| `melsec` | TCP 5007 | Mitsubishi (iQ-R/F, Q, L, FX5) |\n| `fins` | UDP 9600 | Omron (CJ, CP, CS, NJ, NX) |\n| `srtp` | TCP 18245 | Emerson / GE (PACSystems, Series 90, VersaMax) |\n| `opcua` | TCP 4840 | cross-vendor industrial servers |\n| `haas` | TCP 5051 | Haas Automation NGC controllers |\n| `fanuc` | TCP 21 | Fanuc CNC + R-30iB robots (FTP banner) |\n\n`--mode auto` (default) runs all of the above concurrently and merges results.\n\n**BACnet/IP** lives behind a build tag — `go build -tags bacnet ./cmd/deadband` — and is excluded from default builds.\n\n**Fanuc FOCAS2** (TCP/8193) is stubbed pending live-device access; the FTP banner-grab handles common fingerprinting today.\n\n## HTML Report\n\n`--out-format html` produces a single-file report with no external resources. Everything is inline — open it on an air-gapped laptop, print it from a browser, attach it to an email.\n\nContents:\n\n- Cover with site name (`--site-name`), generation timestamp, advisory DB version\n- Executive summary (vulnerable / potential / OK / no-match) with a stacked bar\n- Top risk items sorted by KEV + CVSS + EPSS\n- Device assessment table with status badges\n- Per-device vulnerability detail with CVEs, KEV/ransomware flags, remediation links\n- Optional compliance mapping with `--compliance iec62443,nist-csf,nerc-cip`\n- Print stylesheet — browser Print → Save as PDF gives a clean light-mode export\n\nA regression test (`pkg/output/html_test.go`) asserts the rendered template carries zero external references.\n\n## Web UI\n\n```bash\nbin/deadband serve         # API + UI on :8484\n```\n\nFour panes:\n\n- **Dashboard** — exposure summary, site risk overview, top findings, Export Report button\n- **Scan** — kick off discovery against a CIDR with any mode\n- **Report** — sidebar action that downloads the HTML report\n- **Settings** — advisory DB status + Update Now\n\nDevelopment with hot reload:\n\n```bash\ngo run ./cmd/deadband serve   # API on :8484\ncd web \u0026\u0026 npm run dev          # Frontend with /api/* proxy\n```\n\n## Advisory Database\n\n`--update` resolves its source like this:\n\n| `--source` value | Behavior |\n|---|---|\n| empty (default) | Try the deadband-hosted snapshot, fall back to per-file CSAF |\n| `github` | Force per-file fetch from `cisagov/CSAF` |\n| `https://...` | Specific snapshot URL with `.sha256` verification |\n| `/local/path/` | Local CSAF mirror (full air-gap) |\n\n```bash\nbin/deadband --update                                # default: snapshot + fallback\nbin/deadband --update --source github                # force per-file\nbin/deadband --update --source ./local-csaf-mirror   # air-gapped\n```\n\nFor air-gap, copy the resulting database between hosts:\n\n```bash\nscp ~/.deadband/advisories.json analyst@isolated:~/.deadband/\n```\n\n## Input Formats\n\n**CSV**:\n```\nScanned IP,Device Name,Ethernet Address (MAC),IP Address,Product Revision,Serial Number,Status,Uptime\n172.16.12.21,1756-EN2T/D,5C:88:16:C4:26:3C,172.16.12.21,11.002,D060925B,Run,\"206 days, 03h:12m:20s\"\n```\n\n**JSON**:\n```json\n[{\"scanned_ip\":\"172.16.12.21\",\"device_name\":\"1756-EN2T/D\",\"product_revision\":\"11.002\"}]\n```\n\n## Flags\n\n### Discovery\n| Flag | Default | Description |\n|---|---|---|\n| `--cidr` | | CIDR range |\n| `--mode` | `auto` | See discovery table above |\n| `--timeout` | `2s` | TCP/UDP scan timeout |\n| `--http-timeout` | `5s` | HTTP scrape timeout |\n| `--concurrency` | `50` | Concurrent workers |\n\n### Check\n| Flag | Default | Description |\n|---|---|---|\n| `--inventory` / `-i` | | Inventory file |\n| `--format` | auto-detect | `csv`, `json`, `flat` |\n| `--db` | `~/.deadband/advisories.json` | Advisory database |\n| `--output` / `-o` | stdout | Output path |\n| `--out-format` | `text` | `text`, `csv`, `json`, `html`, `sarif` |\n| `--site-name` | | Site label for the HTML report cover |\n| `--min-confidence` | `low` | `low`, `medium`, `high` |\n| `--min-cvss` | `0.0` | Minimum CVSS v3 score |\n| `--vendor` | | Filter to a specific vendor |\n| `--prioritize` | `false` | Sort by risk score (KEV + EPSS + CVSS) |\n| `--compliance` | | `iec62443,nist-csf,nerc-cip,all` |\n\n### Update\n| Flag | Default | Description |\n|---|---|---|\n| `--update` | | Refresh advisory database |\n| `--source` | | See updater table above |\n| `--since` | | Only fetch advisories after `YYYY-MM-DD` |\n| `--skip-enrichment` | `false` | Skip KEV/EPSS fetch |\n\n### Server\n| Flag | Default | Description |\n|---|---|---|\n| `--serve` | `false` | Start the web UI + API |\n| `--addr` | `:8484` | Listen address |\n\n## Exit Codes\n\n| Code | Meaning |\n|---|---|\n| `0` | No vulnerabilities matched |\n| `1` | Matches found |\n| `2` | Error (missing DB, bad input, parse failure) |\n\n## Confidence Levels\n\n| Level | Meaning |\n|---|---|\n| HIGH | Vendor + model exact match, firmware in advisory range (clean semver) |\n| MEDIUM | Vendor + model match, version comparison ambiguous |\n| LOW | Vendor match only, model is partial / wildcard |\n\n## Safety\n\n- Read-only probes — only documented identification reads or banner grabs\n- No runtime internet calls — advisory data is fetched ahead of time via `--update`\n- No authentication, no credential storage, no writes\n- Safety banner on every entry point\n- Public CISA data only (TLP:WHITE)\n\n## Project Structure\n\n```\ncmd/deadband/main.go       CLI entrypoint\npkg/advisory/              Advisory DB load/save\npkg/asset/                 Asset inventory + vulnerability state\npkg/cli/banner.go          Safety banner\npkg/discover/              Active discovery (CIP, S7, Modbus, MELSEC, FINS, SRTP, OPC UA, Haas, Fanuc)\npkg/inventory/             CSV / JSON / flat parsing\npkg/matcher/               Vendor, model, version matching\npkg/output/                Text, CSV, JSON, HTML, SARIF writers\npkg/server/                HTTP API + report export\npkg/updater/               CISA CSAF fetch (snapshot + per-file)\nweb/                       Next.js frontend\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmeltz%2Fdeadband","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmeltz%2Fdeadband","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmeltz%2Fdeadband/lists"}