Skip to main content
The probe phase is Vigolium’s native host sweep: one request per target, passive technology fingerprinting and attack-surface scoring, and nothing else. No content discovery, no fuzzing, no crawling. It exists because run discover spends its whole budget on the first handful of hosts. A sweep has the opposite shape - you want a shallow answer about thousands of hosts, so you can decide which few deserve a real scan.
Aliases: probing, httpx, alive, sweep. vigolium run httpx -T hosts.txt and vigolium scan -T hosts.txt --only probe are the same command.

When to use it

The intended flow is probe first, rank by surface_score, then point a full scan at the top of that list.

Quick start

-T/--target-file reads its file as one target URL per line. A spec or an export goes through -i/--input instead - see Input Modes.

Output

stdout is pure JSONL; human progress goes to stderr. Pipe with 2>/dev/null, or add --silent for a fully quiet run. One object per record:
Field names match httpx’s (a / aaaa / cname / tls), so a consumer written against that output reads these unmodified.
A sweep produces records, not findings. A 0 findings summary is the expected result - the answer lives in the record’s surface_score, technology, and status_code columns.

Probe flags

--tls-probe and --record-redirect-chain on a run that has no probe phase warn that they are inert rather than silently doing nothing.

--tls-probe

Reports the negotiated TLS version and cipher plus the leaf certificate - subject/CN, SANs, issuer, validity window, serial, and MD5/SHA-1/SHA-256 fingerprints - under an httpx-shaped tls key.
Validation is deliberately off. An expired or self-signed certificate is the result you came for, so the handshake records it instead of refusing it.

--redirect-mode

Replaces the old FollowRedirects / FollowHostRedirects bool pair, which had no spelling for what a host sweep actually needs. same-apex fails closed to exact-host equality when either side has no registrable domain.

--record-redirect-chain

Each followed hop becomes its own http_records row, chained through the existing parent_uuid column. a.example (301) -> www.a.example (302) -> the 200 that answered is three rows, not one. A 3xx also stores its Location header verbatim in response_location, so traffic --tree prints the destination (↪ https://…) off the row instead of hydrating response bytes.

Probe-only defaults

A standalone probe run - vigolium run probe, vigolium scan --only probe, or REST {"only": "probe"} - flips its own defaults. Each one yields to an explicit flag, and none of them apply when the probe rides along inside a wider scan. Reactive back-off after a confirmed WAF block is untouched. To restore either default: --no-waf-pacing=false re-enables proactive pacing, --export-only http,findings puts the findings back in the envelope.

Attack-surface scoring

Every probed record gets a surface_score: 0-100, the percentage of a 17-signal set present on that exchange. It is written by the surface-scoring passive module and is deterministic - the same record scores the same on every scan. Every signal is readable from a single unauthenticated GET, which is what a host sweep has to rank on:
  • An advertised authentication boundary, a session, a login surface
  • A non-standard port
  • A dynamic origin (versus edge-cached)
  • Permissive CORS
  • Leaked internals - source maps, directory listings, dev-server banners, debug headers
  • API markers and the input surface the response advertises
A bare sweep can’t score everything. run probe only ever observes a GET with no session, so signals that need a request you shaped - input carried, a mutating method, an upload, a session in hand - cannot fire. Probe scores top out well under 100. Compare them against each other, not against scores from a full scan.
surface_score is not risk_score. See --min-surface vs --min-risk for the full comparison - the short version is that surface is absolute and reproducible, while risk is a rank within whichever batch the record was flushed alongside.

Reading a sweep back

Probe rows are labelled source: probe, so a sweep is separable from a real scan in the same project:
Host facts are output-only, not stored. a, aaaa, cname, and tls are reported inline in the probe’s own --json stream, but the schema keeps only the single ip column - a sweep writes several records per host, and storing the full answer per row would be many copies of one identical, TTL-stale blob. Reading the database back later shows ip alone; re-run the probe if you need the rest.surface_score, technology, response_time_ms, response_location, and parent_uuid are stored and queryable.