Skip to main content

Linux-native AD CS collector library for BloodHound CE - enumerate ADCS and export to BloodHound format

Project description


CertiHound

Linux-native AD CS collector for BloodHound CE

PyPI Python Version License

FeaturesInstallationQuick StartUsageBloodHoundAPI


CertiHound enumerates Active Directory Certificate Services (AD CS) via LDAP and exports BloodHound CE-compatible data for attack path visualization. Identify ESC1-ESC17 vulnerabilities and visualize certificate-based attack paths.

Screenshots

ESC1 - Enrollee Supplies Subject Detection

ESC1 Detection in BloodHound

CertiHound detects ESC1 vulnerable templates and creates enrollment edges to Enterprise CAs, enabling attack path analysis in BloodHound CE.

ESC4 - Template ACL Abuse Detection

ESC4 Detection in BloodHound

WriteDacl, WriteOwner, and other dangerous permissions on certificate templates are identified and mapped as attack edges.


Features

Feature Description
Linux-Native No Windows dependencies - pure Python LDAP enumeration
BloodHound CE v6+ Direct JSON/ZIP import with full node and edge support
Vulnerability Detection ESC1-ESC11, ESC13-ESC17, GoldenCert
Multiple Backends Works with ldap3, impacket, or any compatible LDAP adapter
NetExec Integration Seamless integration with NetExec's --bloodhound option
Comprehensive Coverage Certificate templates, Enterprise CAs, Root CAs, NTAuth, AIA CAs

Supported Vulnerabilities

Vulnerability Description
ESC1 Enrollee supplies subject with low-privilege enrollment
ESC2 Any Purpose EKU or no EKU allows enrollment agent abuse
ESC3 Enrollment agent templates + vulnerable targets
ESC4 Dangerous ACL permissions on certificate templates
ESC5 Vulnerable PKI object access control on AD containers
ESC6 EDITF_ATTRIBUTESUBJECTALTNAME2 on Enterprise CA
ESC7 Dangerous CA permissions (ManageCA / ManageCertificates)
ESC8 NTLM relay to AD CS web enrollment (HTTP) endpoints
ESC9 No security extension + weak certificate mapping
ESC10 Weak certificate mapping without strong binding
ESC11 NTLM relay to AD CS RPC endpoints (no encryption enforcement)
ESC13 Issuance policy with OID group link abuse
ESC14 Weak explicit certificate mappings (altSecurityIdentities)
ESC15 EKUwu - Application policy abuse on Schema V1 templates
ESC16 Security extension globally disabled on CA
ESC17 Server Authentication EKU + enrollee supplies subject (TLS MITM)
GoldenCert CA private key extraction from hosting computer

Installation

From PyPI (Recommended)

pip install certihound

From Source

git clone https://github.com/0x0Trace/certihound.git
cd certihound
pip install -e .

Verify Installation

certihound --version
certihound --help

Quick Start

Command Line

# Basic enumeration with password authentication
certihound -d corp.local -u 'user' -p 'password' --dc 10.10.10.10 -o output/

# LDAPS (SSL/TLS) connection
certihound -d corp.local -u 'user' -p 'password' --dc 10.10.10.10 --ldaps -o output/

# Kerberos authentication (uses ccache)
certihound -d corp.local -k --dc 10.10.10.10 -o output/

# Output as ZIP (default) or JSON
certihound -d corp.local -u 'user' -p 'password' --dc 10.10.10.10 --format zip
certihound -d corp.local -u 'user' -p 'password' --dc 10.10.10.10 --format json

Python Library

from certihound import ADCSCollector, BloodHoundCEExporter
from certihound.ldap.connection import LDAPConnection, LDAPConfig

# Configure connection
config = LDAPConfig(
    domain="corp.local",
    username="user",
    password="password",
    dc_ip="10.10.10.10",
    use_ldaps=True,
)

# Collect and export
with LDAPConnection(config) as conn:
    collector = ADCSCollector(conn)
    data = collector.collect_all()

    exporter = BloodHoundCEExporter(data.domain, data.domain_sid)
    result = exporter.export(data)
    result.write_zip("bloodhound_adcs.zip")

Usage

CLI Options

Usage: certihound [OPTIONS]

Options:
  -d, --domain TEXT         Target domain FQDN (e.g., corp.local)  [required]
  -u, --username TEXT       Username for authentication
  -p, --password TEXT       Password for authentication
  --dc TEXT                 Domain Controller IP or hostname
  -k, --kerberos            Use Kerberos authentication (ccache)
  --ldaps                   Use LDAPS (SSL/TLS)
  --ca-cert PATH            CA certificate file for LDAPS validation
  --port INTEGER            LDAP port (default: 389 or 636 for LDAPS)
  -o, --output TEXT         Output directory (default: ./output)
  --format [json|zip|both]  Output format (default: zip)
  --enum-only               Only enumerate, skip vulnerability detection
  -v, --verbose             Increase verbosity (-v, -vv)
  --version                 Show the version and exit.
  --help                    Show this message and exit.

Output Files

CertiHound generates BloodHound CE v6 compatible files:

File Description
certtemplates.json Certificate template nodes with properties and edges
enterprisecas.json Enterprise CA nodes with template publishing
rootcas.json Root CA hierarchy nodes
ntauthstores.json NTAuth store configuration
aiacas.json AIA CA entries

BloodHound Integration

Importing Data

  1. Run CertiHound to generate the ZIP file
  2. Open BloodHound CE
  3. Click Import → Select the generated ZIP file
  4. Use the built-in ADCS queries or create custom ones

Example Cypher Queries

Find ESC1 Vulnerable Templates:

