Skip to contentSkip navigation

Indicator Enrichment

Everything worth knowing about one indicator, on a single card. Give it a domain or an address and it fills in the picture: who registered it, where it's hosted and in which country, its mail and name servers, the network behind it, and a reputation read. The fast way to go from a bare indicator to real context before you decide what to do with it.

The alert

A takedown request names a credential-harvesting page served from a github.com URL and asks you to block the domain. The indicator arrives with no verdict attached and no context beyond the string.

The question

Do I block github.com, and what would tell me I am wrong?

Blocking a domain is a statement about who operates it. The ticket describes one page, the card describes the operator, and the whole risk in this ticket is treating those as the same fact.

What this cannot answer

  • Whether the indicator is malicious. No step in this run reads a threat feed, calls explain() or scores anything. That is a separate run, and this card must not be read as its answer.
  • Whether anything of yours touched it. The run reads the indicator, never your traffic. Direction, timing and which host connected live in your proxy and mail logs.
  • Who owns it, in words a human wrote. REGISTERED_BY returns two ORGANIZATION names for github.comgithub hostmaster and github, — scraped fragments rather than a company. Readable ownership comes from the WHOIS arm, whisper.history.whois, and that arm is dated.
  • How large the web footprint is. The link-count step is written to saturate: for a hub this size both directions return the step's own saturation flag, so the number is a floor and not a count.

What do we know

Measured on 2026-08-09. whisper.identify returns Github, category saas, roles DNS_OPERATOR, MAIL_RECEIVER and ORIGIN_AS, and host_class = multi_tenant_user_content. The domain resolves to four IPv4 addresses in two networks: 140.82.121.3 and 140.82.121.4 in 140.82.121.0/24 on AS36459 — GITHUB, and 20.205.243.166 and 4.228.31.150 on AS8075 — MICROSOFT-CORP-MSN-AS-BLOCK.

Delegation and mail are split the same way. Eight authoritative nameservers, four at NS1 and four at AWS. Six mail exchangers, five Google and one Outlook. Eight SPF_INCLUDE targets — Google, Marketo, Outlook, Salesforce, Zendesk and Mailchimp — plus twelve SPF_IP mechanisms. And 36,131 hostnames hang off the domain by CHILD_OF.

Four arms come back empty for two different reasons, and neither reason is a finding about the domain. The co-hosted, ASN-profile and prefix-profile arms anchor on a label a hostname does not carry, so they return zero rows at HTTP 200 by construction. The nested-SPF arm is empty for a different reason: anchoring on spf.protection.outlook.com shows 104 MAIL_FOR, 11 SPF_IP, 4 NAMESERVER_FOR and no SPF_INCLUDE at all, so the second level is there under a different edge type. Zero rows is never a verdict.

Why

  1. 01Registration identity. REGISTERED_BY / HAS_EMAIL / HAS_PHONE — the ownership anchors that link the domain to siblings. The human registrar is not here (HAS_REGISTRAR is an opaque iana code); it lives in the WHOIS history.
  2. 02WHOIS history. whisper.history.whois carries the readable registrar/registrant/expiry and the nameserver set at each observation — the record the scrubber reads as of any date. Age and change cadence separate a stable asset from a freshly-registered one.
  3. 03Role in the graph. Outbound NAMESERVER_FOR makes a host a nameserver, MAIL_FOR a mail exchanger, an inbound SPF mechanism an authorised sender. Counting each — capped and saturation-flagged — tells the reader what this host DOES for others, not only what it is called.
  4. 04Registrable apex. whisper.psl.tldPlusOne collapses a deep host to its registrable domain using the Public Suffix List — the only correct way to say "a subdomain of X" when the immediate DNS parent is itself a subdomain.
  5. 05Vendor & category (atlas). whisper.identify folds the atlas’s own view — the operating vendor, the category (saas / cloud / …), the derived roles — onto the indicator, so the profile carries an attribution even where no single edge spells it out.
  6. 06Subdomains & parent. The subdomains beneath the host (CHILD_OF, reverse). The count is the substrate aggregate the canvas draws as "+N"; the sample seeds the graph.
  7. 07Nameservers. The authoritative nameservers (NAMESERVER_FOR goes NS→domain). The 13 DNS root servers (a–m.root-servers.net) are filtered — they appear as NAMESERVER_FOR edges on many domains as a resolution-trace artifact (bupa.com.au and stripe.com each carry all 13) but are never a domain’s actual authoritative NS, and they inflate the count. Names only — resolving each NS to a provider 524-times-out when a domain does delegate to root servers.
  8. 08Mail servers. The mail exchangers (MAIL_FOR goes MX→domain). Names only — resolving each MX to a vendor is slow (a big MX resolves to hundreds of IPs) and the exchanger name already names the provider.
  9. 09Resolution. RESOLVES_TO → IPV4 and IPV6 — the addresses the domain actually points at, counted for the lede and grouped into the network tree.
  10. 10SPF authorization chain. The domain’s SPF record one and two levels deep — which hosts, exchangers and IP ranges it authorizes to send mail as it.
  11. 11CNAME aliases. ALIAS_OF both ways — what this host is a canonical name for, and what points at it.
  12. 12Web links. How the wider web references this host and what it references (LINKS_TO) — the web-graph footprint, capped at 50k with a saturation flag so a huge hub reads "50,000+" rather than a wrong exact number.
  13. 13Network & hosting attribution. For the indicator’s own address(es): the announcing prefix and ASN (with name), the registered-prefix owner org, the GeoIP city/country (with lat/lon for the map link), and the CDN/cloud vendor or cloud region — the hosting story as one table.
  14. 14Network topology. The resolved addresses as a tree — each address under its announced prefix, each prefix under the ASN that routes it. Multi-homed hosts (github.com sits on GitHub AND Microsoft) show as parallel ASN subtrees, which a flat table hides.
  15. 15Co-hosted hostnames. For a raw IP: every hostname RESOLVES_TO it — the co-tenants sharing the address. A Fastly anycast address carries thousands; a dedicated host, one.
  16. 16ASN profile. For an ASN seed: its registered name (HAS_NAME), country, registrant org, the count of prefixes it routes (ROUTES) and of ASNs it peers with (BGP_NEIGHBOR).
  17. 17Routed prefixes. For an ASN seed: a sample of the prefixes it originates (ROUTES), as a tree hung off the ASN. Capped at 12 — a large transit AS routes thousands, and the count in the profile carries the true total.
  18. 18Prefix profile. For a CIDR seed: the ASN(s) that route it (ROUTES) with their name, the registrant organization, any cloud region, and how many member IPs it carries.
  19. 19Physical footprint. The data-center facilities (AS_PRESENT_AT) and internet exchanges (IX_MEMBER) the owning network is present at, as a tree per ASN. Sparse for small networks (PeeringDB coverage).

