Threat Investigation
The deep-dive you run when something looks bad and you need the full story. Give it one indicator and it works outward across its whole footprint — the related domains, the real servers behind any CDN, the neighbouring infrastructure — and checks each piece for known abuse. You get one coherent read on how dangerous it is and why, with safe next steps to pivot on. Reach for it when a quick check says 'look closer.'
How it uses the graph
Traverses the threat-intel, DNS, BGP, WHOIS, historical layers of the graph, in 69 steps:
Reading the live capability map (which threat layers this server carries)…
Reading the indicator through explain()…
Asking whisper.assess for a coverage-qualified suspicion band…
Listing the actual threat feeds that name the indicator (popularity & ad/tracking lists excluded)…
Checking popularity/trust & ad-tracking lists (context, NOT threat feeds)…
Scoring each pasted value with explain()…
Assessing the whole list with whisper.assess…
Detecting the indicator type to seed the fan-out…
Discovering the real origin behind any CDN…
Deriving the apex and enumerating its subdomains (the whole domain family)…
Classifying the seed address — CDN/cloud vendor, anycast prefix, co-tenant degree, egress/abuse flags…
Expanding round-1 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-1 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-1 ASNs announce…
Reading the IPs inside round-1 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-2 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-2 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-2 ASNs announce…
Reading the IPs inside round-2 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-3 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-3 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-3 ASNs announce…
Reading the IPs inside round-3 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-4 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-4 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-4 ASNs announce…
Reading the IPs inside round-4 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-5 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-5 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-5 ASNs announce…
Reading the IPs inside round-5 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-6 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-6 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-6 ASNs announce…
Reading the IPs inside round-6 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-7 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-7 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-7 ASNs announce…
Reading the IPs inside round-7 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-8 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-8 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-8 ASNs announce…
Reading the IPs inside round-8 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-9 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-9 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-9 ASNs announce…
Reading the IPs inside round-9 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Expanding round-10 hostnames to their IPs, subdomains, parent domain and the sites they link to…
Reverse-resolving round-10 IPs to their hosts and prefix (CDN co-tenancy suppressed)…
Listing the prefixes round-10 ASNs announce…
Reading the IPs inside round-10 prefixes and the ASN that routes them (large-provider blocks suppressed)…
Threat-checking every discovered node — feeds, threat signals and flags (C2 / malware / phishing / Tor / proxy / botnet / scanner / spam)…
Tallying the fan-out…
Checking in-scope prefixes for MOAS / route-origin conflicts…
Counting authorizing ROAs per in-scope network (roa_n = 0 → unverified origin)…
Grouping in-scope hosts that resolve to the same IP…
Grouping in-scope domains served by the same nameserver…
Grouping in-scope domains sharing a registrant email…
Counting in-scope threat-listed IPs per SMALL network (toxic-neighbourhood density)…
Rolling up in-scope nodes by egress / anonymizer class (Tor / VPN / proxy / exfil)…
Finding SMALL prefixes where clean-looking IPs sit alongside threat-listed ones (provider blocks excluded)…
Expanding abuse infrastructure harder — threat neighbours of in-scope C2/threat IPs…
Reading the registrar and registrant contacts…
Pulling historical WHOIS snapshots…
Classifying the host — vendor, category and roles…
Listing vector — feeds, weights & recency…
Threat-class vector — phishing / malware / C2 / spam / anon…
Network-neighborhood vector — toxic density on the hosting prefix…
ASN composite vector — threatDensity / graphMetrics / historical / prefixAge…
Why each step runs
- 01Capability preflight. db.relationshipTypes()/db.labels() are quota-exempt; the flags they yield gate the §9 aggregate pass so a layer absent on this server degrades to a coverage note instead of erroring — the same instructions enrich automatically as layers ship.
- 02Threat-engine reading. explain() auto-detects the indicator type and returns the graph's own score, level, factors and cited sources — the first-hand observation everything else is read alongside.
- 03Suspicion assessment. whisper.assess returns a label + band with an explicit coverage qualifier, so a clean read is reported as "known-clean" vs "no-data" rather than silently implying safety.
- 04Threat-feed listings. Names the LISTED_IN feeds and their categories, EXCLUDING popularity/trust lists (Tranco, Cloudflare Radar — a legitimacy signal, not a threat) and ad/tracking blocklists, so the threat-feed count is real.
- 05Popularity / trust context. Tranco / Cloudflare Radar top-1M membership is a popularity/legitimacy signal, and ad/tracking blocklists merely flag ad-serving domains — neither is a security threat, so they are reported as CONTEXT, never as a threat hit. (Popularity VDP — returns nothing until the layer ships to prod, then activates automatically.)
- 06Batch threat readings. Returns one sourced reading per pasted indicator, so an analyst can triage a whole list in a single pass.
- 07Batch suspicion bands. whisper.assess takes the list directly and returns a coverage-qualified band per host, complementing the batch explain() scores.
- 08What this is. The indicator is routed into the right typed frontier (hostname / IP / ASN / prefix) so round one expands it by the correct rules.
- 09De-CDN origins. whisper.origins peels back CDN/proxy fronting to the likely origin IP(s) and network; those origin IPs are seeded into the IP frontier so the fan-out expands the infrastructure that actually serves the content — not the CDN front-end (whose co-tenants are suppressed).
- 10Subdomain family. A domain investigation should analyse the whole subdomain family — deriving the registrable apex (via PSL) means investigating www.X still enumerates X and every sibling subdomain (admin, dash, api, …), each threat-checked, rather than only the children of the exact host submitted.
- 11Infrastructure classification. Reads vendor delegation, the prefix anycast flag (ip.isAnycast is null — read it from the prefix), co-tenant degree and the node's own egress/abuse flags to tag the infra class (§15.7). A threat/egress flag on a SHARED address (CDN vendor / anycast / high-degree) is a bad co-tenant, not the seed's own infra, so it does NOT flip a fronted domain to BULLETPROOF/TOR — shared seeds suppress co-tenant fan-out and lean on de-CDN origins; only a DEDICATED abuse address expands HARDER.
- 12Round 1: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 13Round 1: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 14Round 1: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 15Round 1: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 16Round 2: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 17Round 2: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 18Round 2: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 19Round 2: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 20Round 3: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 21Round 3: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 22Round 3: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 23Round 3: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 24Round 4: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 25Round 4: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 26Round 4: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 27Round 4: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 28Round 5: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 29Round 5: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 30Round 5: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 31Round 5: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 32Round 6: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 33Round 6: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 34Round 6: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 35Round 6: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 36Round 7: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 37Round 7: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 38Round 7: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 39Round 7: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 40Round 8: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 41Round 8: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 42Round 8: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 43Round 8: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 44Round 9: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 45Round 9: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 46Round 9: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 47Round 9: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 48Round 10: hostnames → IPs & subdomains. Each hostname fans out to the IP(s) it resolves to (its hosting), the subdomains beneath it, its parent domain (up to the apex, never the TLD), and the hostnames it links out to — all become nodes the next round expands.
- 49Round 10: IPs → hosts & prefix. Each IP fans out to the hostnames it serves and the prefix that announces it. CDN/cloud-delegated addresses host millions of unrelated tenants, so their co-tenant promotion is suppressed (DELEGATED_TO a VENDOR) — the de-CDN origins pivot carries the meaningful neighbours instead.
- 50Round 10: ASNs → prefixes. Each owning network fans out to the prefixes it announces — the address space that depends on it, and the next nodes to expand to their IPs.
- 51Round 10: prefixes → IPs & ASN. Each prefix fans out to the IPs it contains and the ASN that routes it — but a prefix on a large provider network (anycast / many-prefix ASN / CDN vendor) holds hundreds of unrelated tenants, so its IP expansion is suppressed (the toxic-neighbourhood poison pivot); a small dedicated prefix still reaches its sibling hosts.
- 52Threat sweep across the fan-out. Every hostname, IP, prefix and ASN reached is read for its own threat listing & level, LISTED_IN feeds, HAS_SIGNAL threat signals and per-node flags — so a compromised node anywhere in the neighbourhood surfaces, not just the indicator itself.
- 53Fan-out recap. A count of everything reached — hostnames, IPs, prefixes and networks — the strategy expands each branch as far as its signal warrants, up to the internal ceiling.
- 54MOAS route conflicts. A prefix flagged isMoas with several CONFLICTS_WITH origins is announced by competing ASNs — a route-hijack or multi-homing signal (validated: 216.168.228.0/24 → isMoas + 16 conflicts).
- 55RPKI origin authorization. ROAs are typed to PREFIX and routing produces ANNOUNCED_PREFIX, so bridge through the ASN. roa_n = 0 is a CANDIDATE unverified origin (labelled "unverified", not "invalid") — corroborate per (prefix, origin).
- 56Shared-IP clusters. Hosts sharing one IP are a co-hosting cluster (size ≥ 2, ≤ 200 — a mapping to hundreds is shared hosting, not a cluster).
- 57Shared-nameserver clusters. Domains behind one nameserver (NAMESERVER_FOR goes ns→domain) form a shared-NS cluster — a bulk-registration pivot (a boutique NS, not a mega-managed-DNS one with 137k siblings).
- 58Shared-registrant clusters. Domains registered by one email are a campaign cluster — the highest-value shared-infra pivot (exclude privacy-proxy contacts that map to countless domains).
- 59Threat density by network. A SMALL network hosting many threat-listed IPs is a toxic neighbourhood even where individual IPs look clean. Large providers (many-prefix ASNs) are excluded — a threat IP on AWS/DigitalOcean/Cloudflare is an unrelated tenant, not a signal about the seed (inner LIMIT 200 bounds the scan under the timeout).
- 60Egress / anonymizer concentration. A concentration of egress/anonymizer nodes in one class is a stronger signal than any single hit (per-node flags; no assess round-trip needed).
- 61Clean-in-toxic contradictions. A clean IP inside a prefix that also carries threat-listed IPs is not "safe" — no-data at the IP granularity inside a hostile neighbourhood is a contradiction worth surfacing (WHOIS/GeoIP mismatch is computed in the handler from whois + origins).
- 62Abuse-infra neighbours. Co-tenants of a bulletproof/abuse address are likely related bad actors (the opposite of CDN noise) — the highest-value branch to expand, bounded to threat-flagged neighbours in the same prefix. Fires on the aggregate pass or whenever the seed classified as bulletproof/abuse.
- 63WHOIS ownership. Registrar, registrant org and contact email are the ownership anchors that link this domain to siblings and to known actors.
- 64WHOIS history. Registration age and the history of registrar/registrant/nameserver changes separate stable assets from freshly-registered, disposable ones.
- 65Vendor / host identity. whisper.identify maps the host to a canonical vendor, category and role set (CDN, mail receiver, DNS operator…), so known-good infrastructure is recognised rather than re-investigated.
- 66Listing vector — feeds, weights & recency. Breaks the base score into its direct-listing evidence: every feed that listed the indicator, the weight it contributed, and when it was first and last seen — the sourced, dated rows that justify the verdict to an analyst or auditor.
- 67Threat-class vector — phishing / malware / C2 / spam / anon. Decomposes the indicator's own verdict into named abuse types — phishing, malware, C2, spam, botnet, DGA, brute-force, scanner, anonymizer/Tor — so the score reads as a class breakdown rather than one opaque number.
- 68Network-neighborhood vector — toxic density on the hosting prefix. The guilt-by-hosting signal: how many threat-listed IPs share the announced prefix behind the indicator. An IP anchors directly on its prefix; a domain resolves to its serving IPs first, so a clean indicator sitting in a bad block still surfaces the neighbourhood risk.
- 69ASN composite vector — threatDensity / graphMetrics / historical / prefixAge. Exposes the engine's structured reputation breakdown for the owning network — threat-density, graph-metrics, historical-behaviour and prefix-age sub-scores. Scores the ASN directly when the indicator is one, otherwise resolves the owning ASN behind an IP or domain.