Vulnerability & Attack Surface Management

A live look-alike of your login page is a finding, and it has no CVE

Your scanner enumerates hosts you own and reports what is unpatched on them. It has nothing to say about a domain registered last week that resolves to a copy of your single sign-on page, even though that domain is an open door into the same estate. This page is about turning verified phishing infrastructure into tracked findings with an owner, a severity and an SLA.

390,000+Active phishing domains, every one DNS-verified as resolving
04:30 UTCDaily rebuild, with an added and removed changelog
0.98 / 0.0Confidence on a confirmed match or on no match
100 / callDomains per batch request, at one lookup each

What the finding looks like

Confirmed
AssetExternal — look-alike of the corporate SSO hostname
Evidenceis_phishing: true, confidence: 0.98
Categoryphishing/malware
DNS statusresolves — an active A record at time of check
Last checkedVerified in the most recent 24-hour rebuild
OwnerAssign like any other finding, with an SLA and a closure test
External attack surface
Look-alikes of your estate
Shadow and forgotten domains
Findings with owners
Scheduled re-screening
Risk register evidence
Home / Use Cases / Vulnerability Management
The gap in the programme

Your attack surface includes hosts you do not own

Vulnerability management matured around assets in a CMDB. The most productive route into most organisations is a host that will never appear in one.

The discipline has a clean model and it works well within its boundaries. You enumerate assets, you scan them, you correlate findings against a vulnerability database, you prioritise by exploitability and exposure, you assign an owner, you track remediation against an SLA, and you verify closure with a re-scan. Every part of that model assumes the thing you are worried about is something you control. Patch it, reconfigure it, decommission it, compensate for it — the remediation verbs all presuppose administrative access.

Now consider the asset a domain registered on Tuesday represents. It resolves, it serves a pixel-perfect copy of your identity provider's sign-in page, it is reaching two hundred of your employees this afternoon, and you cannot patch it, reconfigure it or decommission it. No CVE, no CVSS vector, no vendor advisory, and no appearance in an authenticated scan, an agent inventory or a configuration baseline — yet on any honest reading of exploitability it is a more likely route in this quarter than most of the medium-severity findings in your queue.
EASM closed half of this gap. Most tooling now does a competent job of discovering the estate you forgot you had — the marketing microsite from a campaign three years ago, the staging environment somebody exposed, the subsidiary domain that never made it into the register, the certificate covering a hostname nobody recognises. Discovery of your own sprawl is genuinely valuable, but the adversary's infrastructure sits one step further out and is not discoverable by enumerating anything you control.
So be precise about what this data source is. A database of domains observed and confirmed as live credential-harvesting infrastructure, every entry verified as currently holding an active A record, rebuilt every 24 hours. It is not a scanner, it is not a monitoring service watching registrations on your behalf, and it does not score risk. It answers one narrow question with high confidence: is this specific hostname confirmed hostile right now?
Narrower than an EASM platform — and more decisive. Vulnerability management is fundamentally an argument about where to spend limited remediation attention, and most of that argument is about uncertainty: is this reachable, is it exploitable, is the compensating control real. A confirmed match here carries none of that ambiguity. The confidence is 0.98 or it is 0.0, with no middle band to litigate in a triage meeting.
Programme questions

Six questions a mature programme should be able to answer

If your answer to any of these is "we would have to ask someone", that is the gap this data closes.

Is anything impersonating us right now?

Not "has anything ever been reported", which is what most feeds answer, but which hostnames resembling our estate are confirmed live and resolving today. The verification standard is what turns that from a research question into an operational one.

Do we know every hostname we publish?

Your own external inventory is the input to everything else here. If asset discovery has produced a list of hostnames, that list is exactly what you screen — and the subsidiaries and acquisitions are where the surprises are.

Who owns a hostile look-alike?

Findings without owners do not get closed. A confirmed impersonation needs an assignee, a due date and a defined closure test, exactly like a missing patch — usually split between a takedown request and blocking it internally.

How often do we re-check?

A one-off scan tells you about one Tuesday. Because the infrastructure churns daily, the control is a schedule rather than a scan, and the changelog of additions and removals is what makes the schedule cheap to run.

Do our own outbound links still resolve safely?

Marketing pages, documentation, partner directories and internal wikis accumulate outbound hostnames for years. Domains lapse and get re-registered. Screening what you publish is a genuine finding class nobody scans for.

Can we evidence this to an auditor?

A dated, machine-generated result with a stated verification method and a binary confidence is far easier to put in a risk register than a screenshot of someone's search. The response fields are designed to be stored verbatim.

