diff --git a/src/network-services-pentesting/700-pentesting-epp.md b/src/network-services-pentesting/700-pentesting-epp.md index 623432c1f08..bf83a8711d4 100644 --- a/src/network-services-pentesting/700-pentesting-epp.md +++ b/src/network-services-pentesting/700-pentesting-epp.md @@ -4,78 +4,130 @@ ## Basic Information -The Extensible Provisioning Protocol (EPP) is a network protocol used for the **management of domain names and other internet resources** by domain name registries and registrars. It enables the automation of domain name registration, renewal, transfer, and deletion processes, ensuring a standardized and secure communication framework between different entities in the domain name system (DNS). EPP is designed to be flexible and extensible, allowing for the addition of new features and commands as the needs of the internet infrastructure evolve. +The **Extensible Provisioning Protocol (EPP)** is the standard protocol used by **registries** and **registrars** to manage domain objects (create, update, renew, transfer, delete, DNSSEC data, poll messages, etc.). -Basically, it's one of the protocols a **TLD registrar is going to be offering to domain registrars** to register new domains in the TLD. +In practice, this is one of the most sensitive services in a TLD environment: if you can operate EPP as a registrar or abuse a registrar-facing control plane that proxies EPP actions, you can usually **change nameservers, rotate transfer credentials, alter DNSSEC state, or transfer domains away**. + +The classic transport is **TLS over TCP on port `700/tcp`**, usually with **mutual TLS**, source-IP restrictions, and an additional EPP `login` using a username/password. However, do not assume the attack surface is limited to raw TCP on port 700 anymore: current IETF work is standardizing **EPP over HTTPS**, and some registries/clients already implement or test that model. ### Pentest -[**In this very interesting article**](https://hackcompute.com/hacking-epp-servers/) you can see how some security researches found several **implementation of this protocol** were vulnerable to XXE (XML External Entity) as this protocol uses XML to communicate, which would have allowed attackers to takeover tens of different TLDs. +A good real-world starting point is [**HackCompute's research on vulnerable EPP implementations**](https://hackcompute.com/hacking-epp-servers/). They found XML parser abuse (XXE) and chained it into local file disclosure against real registry software, showing how an EPP bug can become **domain or even TLD-level compromise**. --- ## Enumeration & Recon -EPP servers almost always listen on TCP `700/tcp` over TLS. A typical deployment also enforces **mutual-TLS (mTLS)** so the client must present a valid certificate issued by the registry CA. Nevertheless, many private test or pre-production deployments forget that control: +### Initial network checks + +EPP servers commonly use hostnames such as `epp.`, `ote.`, `ot&e.`, `sandbox`, or `staging`. ```bash -# Banner-grabbing / TLS inspection -nmap -p700 --script ssl-cert,ssl-enum-ciphers +# TLS and certificate inspection +nmap -sV -Pn -p700 --script ssl-cert,ssl-enum-ciphers +openssl s_client -connect :700 -servername -showcerts :700 -quiet \ - -servername epp.test 2>/dev/null | head +### Grab the EPP greeting + +The greeting is the EPP equivalent of banner-grabbing. It tells you which **object URIs** and **extension namespaces** the server supports. + +```bash +printf '%s\n' \ +'' \ +'' \ +| openssl s_client -quiet -connect :700 -servername 2>/dev/null ``` -If the server does not terminate the connection after the TLS handshake you can attempt to send an unauthenticated `` message: +From the greeting, pay attention to namespaces such as: -```xml - - - - +- `domain`, `host`, `contact` +- `secDNS` --> DNSSEC DS / key-data management +- `rgp` --> restore / redemption flows +- `launch`, `fee`, `ttl`, proprietary namespaces --> custom business logic / extra parser surface +- `loginSec` --> login-security extension +- `changePoll`, `maintenance` --> out-of-band workflow visibility + +If the server advertises a lot of extensions, the parser and authorization surface is usually much larger than the base RFCs suggest. + +### Check for EPP over HTTPS + +The current EPP-over-HTTPS draft maps the greeting to an **HTTP `GET`** and subsequent commands to **HTTP `POST`**, with state tracked through **cookies / sticky sessions**. If the registry exposes this transport, you may see `Content-Type: application/epp+xml`, `Set-Cookie`, and cache-control headers in the greeting response. + +```bash +curl -isk https:/// -H 'Accept: application/epp+xml' ``` +If HTTPS works, test it like an authenticated/stateful API in addition to classic EPP: + +- cookie fixation / session mix-up behind load balancers +- path confusion (`/`, `/epp`, `/api/epp`, `/registry/epp`) +- reverse-proxy auth mistakes +- accidental caching or logging of XML bodies and transfer credentials + +### Look for forgotten OT&E / registrar onboarding infrastructure + +Public registry documentation is often gold. For example, some registrar manuals openly document: + +- production EPP endpoints +- OT&E / certification endpoints +- whether OT&E is IP-restricted or not +- registrar consoles, WHOIS test services, and onboarding workflows + +That matters because **test environments commonly share code paths with production** while having weaker IP allowlists, reused credentials, weaker certificates, or lower scrutiny. + +### Authentication stack to map + +Real deployments often layer several controls: + +- **client certificate** +- **source IP allowlist** +- **EPP username/password** +- optional registrar web panel / reseller console that ultimately issues EPP actions + +This is important during an assessment because you do **not** always need direct socket-level EPP access. Compromising a registrar console, support workflow, internal API, or an automation worker that holds the client certificate may be enough. + ### Open-source clients useful for testing -* **epp-client (Go)** – actively maintained, supports TCP/TLS and EPP-over-HTTPS (RFC 8730): - `go install github.com/domainr/epp/cmd/epp@latest` -* **gandi/go-epp** – minimal client library that can easily be instrumented for fuzzing or nuclei-style workflows. -* **afq984/php-epp-client** – PHP implementation used by many small registrars; a convenient target for code-review. - -Example minimal login+check script with Go epp-client: - -```go -package main -import ( - "github.com/domainr/epp" - "crypto/tls" -) - -func main() { - cfg := &tls.Config{InsecureSkipVerify: true} - c, _ := epp.DialTLS("epp.test:700", cfg) - c.Login("CLIENT_ID", "PASSWORD", nil) - resp, _ := c.DomainCheck("example","com") - println(resp) -} -``` +- **[domainr/epp](https://github.com/domainr/epp)** / **[domainr/epp2](https://github.com/domainr/epp2)** – lightweight Go clients that are easy to instrument for fuzzing and custom namespaces. +- **[CZ-NIC/fred-client](https://github.com/CZ-NIC/fred-client)** – Python CLI/API for FRED-based registries. +- **[getnamingo/epp-client](https://github.com/getnamingo/epp-client)** – PHP client with broad registry support, including EPP-over-HTTPS support in current releases. + +--- + +## High-Value EPP Operations + +If you obtain registrar-level access, these operations usually have the highest offensive value: + +| Operation | Why it matters | +| --- | --- | +| `domain:update` | Change nameservers, contacts, statuses, or `authInfo` | +| `domain:transfer` | Move the domain to another registrar or interfere with approval flows | +| `domain:info` | Often reveals transfer state and, in some implementations/workflows, authorization material | +| `secDNS:update` | Add/remove/replace DS or key data to break validation or control DNSSEC state | +| `poll` | Observe asynchronous events: transfer approvals, registry actions, out-of-band changes | + +A lot of real compromises happen **around** these commands rather than in the XML parser itself: panel/API auth bugs, support workflows, leaked transfer codes, stale OT&E credentials, or weak separation between resellers and parent registrar accounts. --- -## Common Weaknesses & 2023-2025 Vulnerabilities +## Common Weaknesses & Attack Surface -| Year | Component | CWE | Impact | -|------|-----------|-----|--------| -| 2023 | CoCCA Registry < 3.5 | CWE-611 XXE | Remote file read & SSRF via crafted `` payload (patch: 2023-11-02) | -| 2024 | FRED EPP Server 2.x | CWE-322 Insufficient TLS cert validation | Bypass of mTLS allowed unauthorized registrar login | -| 2025 | Proprietary registrar panel | CWE-306 Missing Authentication for Critical Function | Domain transfer approval endpoint exposed over EPP-HTTP bridge | +### XML parser bugs (XXE, SSRF, local file disclosure) -### XXE / SSRF payload (works against many Java/Spring implementations) +EPP is XML, so the classic parser bug class is still relevant. The HackCompute research showed how XXE in real EPP implementations could be chained into local file disclosure and potentially much wider registry compromise. + +Basic test payload: ```xml -]> +]> @@ -87,39 +139,128 @@ func main() { ``` -When the parser is mis-configured (`XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES=true`) the file content is returned inside the `` structure. +Besides plain file read, test for: + +- **SSRF** to metadata/internal services +- **external DTD fetches** for blind callbacks +- parser differences between **production** and **OT&E** stacks +- XML handling in **registrar-side portals** that transform user input into EPP XML + +### Legacy password model and the `loginSec` extension + +Base EPP historically limited the `pw` field to a short XML schema string, which is why [RFC 8807](https://datatracker.ietf.org/doc/rfc8807/) introduced the **Login Security Extension** for longer passwords/passphrases and machine-readable security events. + +When testing authenticated access, check whether the registry still behaves like an old deployment: + +- short shared passwords only +- no password rotation hints +- no visibility into expiring client certificates +- no telemetry for repeated failed logins or insecure TLS/cipher negotiation + +If `loginSec` is enabled, a successful login can return structured warnings such as **expiring passwords/certificates**, **insecure TLS versions/ciphers**, or **high failed-login counts**. That is useful both for offensive situational awareness and for identifying weak operational hygiene. + +### `authInfo` / EPP code abuse and transfer workflows + +`authInfo` (also called EPP code / transfer code / Auth-Info code) is one of the most valuable secrets in the domain lifecycle. + +The important offensive detail is that **the protocol and policy surface around transfers is still large**: + +- EPP domain objects support `authInfo` +- ICANN transfer policy still requires registrars to provide the AuthInfo code and remove `ClientTransferProhibited` within specific conditions/time limits +- [RFC 9154](https://datatracker.ietf.org/doc/html/rfc9154) exists because long-lived, stored, reusable transfer secrets are dangerous + +Practical checks: + +- Can a low-privilege user, reseller, or support role **view or reset** `authInfo`? +- Does a registrar panel/API return a **static** transfer code that rarely changes? +- Is `authInfo` emailed, ticketed, logged, or stored in CRM/internal notes? +- Can you **unlock** a domain or fetch its EPP code through a weaker path than the one required to edit nameservers/contacts? +- Do internal APIs mirror `domain:info` responses containing authorization data to users that should not see it? +- Can a transfer be raced against manual review or asynchronous approval messages? + +The secure model from RFC 9154 is: **strong random authInfo, short-lived, not stored by the client, hashed at the server, not logged, and automatically unset after successful transfer**. Anything materially weaker is worth digging into. + +### DNSSEC / `secDNS` abuse + +Once you have EPP access, do not stop at nameserver changes. Many operators forget that EPP also controls **DNSSEC state**. + +With [RFC 5910](https://datatracker.ietf.org/doc/html/rfc5910), a registrar can add/remove/replace **DS records** and key data via `secDNS`. That means a privileged attacker may be able to: + +- remove DS material to intentionally break validation during takeover +- replace DS/key data to match attacker-controlled signing keys +- combine nameserver and DNSSEC changes in one workflow to make recovery slower and more error-prone + +Minimal example of removing all existing DNSSEC material and adding attacker-controlled DS data: + +```xml + + + true + + + 3133713 + 2DEADBEEF + + + + +``` + +### Poll queue, change poll, and maintenance events + +Modern EPP deployments increasingly rely on asynchronous workflows: -### Other typical findings +- `poll` for queued messages +- [RFC 8590](https://datatracker.ietf.org/doc/rfc8590/) for **Change Poll** (out-of-band object changes) +- [RFC 9167](https://datatracker.ietf.org/doc/rfc9167/) for **Registry Maintenance Notification** -1. **Weak credential policy** – EPP login passphrases shorter than 8 chars; brute-force is often feasible because the spec only RECOMMENDS (not requires) rate-limiting. -2. **Missing `registryLock` / `serverUpdateProhibited` status** – once authenticated, attackers can immediately update NS records and steal traffic. -3. **Unsigned poll messages** – some implementations still do not sign poll Q&A messages, enabling spoofing/phishing of registrar operators. +These are valuable during an assessment because they often reveal: + +- transfers initiated outside your current session +- support/operator actions not initiated via EPP +- UDRP/court/policy-driven changes +- maintenance windows and secondary systems + +If a registrar mirrors these messages into **email, webhooks, dashboards, or reseller portals**, test those integrations too. A weak internal consumer can become the easier compromise path than raw EPP itself. --- -## Attack Path: From Zero to TLD Hijack +## Practical Offensive Checks -1. Discover an EPP endpoint (often hidden behind a generic host like `ot&e..nic.`). -2. Abuse one of the weaknesses above to gain registrar-level credentials (XXE → SSRF to IMDSv1, credential exfil, or TLS-bypass). -3. Issue `` requests to change the domain’s `hostObj` records to attacker-controlled name servers. -4. (Optional) Submit a `` to move the domain to an attacker-controlled registrar – many registries still rely on a **single auth-code**. -5. Profit: full control of DNS zone, ability to request TLS certificates via ACME. +1. **Find every endpoint**: production, OT&E, reseller, registrar console, API gateway, docs, and WHOIS/RDAP references. +2. **Enumerate greeting namespaces** and map which flows exist: transfer, DNSSEC, poll, launch, fee, maintenance. +3. **Compare prod vs OT&E**: cert policy, source-IP restrictions, login behavior, extension availability, error handling. +4. **Hunt for transfer-secret exposure** in registrar UIs, APIs, ticketing, logs, exports, and support workflows. +5. **Test authorization asymmetry**: can you unlock / fetch EPP code / transfer more easily than you can edit nameservers? +6. **Abuse post-compromise EPP breadth**: nameservers, statuses, `authInfo`, DS records, contact changes, and poll queue visibility. +7. **For HTTPS transports**, test cookie/session behavior and proxy-induced bugs exactly like a high-value stateful XML API. --- -## Defensive Measures & Hardening +## Attack Path: From Recon to Domain / TLD Hijack + +1. Discover production or OT&E EPP infrastructure via docs, certificates, registrar portals, or related services. +2. Enumerate the greeting to learn supported namespaces and high-value operations. +3. Obtain registrar capability by exploiting XML parsing, a registrar control-plane bug, stolen client certificate, leaked EPP credentials, or exposed `authInfo` workflows. +4. Change `hostObj` / nameserver data, rotate `authInfo`, submit transfer operations, or alter DNSSEC material through `secDNS:update`. +5. Use `poll` responses and asynchronous workflow artefacts to monitor completion and race defenders. -* Enforce **mTLS with per-registrar client certificates** and pin the registry CA. -* Set `parserFeature secure-processing=true` or equivalent to kill XXE. -* Run **continuous fuzzing** of the XML parser (e.g., with `go-fuzz` or `jazzer` for Java). -* Deploy **Registry Lock / server*Prohibited** statuses for high-value domains. -* Monitor `poll` queue for suspicious `` or `` commands and alert in real-time. -* ICANN 2024 DNS-Abuse contract amendments require registries to prove rate-limit & auth controls – leverage them. +For a **single domain**, this usually means DNS takeover, certificate issuance opportunity, and email interception. For a **registry-side compromise**, the blast radius can become **every domain sponsored by that registrar or even the full TLD**. + +--- + +## Defensive Measures & Hardening +Keep this short from an offensive perspective, but these are the controls that most reduce attacker options: +- enforce **mTLS + source-IP restrictions + strong/passphrase-based login security** +- treat **OT&E/staging** as production-grade from an auth and monitoring perspective +- implement **short-lived, one-time, hashed `authInfo`** workflows +- alert on **nameserver, transfer, and DNSSEC** changes together, not separately +- consume and review **poll / change-poll / maintenance** events centrally ## References -* ICANN Security and Stability Advisory Committee (SSAC). "SAC118: Consequences of Registry Operator Failure to Implement EPP Security Controls". 2024. -* HackCompute – "Hacking EPP servers: abusing XXE to hijack TLDs" (2023). +- [HackCompute - can I speak to your manager? hacking root EPP servers to take control of zones](https://hackcompute.com/hacking-epp-servers/) +- [RFC 9154 - Extensible Provisioning Protocol (EPP) Secure Authorization Information for Transfer](https://datatracker.ietf.org/doc/html/rfc9154) {{#include ../banners/hacktricks-training.md}}