The pivot the score did not suggest

There is no score in this run, so nothing suggests anything. The pivot is one field most readers skim: host_class comes back multi_tenant_user_content, which the identify reference glosses as a platform where anyone can publish.

That string decides the ticket. Registrant, ASNs, nameservers and mail servers all describe GitHub, Inc., and not one of them is the party that put a page on the domain. The 36,131 subdomains are the same argument in another column: a block on the apex is a block on every tenant, and the tenant count is the cost of getting this wrong.

Falsify it

The conclusion rests on the operator today being the operator the card describes, and the card's identity half is an observation with a date on it. The WHOIS arm holds 30 snapshots for github.com, from 2017-06-20 to 2024-09-22 14:40:57, against a create date of 2007-10-09. The registrant field on that newest snapshot is empty. Control could have changed after it and the arm would not know.

Delegation is the independent check. The newest snapshot records eight nameservers; live NAMESERVER_FOR returns eight; compared name by name the two sets are identical, with nothing on either side the other lacks. Two layers observed years apart agree on who answers for the domain. Divergence there is the signal that the identity half is the thing to distrust, and it is the query to run before trusting any of this on a domain you do not already know. The SPF and delegation queries are runnable on DNS and email.

The conclusion

github.com is a multi-tenant platform rather than attacker infrastructure: host_class = multi_tenant_user_content, 36,131 subdomains, addresses in the operator's own AS36459 and in AS8075, and a delegation unchanged since the last WHOIS observation. Block the URL, not the domain, and route the ticket to the platform as hosting abuse.

Nothing here says the reported page is harmless. This run makes no claim about it in either direction, and four things would change the answer:

  • a threat read on the host or its addresses, which this run does not perform and which has to be asked for separately;
  • live delegation diverging from the last WHOIS snapshot, the drift test above;
  • whisper.identify returning a different host_class later — the atlas is a classification that moves, not a constant;
  • evidence that the operator, rather than a tenant, published the page.

Enrichment is context, not a verdict. Read as a verdict, a card's silence about threat becomes an answer it never gave.

What this cost

19 named steps across the WHOIS, DNS, email, BGP, TLS, threat-intel layers. The runner reports what each step returned, row by row, so the evidence and what it took to get it arrive together rather than as one number at the end.

How it uses the graph

Traverses the WHOIS, DNS, email, BGP, TLS, threat-intel layers of the graph, in 19 steps:

How it walks the graph19 steps
01Registration identity

Reading the registrant organization and contacts…

WHOIS
02WHOIS history

Pulling historical WHOIS snapshots…

WHOIS
03Role in the graph

Inferring the host’s own role — nameserver, mail server, SPF sender…

DNS
04Registrable apex

Resolving the registrable apex (eTLD+1)…

DNS
05Vendor & category (atlas)

Attributing the indicator to a known vendor and category…

DNS
06Subdomains & parent

Counting the subdomain family…

DNS
07Nameservers

Listing the authoritative nameservers…

DNS
08Mail servers

Listing the mail exchangers…

email
09Resolution

Resolving the domain to its A / AAAA addresses…

DNS
10SPF authorization chain

Resolving the SPF authorization chain (include / a / mx / ip)…

email
11CNAME aliases

Following CNAME aliases in and out…

DNS
12Web links

Counting inbound / outbound web links…

DNS
13Network & hosting attribution

Attributing each hosting address — prefix, ASN, org, geolocation, CDN/cloud vendor…

BGP
14Network topology

Grouping the resolved addresses by ASN and prefix…

BGP
15Co-hosted hostnames

Reverse-resolving the address to its co-hosted hostnames…

DNS
16ASN profile

Profiling the ASN — name, country, prefixes, peers…

BGP
17Routed prefixes

Sampling the prefixes the ASN routes…

BGP
18Prefix profile

Profiling the prefix — routing ASN, registrant org, cloud region…

BGP
19Physical footprint

Mapping the physical footprint — facilities and internet exchanges…

BGP