The technique

Search the day's list for anything wearing your name

This is the concrete workflow, and it is deliberately unsophisticated. The whole database is downloadable, so the matching logic is yours to write and yours to tune.

Start by assembling the terms that identify you. Your primary domain label, the labels of any subsidiaries and acquisitions, product names, the brand names of anything customer-facing, and the distinctive parts of your identity provider's hostname. Then add the deformations that actually get registered: character substitutions that look similar in a browser address bar, doubled and dropped letters, inserted hyphens, and the pattern where your brand appears as a subdomain of something unrelated — the last one is the most common and the easiest to miss with a naive equality check.

Then pull the current database from /feed. It arrives as CSV with three columns — domain, category and dns_status — or as JSON if that suits your pipeline better. Downloads are unlimited with a subscription, which matters here because you will want to re-run this daily rather than monthly, and the build lands at 04:30 UTC so a job an hour later always has fresh data.
The matching is trivial; the state handling is not. A substring scan across a few hundred thousand rows costs nothing. The engineering effort is entirely in the term list and in suppressing repeats, because a match will keep matching every day until the host goes dark, and a finding that re-opens daily trains people to ignore the report. Keep a state file of what you have raised, emit only new matches, and let the changelog drive removals so a closed finding does not silently reopen.
Daily sweep of the feed for look-alikes of your estate
# Pull the current database, then scan it for anything resembling our estate.
# Emit only hostnames we have not already raised as a finding.
import csv, json, pathlib

TERMS = ["acme", "acme-corp", "acmecorp", "acrne",
 "sso-acme", "acme-login", "acmepay"]

seen = pathlib.Path("raised.json")
already = set(json.loads(seen.read_text())) if seen.exists() else set()
new = []

with open("phishing_domains_active.csv") as f:
 for row in csv.DictReader(f):
 host = row["domain"].lower()
 if any(t in host for t in TERMS) and host not in already:
 new.append({"domain": host,
 "category": row["category"],
 "dns_status": row["dns_status"]})

# Hand `new` to the ticketing system: one finding per hostname, with an owner.
already.update(item["domain"] for item in new)
seen.write_text(json.dumps(sorted(already)))
Screening a known list instead? If you already hold an inventory of external hostnames from asset discovery, batch it through /batch — up to 100 domains per POST at one lookup each — rather than downloading the whole database. The response returns checked, phishing_found and credits_used, which is a tidy one-line summary for a job log.
Do not put the key in a scanner's client-side config. The API key is the username chosen at registration and is a server-side secret. Anything that runs in a browser, a desktop agent or a distributed runner should call an endpoint of your own, not the service directly.
Why the verification standard matters here

False positives cost a vulnerability programme more than they cost anyone else

Your whole operating model runs on the credibility of the queue. A finding class that generates noise gets ignored, and then quietly gets switched off.

Every vulnerability manager has watched the same failure. A new data source is plumbed in, it produces a burst of findings, some of them turn out to be wrong, an engineering team pushes back, the source loses credibility, and within two quarters nobody looks at it. The technical quality of the data was never the deciding factor — the deciding factor was whether the first fifty findings held up under scrutiny.

Which is why the verification rule deserves reading rather than skimming. Inclusion requires an active A record confirmed through rotating proxy infrastructure, so a domain that was reported, taken down and has stopped resolving is simply not in the list. The active population stays around 390,000 instead of growing without limit, because entries age out when the infrastructure goes dark. When you hand an owner a finding, you are handing them a host that answered a DNS query within the last rebuild cycle — not a historical report they can dismiss as stale.

The binary confidence does the same work. There is no 0.6 to argue about in a triage meeting and no threshold for a team to lobby you to raise: a hostname is a confirmed match at 0.98 or it is absent at 0.0. That is unusually convenient for a discipline that spends much of its time negotiating over severity, and it is why these findings tend to close faster than the average item in a queue.

Verified live, not merely reported

An active A record at check time is the inclusion rule. Dead infrastructure falls out of the list instead of accumulating as findings nobody can action.

Rebuilt every 24 hours

The build lands at 04:30 UTC with a changelog of what was added and removed, so your sweep is a diff rather than a full re-evaluation every morning.

No score to argue about

0.98 for a confirmed match, 0.0 for no match. Nothing in between means nothing to tune, nothing to threshold, and nothing to negotiate during triage.

Requirement to implication

What each programme requirement actually implies here

Fitting an external finding class into an existing process is mostly a matter of deciding what the familiar words mean when you do not own the asset.

