Skip to contentSkip navigation

Attack-Surface Mapper

See your organisation the way an attacker does. Give it a domain and it maps the full external footprint — every subdomain, the name and mail servers, who registered it, the third-party services it leans on, and the wider web of sites it connects to — and scores the exposure. The starting point for shrinking what's reachable from the outside.

The alert

An external-exposure review opens on github.com, and the asset's own verdict comes back 46.4 / INFO with the advisory multi-tenant-apex. That is a clean read on one name, sitting on top of 42,465 hostnames that end in .github.com.

The question

Do I sign this footprint off as low risk, and what would tell me I am wrong?

Not "how big is the surface". Size is an input. What changes the answer here is which handful of names point at somebody else's empty slot.

What this cannot answer

  • What is listening on any of it. No port, no banner, no version, no agent on the host. This maps names, addresses, routes and ownership, and never connects to anything. Reachability stays a scanner's job.
  • Whether a dangling name is claimable. The takeover step tests whether the CNAME target holds a resolution edge, not whether the vendor slot is free. Two of the four names it flagged still resolve themselves: communication.github.com to 1 address, info.github.com to 5. What you get is a candidate list.
  • Anything from certificate transparency, on this domain. The CT layer holds 29,861 observations, none of which ends in github.com, and github.com carries no SEEN_IN_CT edge. That is a coverage gap and not an absence of certificates — Coverage.
  • Who operates a delegation target. whisper.identify returns amazon com at band HEURISTIC for both mktomail.com and mktoweb.com. That is where they are hosted, not who runs them.

What do we know

explain() returns the arithmetic along with the number: two counted sources at combined weight 2.40, 2.40 × log₂(2 + 1) = 40.00, then ×1.1 for recency and ×1.05 for age. Read the sources array rather than the sentence. It carries four entries, and the two producing that 2.40 are tweetfeed-month (0.9) and abuse-ch-urlhaus (1.5); the other two are popularity rankings.

The advisory multi-tenant-apex decides how the number should be read, and whisper.identify agrees from a different direction: host class multi_tenant_user_content, roles DNS_OPERATOR, MAIL_RECEIVER and ORIGIN_AS. A listing on an apex that serves other people's content describes a tenant, not the operator.

That verdict covers one name. Underneath it: 36,131 hostnames hanging off the apex by CHILD_OF, 8 nameservers split across two operators, 6 mail exchangers split across two more, 4 serving addresses on 2 networks, and those networks standing in 45 and 1,154 named facilities. A clean read on any of it arrives as a populated row saying so. Zero rows is never a verdict.

