Features • Installation • Use • Classifier • Python bridge • Scope
visorbait is a Go CLI and shared signature database for known honeypot fleets. Subscriber model: maintain one signature DB so every recon tool can filter bait responses before promoting them to a "verified unauth" finding. Saves every operator from re-discovering the same fleets one platform sweep at a time.
The inverse of VirusTotal. Instead of "is this thing malware?" the question is "is this thing fake infrastructure pretending to be the platform I am scanning for?" Part of the NuClide Visor* tool lineup (VisorRoam, VisorCAS, VisorLog, VisorGraph, VisorPlus, VisorScuba, VisorAgent).
- Shared honeypot-fleet signature database, embedded in the binary
- AS63949 (Akamai/Linode/Aliyun residential) fleet seeded by default: shared crypt salt
wW0sffoqsk.EM, three reusable bait markers - Four-signal classifier: body hash, IP list, marker-substring co-occurrence, ASN match
- Per-classification confidence (
high,medium,low) with the matched reasons inline - Exit code 0 on honeypot match, 1 on clean. Pipeline-composable
classify(from body or stdin),check(live single-GET URL),seed(add a fleet),list(inspect DB)- User-local DB at
~/.visorbait/fleets.jsonshadows the embedded one. Edit it directly to add ASN ranges, IP lists, hashes - Python bridge (
bridge.py) for scanners that want to call out via subprocess
Requires Go 1.22+.
go install -v github.com/nuclide-research/visorbait@latestOr build from source:
git clone https://github.com/nuclide-research/visorbait ~/visorbait
cd ~/visorbait && go build -o visorbait .$ cat suspicious-response.json | visorbait classify --body-file -
HONEYPOT AS63949 [medium] reasons: markers=3/3
$ visorbait classify --body-file body.txt --asn AS63949 --json
{"fleet":"AS63949","confidence":"high","reasons":["markers=3/3","asn-match"]}Exit code is 0 on match, 1 on no-match. Compose with shell:
if visorbait classify --body-file body.txt > /dev/null; then
echo "skip: honeypot"
fi$ visorbait check --url http://198.51.100.42:12207/api/version
http://198.51.100.42:12207/api/version -> 200 HONEYPOT AS63949 [medium]
reasons: markers=3/3$ visorbait list
visorbait DB version=0.1 updated=2026-06-07 1 fleet(s)
AS63949
Akamai/Linode/Aliyun residential-range honeypot fleet. Emits identical
bait JSON containing the shared crypt salt 'wW0sffoqsk.EM' and a
'VULNERABLE -version' marker across many probe endpoints.
markers=3 body_hashes=0 ips=0 asns=1$ visorbait seed --name FOO-FLEET --body-file captured-bait.txt \
--markers "honeypot-string-1,honeypot-string-2" \
--desc "Found during MLflow sweep, 2026-XX-XX" \
--source "your-handle"
seeded FOO-FLEET (hash=...) into ~/.visorbait/fleets.jsonA body is classified as a honeypot when any of:
| Signal | Confidence |
|---|---|
| Body sha256 exact-matches a known bait hash | high |
| Candidate IP is in a known honeypot IP list | high |
| 2+ marker substrings co-occur in the body | medium |
| Candidate ASN matches a fleet ASN (no body signal) | low |
Falsifiability: a clean body returns null. The exit code lets shell scripts gate on match status.
Scanners written in Python can call visorbait via subprocess:
import subprocess, json
def is_honeypot(body: str, ip: str = "", asn: str = "") -> dict | None:
p = subprocess.run(
["visorbait", "classify", "--body-file", "-",
"--ip", ip, "--asn", asn, "--json"],
input=body, capture_output=True, text=True, timeout=5,
)
if p.returncode == 1:
return None
return json.loads(p.stdout)See bridge.py for the canonical helper.
If you encounter a honeypot fleet in your own sweeps:
- Capture a representative bait body (
curl -sk URL > captured.txt) - Identify the markers: substrings that distinguish the family from legitimate responses (shared salt, fake credential lines, signature error strings, distinctive port distribution)
visorbait seed --name <FLEET-NAME> --body-file captured.txt --markers "..."- Submit a PR with the updated
data/fleets.json
During a NuClide sweep of Ray Dashboards, all seven "open Ray Dashboard" candidates that responded turned out to be honeypots from the AS63949 fleet, the same fleet documented in prior NuClide research. Without a shared filter, every scanner re-learns the fleet from scratch and risks notifying the wrong abuse contact. Codifying honeypot signatures keeps the verified-finding ledger honest.
visorbait classifies HTTP response bodies and live URLs against an embedded honeypot signature DB. check makes one HTTP GET per URL. classify makes zero network calls. seed writes to the user-local DB at ~/.visorbait/fleets.json. No authentication, no POSTs, no exploits. Only point check at hosts you own or have explicit written authorization to assess.
- aimap — AI/ML infrastructure fingerprint scanner
- scanner — active-banner stage between passive discovery and deep enumeration
- VisorLog — finding ledger and ingest pipeline
- VisorCAS — content-addressed false-positive ledger
- VisorGraph — cert-pivot to operator attribution
MIT. Part of the NuClide toolchain. Contact: nuclide-research.com