65 lines
3.1 KiB
Markdown
65 lines
3.1 KiB
Markdown
# checker-dangling
|
|
|
|
A happyDomain checker that scans a working zone for **dangling subdomains**:
|
|
records (`CNAME` / `MX` / `SRV` / `NS`) whose targets resolve to NXDOMAIN,
|
|
or whose external registrable domain is expired, in `pendingDelete`, or
|
|
recently re-registered. This is the attack class popularised by Ars
|
|
Technica in 2017, where universities ended up serving porn from CNAMEs
|
|
that pointed at decommissioned third-party services after malicious
|
|
actors re-registered the lapsed targets.
|
|
|
|
It runs in three deployment modes (standalone HTTP binary, Go plugin,
|
|
Docker image), like every other checker in the happyDomain ecosystem.
|
|
|
|
## How it works
|
|
|
|
The checker walks every service in the working zone (`AutoFillZone`) and
|
|
extracts pointer records from `svcs.CNAME`, `svcs.SpecialCNAME`,
|
|
`svcs.MXs`, `svcs.UnknownSRV`, and `svcs.Orphan` bodies (the latter
|
|
covering bare `NS`/`CNAME`/`MX` records when no dedicated service is
|
|
attached). For each (owner, rrtype, target) triple it:
|
|
|
|
1. Classifies the target as in-zone or external relative to the zone's
|
|
eTLD+1 (via `golang.org/x/net/publicsuffix`).
|
|
2. Performs a single, time-bounded DNS resolution to detect immediate
|
|
breakage (`nxdomain`, `servfail`, `no_answer`, `timeout`).
|
|
3. Publishes a `DiscoveryEntry` per pointer:
|
|
- `dangling.external-target.v1` for external pointers — companion
|
|
checkers (notably the host's `domain_expiry`) subscribe to this
|
|
type and run RDAP/WHOIS on the registrable domain.
|
|
- `dangling.in-zone-target.v1` for same-registrable pointers — used
|
|
as a join key for future reachability checkers (alias / ping /
|
|
http) that may consume it.
|
|
|
|
## Verdict matrix
|
|
|
|
| Signal | Severity | Source |
|
|
|--------------------------------------------------------------|----------|-------------------------|
|
|
| Target NXDOMAIN | Critical | local DNS resolution |
|
|
| Target SERVFAIL | Warning | local DNS resolution |
|
|
| Target NOERROR with empty answer | Info | local DNS resolution |
|
|
| Registrable domain expired | Critical | `whois` related obs. |
|
|
| Registrable status `pendingDelete` / `redemptionPeriod` | Critical | `whois` related obs. |
|
|
| Registrable registered within the last 90 days | Warning | `whois` related obs. |
|
|
|
|
The rule emits one `CheckState` per impacted owner and ranks them by
|
|
descending severity so the report's "Fix this first" card always
|
|
matches the rule output.
|
|
|
|
## Companion: `domain_expiry`
|
|
|
|
For the WHOIS-driven signals to fire, the host's existing
|
|
`domain_expiry` checker must be extended to subscribe to
|
|
`dangling.external-target.v1` entries via `AutoFillDiscoveryEntries`,
|
|
run RDAP per registrable domain, and publish a per-Ref `whois`
|
|
observation. Without that subscription the checker still works as a
|
|
DNS-only dangling detector.
|
|
|
|
## Build
|
|
|
|
```sh
|
|
make # standalone binary
|
|
make plugin # .so plugin for happyDomain
|
|
make docker # Docker image
|
|
make test # run the unit tests
|
|
```
|