Why

  1. 01Asset verdict. Sets the headline threat verdict for the asset before the surface is enumerated, framing how risky the footprint is.
  2. 02Asset class. Reads host-class and roles so a CDN or shared platform reads as structure rather than as an attacker-controlled asset.
  3. 03CT-log subdomains. Reads CT_OBSERVATION names to recover subdomains that issued TLS certs — hosts DNS enumeration alone may miss.
  4. 04Nameservers. Walks NAMESERVER_FOR (excluding root servers) to name the DNS operators the domain delegates to — its control-plane dependency.
  5. 05Subdomain-takeover candidates. Flags subdomains whose ALIAS_OF target no longer resolves — classic subdomain-takeover candidates an attacker can claim.
  6. 06Dangling delegations — true count. A subdomain whose target resolves to no address is the classic takeover setup. This is the flow's most actionable finding, so it is counted over EVERY delegation rather than over the 50 that happen to fit in the sample.
  7. 07CNAME delegation targets. Walks every subdomain's ALIAS_OF target to inventory every CNAME delegation the namespace makes. Most rows are first-party infrastructure aliases (e.g. a domain's own edge/CDN names), not third-party SaaS — the row count overstates the true supply-chain surface, so read this as a delegation inventory, not a SaaS count. `target_ips` is the resolved IPv4 count for the CNAME target; it is not a takeover signal on its own — see subdomain-takeover for the dedicated dangling-CNAME check.
  8. 08SaaS delegation — true count. The delegation list is capped at 50 rows. Counting the rows counts the cap, not the dependencies — so the total is measured separately and never truncated.
  9. 09Mail servers. Walks MAIL_FOR to surface the mail exchangers, part of the email attack surface and a spoofing/relay consideration.
  10. 10SPF authorized senders. Enumerates every SPF mechanism (include/ip/a/mx/exists/redirect) and its target, the full set of hosts allowed to send as the domain.
  11. 11DMARC reporting. Surfaces the DMARC_REPORTS_TO recipients, indicating whether email-authentication reporting is configured and where it lands.
  12. 12Registrar & registrant. Captures the WHOIS ownership trail — registrar, organisation, contact email — the human/legal layer of the surface.
  13. 13Sibling domains (registrant-email pivot). Pivots on the apex's WHOIS registrant email to the other domains it registered (privacy/role addresses excluded, expansion capped per email so a shared address can't explode) — the org-expansion step the single-domain pass skips. HIGH-confidence only when the email is exact and the portfolio is small; corroborate before trusting.
  14. 14Look-alike / typosquat domains. Generates typo/homoglyph variants of the apex and keeps only the REGISTERED ones — the brand/typosquat surface. Most are owned by unrelated parties; score each before alerting.
  15. 15Real origins (de-CDN). Runs whisper.origins to reconstruct the true server addresses behind any CDN — the real infrastructure the edge hides.
  16. 16Resolving IPs. Pins the addresses the domain resolves to, the anchor the serving-network, TLS and threat steps all key off.
  17. 17Serving network (IP → ASN). Resolves IP→prefix→ASN with country and IP threat flags, naming the network that serves the domain and its reputation.
  18. 18Cloud regions. Maps each serving prefix to its CLOUD_REGION (e.g. aws:eu-west-1) — exact data-residency and blast-radius the country-level GeoIP alone misses.
  19. 19Hosting-network reputation. Runs explain() on each serving ASN for its neighborhood reputation — a high-abuse hosting network is a real signal the per-IP threat view misses, even when the domain's own IPs are clean.
  20. 20Physical footprint. Walks AS_PRESENT_AT to the physical facilities the serving ASN occupies — the supply-chain/physical layer no subfinder/Shodan pipeline can reach. Live on prod: a serving ASN can carry from a handful up to well over a thousand facilities (e.g. 45 for AS36459, 1,154 for AS8075) — often the richest layer in the run.
  21. 21TLS fingerprints. Reads EMITS_TLS_FINGERPRINT to capture each address's TLS stack signature, a clustering and posture signal across the surface.
  22. 22Neighborhood threat. Measures how many co-tenants on the domain's own IPs are already threat-listed — how risky the hosting neighbourhood is.
  23. 23Total subdomain count. Reports the true size of the domain's namespace by suffix match (ENDS WITH '.<domain>'), so the surface enumeration is framed against the real total. This is a broader, name-pattern count than the CHILD_OF-edge subdomain count reported elsewhere in the registry (e.g. indicator-enrichment's "Subdomains & parent") — ENDS WITH also catches names with no materialized CHILD_OF edge, so the two totals can legitimately differ.
  24. 24Subdomain hosting map. Ties each subdomain to the IP, prefix and network that host it, showing exactly where the externally exposed surface lives.
  25. 25Hosting diversity. Counts how many subdomains sit on each hosting network, showing whether the footprint is concentrated on one provider or spread across many.
  26. 26Domains hosted on this ASN. When the input is an ASN, enumerates the domains living inside that network's address space so the surface can be mapped network-first.
  27. 27Branded name search. Surfaces every registered hostname that begins with the given string, catching related or brand-impersonating names outside the direct subdomain tree.
  28. 28Inbound web links. Lists the sites that hyperlink to the domain, mapping its inbound web-link graph and who references it.
  29. 29Outbound web links. Shows which external sites the domain links out to, part of its web-facing surface and third-party exposure.
  30. 30Mutual web links. Finds reciprocal hyperlinks between the domain and its peers, which often signal partnerships or affiliations worth investigating.

The pivot the score did not suggest

101 of those children resolve by delegation rather than to an address, and 4 point at a target holding no resolution edge of any kind: communication.github.comcommunication.github.com.cname.campaign.adobe.com, info.github.com157-gqe-382.mktoweb.com, importer2.github.comporter-production-1232719825.us-east-1.elb.amazonaws.com, media.github.comalambic-origin.github.com. Only 7 of the 101 leave the GitHub namespace at all, so the dangling four are most of the outside edge.