MATCH p = (:Base)-[:Enroll|GenericAll|AllExtendedRights]->
(ct:CertTemplate)-[:PublishedTo]->(:EnterpriseCA)
WHERE ct.enrolleesuppliessubject = True
AND ct.authenticationenabled = True
RETURN p

Find ESC4 Template ACL Abuse:

MATCH p = (principal)-[:WriteDacl|WriteOwner|GenericWrite|GenericAll|WriteAllProperties]->
(ct:CertTemplate)-[:PublishedTo]->(ca:EnterpriseCA)
WHERE NOT principal.objectid ENDS WITH '-512'
AND NOT principal.objectid ENDS WITH '-519'
AND NOT principal.objectid ENDS WITH '-544'
RETURN p

NetExec Integration

CertiHound integrates with NetExec for ADCS enumeration.

Status: Integration PR pending review at Pennyw0rth/NetExec#1054
Try it now: Use the feature/adcs-collection branch from 0x0Trace/NetExec

# ADCS only collection
nxc ldap 10.10.10.10 -u user -p pass --bloodhound -c ADCS

# Full collection including ADCS
nxc ldap 10.10.10.10 -u user -p pass --bloodhound -c All --dns-server 10.10.10.10

NetExec Integration Code

from certihound import ADCSCollector, BloodHoundCEExporter, ImpacketLDAPAdapter

# In NetExec's ldap.py:
adapter = ImpacketLDAPAdapter(
    search_func=self.search,
    domain=self.domain,
    domain_sid=self.sid_domain,
)

collector = ADCSCollector.from_external(
    ldap_connection=adapter,
    domain=self.domain,
    domain_sid=self.sid_domain,
)
data = collector.collect_all()

exporter = BloodHoundCEExporter(data.domain, data.domain_sid)
result = exporter.export(data)
result.write_zip("adcs_bloodhound.zip")

API Reference

Core Classes

Class Description
ADCSCollector Main collector for ADCS enumeration
BloodHoundCEExporter Exports data to BloodHound CE format
ImpacketLDAPAdapter Adapter for impacket-based LDAP (NetExec)
LDAPConnection Standalone LDAP connection wrapper
LDAPConfig Configuration dataclass for LDAP connections

Data Models

Class Description
ADCSData Container for all collected ADCS data
CertTemplate Certificate template with properties and ACLs
EnterpriseCA Enterprise CA with enabled templates
RootCA Root CA node
NTAuthStore NTAuth certificate store
AIACA AIA CA entry
ExportResult Export result with write_zip(), write_json(), to_dict()

Detection Functions

from certihound import (
    detect_esc1,
    detect_esc2,
    detect_esc3_agent,
    detect_esc3_target,
    detect_esc4,
    detect_esc5,
    detect_esc6,
    detect_esc7,
    detect_esc8,
    detect_esc9,
    detect_esc10,
    detect_esc11,
    detect_esc13,
    detect_esc14,
    detect_esc15,
    detect_esc16,
    detect_esc17,
)

Usage Example

from certihound import (
    ADCSCollector,
    BloodHoundCEExporter,
    ADCSData,
    ExportResult,
)

# Collect data
collector = ADCSCollector.from_external(adapter, domain, domain_sid)
data: ADCSData = collector.collect_all()

# Access collected objects
print(f"Templates: {len(data.templates)}")
print(f"Enterprise CAs: {len(data.enterprise_cas)}")
print(f"Root CAs: {len(data.root_cas)}")

# Export to BloodHound
exporter = BloodHoundCEExporter(data.domain, data.domain_sid)
result: ExportResult = exporter.export(data)

# Output options
result.write_zip("output.zip")      # ZIP for BloodHound import
result.write_json("output/")        # Individual JSON files
output_dict = result.to_dict()      # Python dictionary

Development

Setup Development Environment

# Clone repository
git clone https://github.com/0x0Trace/certihound.git
cd certihound

# Install with dev dependencies
pip install -e ".[dev]"

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=certihound

# Run specific test file
pytest tests/test_detection.py -v

Code Quality

# Format code
black certihound/

# Lint
ruff check certihound/

# Type checking
mypy certihound/

Dependencies

Package Purpose
ldap3 LDAP operations (standalone mode)
impacket Kerberos authentication & NetExec integration
cryptography Certificate parsing and analysis
pydantic Data validation and models
click CLI framework
rich Terminal output formatting

License

This project is licensed under the MIT License - see the LICENSE file for details.


Credits & References


Made with :heart: for the security community

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

certihound-0.3.0.tar.gz (66.8 kB view details)

Uploaded Source

Built Distribution

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

certihound-0.3.0-py3-none-any.whl (87.1 kB view details)

Uploaded Python 3

File details

Details for the file certihound-0.3.0.tar.gz.

File metadata

  • Download URL: certihound-0.3.0.tar.gz
  • Upload date:
  • Size: 66.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for certihound-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1112797db62292128bc1c8522017b9b38285ff51ec5d9d4ed3442761701efa9b
MD5 fffd512956b8354c12edd6e7ab8fd164
BLAKE2b-256 f8fbb54bc507c72f7e5266b6633440c143a6e175e32024ff7da25ea11bc22506

See more details on using hashes here.

File details

Details for the file certihound-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: certihound-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 87.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for certihound-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 00c8bd63473684cee335f7f274ce2284c57219cb8f795a2fb82b2be6b7c6ba92
MD5 649e7bb25086966f16aeb441b2dceb80
BLAKE2b-256 4f9280ba20537fee36118bf3fd3da6f2121210775bc2a08d839c328b4e4fb95f

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