Findings must map to an asset

Implication

Register the impersonated thing as the asset, not the hostile host. The finding belongs to the identity provider, the customer portal or the payments brand being copied — which gives it an existing owner, an existing criticality rating and a place in the register.

Findings must have a remediation

Implication

Remediation splits in two, and both halves should be tracked. Externally: a takedown request to the registrar or host. Internally: push the hostname to whatever enforces blocking — proxy, resolver, mail gateway — so exposure ends immediately rather than when the takedown lands.

Findings must have an SLA

Implication

Measure the internal half, because it is the half you control. Blocking a confirmed hostname is a same-day action; takedown timelines depend on a registrar's process and should be tracked separately so a slow provider does not corrupt your remediation metrics.

Closure must be verifiable

Implication

Re-check the hostname. A dns_status that no longer resolves, or absence from the current build, is your closure evidence — and it is machine-readable, which means the verification step can be part of the same scheduled job that raised the finding.

Scope must be honest about what is not covered

The limitation, stated for the record

This is a known-bad lookup, and the programme documentation should say so in those words. A confirmed match means a hostname has been observed, verified as resolving and confirmed as phishing infrastructure. A clean result means "not on the list" — it does not mean the host is safe, and it does not mean nothing is impersonating you. A domain registered this morning and first used this afternoon will not appear yet, and a hostile page on a compromised legitimate site may never appear, because the domain itself is not hostile.

Nor is this a scanner. It does not enumerate your estate, it does not test anything for exploitability, and it patches nothing. Treat it as one high-confidence input into an existing programme — most usefully alongside brand protection for the watch function, threat intelligence for context, and incident response for what happens after a confirmed match.
Where it sits

Against a scanner, an EASM platform and a domain-monitoring service

These are frequently discussed as if they compete. They mostly do not, and knowing which question each one answers stops you buying the same answer twice.

QuestionVulnerability scannerEASM platformThis database
What do we own and expose? Only what you point it at Its core competence No discovery at all
What is unpatched or misconfigured? Its core competence Externally observable issues Out of scope entirely
Is this specific hostname hostile today? Not a question it asks Varies by vendor and tier Verified, binary, dated
Was inclusion verified as live? Not applicable Usually not stated Active A record required
Will it alert on a new registration? No Some tiers do No — you sweep the list yourself
Can we hold the whole dataset locally? Not applicable Rarely Full download, unlimited pulls
Cost shape Per asset or per scan Per domain or per seat, annual Credits, or a flat feed subscription

Use this when

You want a verified, dated answer about specific hostnames — your own inventory, reported look-alikes, outbound links you publish — and you want the raw dataset so the logic lives in your pipeline rather than a vendor's.

Pair it with something else when

You need discovery of your own sprawl, or continuous watching of new registrations. Those are different products solving different problems; this one deliberately does neither.

Do not use it for

Anything that requires "is this safe" rather than "is this confirmed hostile". A clean result is the absence of a match, and treating it as an assurance is the one way to misuse this data.

Cost

What a sweep programme costs to run

The arithmetic is unusually easy here, because a vulnerability programme's volumes are small and predictable.

If you are screening a known inventory rather than sweeping the whole database, credits are the right shape. An organisation with two thousand external hostnames re-screened weekly is spending around a hundred thousand lookups a year, which is the $249 Professional package at $0.0025 per lookup. A smaller estate checked monthly sits comfortably inside the Growth package of 10,000 lookups, or the $99 Growth package of 25,000. Credits are monthly subscriptions via PayPal, billed monthly from purchasefewer than ten percent have been used.

The daily sweep runs on the feed

Downloading the full database each morning and running your own term matching means the Daily Threat Feed at $499 per month or $499/month. The annual tier adds historical archive access, priority support, custom format options, a dedicated account manager and 100,000 API credits, so the inventory-screening work above comes with it rather than needing a second purchase. Downloads are unlimited, which is the point: a nervous first week of hourly pulls costs nothing extra.

The archive enables retrospective hunting

This is the part worth a specific mention for a vulnerability audience. When a hostname appears in today's build, the question "was anybody in our estate resolving that domain in the two weeks before we knew about it" becomes answerable against your own proxy and DNS logs — which converts a preventive control into a detection one. That workflow is developed further on the SIEM integration page.

Larger volumes and restricted environments

Monthly plans range from Growth at $99/month for 25,000 lookups through Enterprise at $999/month for 750,000 lookups. SFTP or S3 delivery, STIX/TAXII, custom update frequencies, an SLA and on-premise deployment are quoted rather than listed — the last of those matters to organisations whose security tooling is not permitted to make outbound calls. Detail is on the pricing page, the daily feed page and in the API documentation.