Then cross to the mail layer, which no score reads. The domain's SPF authorises 20 mechanisms and one of them is include:mktomail.com. The naming layer holds a Marketo delegation that resolves to nothing while the mail layer still authorises a Marketo host to send as the domain. Neither layer states that on its own, and 46.4 / INFO states none of it.

Falsify it

The finding rests entirely on NOT (target)-[:RESOLVES_TO]->(), so attack that predicate first, because it is label-sensitive. github.github.io, the target of dozens of these delegations, reports zero IPv4 in the inventory step and yet holds five resolution edges: three to nodes labelled HOSTNAME whose names are addresses (185.199.109.153, 185.199.110.153, 185.199.111.153), one PREFIX, one IPV6. Re-ask the four flagged targets for a resolution of any label. All four still return zero, and that is what keeps them on the list.

Then score the networks instead of the name. explain() on the two serving ASNs returns AS36459 (GitHub) at reputation 72.0 and AS8075 (Microsoft) at 75.0, both REPUTABLE, and the co-tenancy read finds one threat-listed hostname sharing an address, 141941.xyz on 20.205.243.166. The hosting layer does not argue with the apex verdict, which is exactly why the apex verdict was never the answer.

Runnable forms of both queries are on Attack-surface recon and DNS and email.

The conclusion

github.com is a low-risk name on two well-reputed networks with four delegations pointing at an unresolvable target. Two of them, importer2.github.com and media.github.com, resolve to nothing themselves and are the ones worth a ticket today; the other two still answer, so they are watch items. The apex verdict is correct and beside the point, because it scored the one name that was already fine.

Four things would overturn that, and each is a query rather than an opinion:

  • any of the four targets gaining a resolution edge, which means the delegation is live and there is nothing to claim;
  • the vendor slot turning out to be held, which this workflow never checks and a registrar or a vendor console answers;
  • include:mktomail.com leaving the SPF record, which removes the cross-layer half of the finding;
  • a service found listening on any of the 36,131 children, which nothing above can see.

Measured 2026-08-09 against github.com, the workflow's own default input.

What this cost

30 named steps across the DNS, email, BGP, WHOIS, threat-intel, TLS, GeoIP, physical 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 DNS, email, BGP, WHOIS, threat-intel, TLS, GeoIP, physical layers of the graph, in 30 steps:

How it walks the graph30 steps
01Asset verdict

Scoring the domain with explain()…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
02Asset class

Identifying the domain's vendor and class…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
03CT-log subdomains

Mining CT logs for certificate-named subdomains…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
04Nameservers

Finding the domain's nameservers…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
05Subdomain-takeover candidates

Finding CNAMEs pointing at dangling targets…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
06Dangling delegations — true count

How many subdomains point at a CNAME target that resolves to nothing at all.

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
07CNAME delegation targets

Inventorying every CNAME (ALIAS_OF) delegation target the namespace makes…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
08SaaS delegation — true count

How many subdomains delegate to a third-party platform, in total.

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
09Mail servers

Finding the domain's mail servers…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
10SPF authorized senders

Reading the domain's SPF-authorised senders…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
11DMARC reporting

Reading the domain's DMARC report recipients…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
12Registrar & registrant

Reading registrar, registrant and email…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
13Sibling domains (registrant-email pivot)

Pivoting on the registrant email to co-registered domains…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
14Look-alike / typosquat domains

Enumerating registered look-alike domains…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
15Real origins (de-CDN)

De-CDN'ing to the real origin IPs…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
16Resolving IPs

Resolving the apex to its IPs…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
17Serving network (IP → ASN)

Tracing serving IPs to ASN, country and threat…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
18Cloud regions

Mapping serving prefixes to their cloud region…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
19Hosting-network reputation

Assessing each serving ASN's reputation with explain()…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
20Physical footprint

Tracing serving ASNs to the datacenters they sit in…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
21TLS fingerprints

Collecting the serving IPs' TLS fingerprints…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
22Neighborhood threat

Counting flagged domains on the serving IPs…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
23Total subdomain count

Total subdomain count…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
24Subdomain hosting map

Subdomain hosting map…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
25Hosting diversity

Hosting diversity…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
26Domains hosted on this ASN

Domains hosted on this ASN…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
27Branded name search

Branded name search…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
28Inbound web links

Inbound web links…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
29Outbound web links

Outbound web links…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical
30Mutual web links

Mutual web links…

DNSemailBGPWHOISthreat-intelTLSGeoIPphysical