Skip to content

vhost_brute

vhost_brute is a native Go hxEASM discovery plugin for finding HTTP virtual hosts exposed by existing WebApp endpoints.

It is a normal hxEASM plugin wrapper:

  • no external scanner binary;
  • no shell execution;
  • no database access;
  • no Asset service access;
  • no graph service access;
  • no worker-specific orchestration.

The worker passes the existing PluginInput.Scope to the plugin and processes the returned PluginResult through the normal Asset pipeline.

Input

The plugin accepts webapp targets only.

Examples:

http://example.com
https://portal.example.com
https://89.208.192.24
https://89.208.192.24:8443

It ignores domain, subdomain, ip, cidr, ip_range, service, and other scope types as direct targets.

Base domain selection

For DNS-hosted WebApps, the plugin derives the registrable domain/eTLD+1 from the WebApp hostname using public-suffix semantics:

https://portal.example.com    -> example.com
https://portal.example.co.uk  -> example.co.uk

For IP-hosted WebApps, the plugin uses all current domain entries present in the existing runtime PluginInput.Scope. This is the current scan/runtime scope, not a separate initial-scope field. It intentionally ignores subdomain, ip, cidr, ip_range, webapp, and service entries when selecting base domains for an IP-hosted WebApp.

Wordlist

The default wordlist is bundled into the worker image:

/app/wordlists/vhost/subdomains-top1million-20000.txt

Source:

  • Project: SecLists
  • Repository: https://github.com/danielmiessler/SecLists
  • Upstream file: Discovery/DNS/subdomains-top1million-20000.txt
  • Pinned revision: 2e3e92569043d24297ca6c35070078e5cf41651e
  • License: MIT

Operators may override the path with the wordlist_path plugin setting.

HTTP and HTTPS behavior

The physical network destination is always the original WebApp endpoint. The candidate hostname is used for virtual-host selection.

For HTTP:

TCP destination: original WebApp host:port
HTTP Host:      candidate hostname

For HTTPS:

TCP destination: original WebApp host:port
HTTP Host:      candidate hostname
TLS SNI:        candidate hostname

Candidate DNS resolution is not required and is not used to choose the physical destination. A confirmed virtual host can therefore be emitted as a Subdomain Asset even if the candidate name does not resolve in public DNS.

TLS certificate verification is skipped by default for this plugin because VHost probing commonly targets IP endpoints or shared endpoints whose certificates do not match the physical host. The setting is tls_skip_verify=true by default and can be changed through generic plugin settings.

Detection

The plugin does not treat HTTP 200 alone as a discovery.

For each base domain, it first sends random baseline requests such as:

hxvhost-<random>.example.com

All baseline responses must have the same bounded fingerprint. If the baseline is unstable, that base domain is skipped conservatively.

Candidate responses are compared against the stable baseline using:

  • HTTP status code;
  • bounded body length;
  • bounded body SHA-256 hash;
  • HTML title;
  • redirect Location;
  • body truncation flag.

The plugin reads at most 64 KiB of response body for fingerprinting. It does not store response bodies in metadata.

Redirect handling is conservative: if both the baseline and candidate are redirects with the same status and no stronger title signal, V1 does not confirm the candidate based on redirect differences alone.

Output

Confirmed VHosts are emitted as subdomain Assets only.

The plugin does not create WebApp, Domain, IP, Service, vulnerability, file, or path Assets.

Metadata includes bounded evidence such as:

  • parent_domain;
  • discovered_from_webapp;
  • target_scheme;
  • target_host;
  • target_port;
  • http_status;
  • title;
  • location;
  • response_hash;
  • response_length;
  • source = vhost_brute.

Graph relations are not created by the plugin. Existing generic graph processing may create the normal parent Domain relation for the returned Subdomain based on parent_domain.

Settings

Setting Default Description
wordlist_path /app/wordlists/vhost/subdomains-top1million-20000.txt Local worker path to the prefix wordlist
concurrency 10 Maximum concurrent probes inside the plugin
rate_limit 25 Maximum probe requests per second; 0 disables plugin-local rate limiting
request_timeout 5 Per-request timeout in seconds
baseline_requests 3 Random baseline probes per base domain
tls_skip_verify true Skip TLS certificate verification while preserving candidate SNI

vhost_brute is registered for explicit/custom profile usage, but it is not added to built-in scan profiles by default.