Report the metrics you actually control

Do not report this finding class by volume, because volume is a property of the adversary's activity rather than of your programme. Report time-to-block from first appearance in the build, coverage of your own inventory in the screening list, and the proportion of confirmed matches carrying a named owner. Those three numbers describe something you control, which is the only kind of metric worth defending in a steering meeting.

Questions

What vulnerability managers and EASM leads ask

Several of these deserve an answer that concedes a limitation rather than working around it.

Is this a replacement for our EASM platform?

No, and it would be a poor one. An EASM platform's core job is discovering assets you did not know you exposed — forgotten subdomains, shadow environments, certificates covering hostnames nobody recognises, an acquisition's estate that never made it into the register. This performs no discovery whatsoever.

What it adds: a verified answer about adversary-controlled hostnames, a data class most EASM products either do not carry or carry with a much weaker verification standard. The natural relationship is that your EASM output becomes the input list you screen.
Will it alert us when someone registers a look-alike?

No. There is no watch function and no alerting service — this is a lookup and a downloadable dataset, not a monitoring product, and it is better to be blunt about that than to let you discover it in month two.

What you can build instead: sweep each day's database for your terms, as in the code above, and raise a finding on anything new. A domain only appears once it has been observed and verified as live phishing infrastructure rather than at the moment of registration — later than a registration monitor would tell you, and considerably more certain.
How do we avoid drowning the queue in daily re-matches?

Keep state. A confirmed hostile hostname will keep appearing in the database every day until the infrastructure goes dark, so a sweep that emits every match will re-raise the same finding indefinitely and your engineers will start filtering the report to a folder.

The fix: emit only hostnames absent from your raised set, and use the daily changelog of removals to drive closure verification. That turns a noisy daily report into a small stream of genuinely new items, plus automatic evidence when something goes away.
What severity should a confirmed look-alike get?

Inherit it from the impersonated asset rather than assigning a fixed rating. A copy of your single sign-on page is a different proposition from a copy of a regional marketing site, even though both produce an identical response from the API.

A defensible rule most programmes land on: impersonation of an authentication surface takes the criticality of that identity system, impersonation of a payment or customer-data surface takes the criticality of that data, and everything else defaults one band lower with an option to escalate. Because the confidence is binary, you are only ever arguing about impact — never about whether the finding is real.
Can we run this in an environment with no outbound internet access?

Yes, with the feed rather than the API. The full database downloads as a file, so it can be pulled on a connected system, checked, and carried across into a restricted environment on whatever transfer mechanism you already operate. Matching then happens entirely locally with no outbound call at any point.

This is the standard pattern for organisations whose security tooling may not make outbound requests, and for anyone who does not want a third party holding a record of which hostnames they enquired about. If the restriction runs deeper, on-premise deployment is a quoted option.
Does a clean result count as evidence for an auditor?

Evidence that you checked, yes. Evidence that nothing hostile exists, no — and that distinction should be written into your control description rather than left implicit, because it is exactly where a control gets misrepresented.

The defensible framing is procedural: the organisation screens its external hostname inventory against a daily-rebuilt database of DNS-verified active phishing domains at a stated frequency, raises findings on confirmed matches, and tracks them to closure. That describes something you actually do; "no impersonation of our brand exists" describes something nobody can evidence.
How does this interact with our takedown provider?

It supplies the confirmation step at the front of that process. A takedown request supported by a dated result showing an active A record, a category of phishing/malware and a confidence of 0.98 is a stronger submission than a screenshot, and registrars and hosting providers respond better to structured evidence.

What it will not do: perform takedowns or manage the correspondence. Keep those as separate tracked work, and measure the internal blocking action separately from the external takedown so a slow provider does not distort your remediation figures.
We are a small team. What is the minimum viable version?

One scheduled job, one term list and one ticket queue. Screen your top twenty external hostnames and their obvious deformations through /batch once a week, raise anything confirmed as a finding with a named owner, and block confirmed matches at whatever you already control — proxy, resolver or mail gateway.

That is an afternoon of work and a small monthly plan. Confirm the current database size and last update date first through the /stats endpoint, which requires no API key, no credits and no authentication, then decide whether the daily sweep is worth the subscription.

Give the external half of your attack surface a queue, an owner and a due date

Screen your hostname inventory with a monthly plan, or take the full daily database and sweep it for anything wearing your name — then block confirmed matches the same day and track closure like any other finding.