Catalog PyPI
PACKAGE EXPLORERView in registry

adpentest

PyPI

Active Directory penetration testing framework with automatic Domain Controller detection

active-directoryad-enumerationkerberosldapoffensive-securitypenetration-testingred-teamsecuritysmb
Versions collected1
Direct dependencies10From release 3.4.7
Last observed20 Oct, 19:48 UTC

README

Version 3.4.7 documentation

AdPentestAI-Python

Version 3.4.5

Patch release: fixes LDAP timeout/RootDSE collection, preserves complete scan output in SQLite, and keeps SMB signing observations consistent across probes. Previously truncated scan output requires a new run to collect it again.

Full Active Directory penetration testing framework with WinRM profiling, EVTX log import, Kerberos ticket management, LDAP SPN enumeration, DNS enumeration, privilege auditing, diagnostic storage, and output volume splitting — all with JSON, SQLite, table and HTML output.

GitHub stars GitHub issues License: MIT Python 3.10+ PyPI

Active Directory penetration testing framework with automatic Domain Controller detection, multi-threaded tool execution, WAF bypass engine, CVE scanning, and SQLite scan history.

For authorized penetration testing only. Always get explicit written permission before testing any systems.


Table of Contents


Quick Start

Offline account security review

Review an authorized LDAP snapshot for account inventory, possible exposed secrets and candidate permission paths without contacting a DC:

python -m adpentest --account-audit examples/account-security-snapshot.json --db-path audit.sqlite --json-output audit.json --table

The input format and limitations are documented in Offline account security review. Secrets are redacted before JSON and SQLite persistence. Permission paths remain unverified; account discovery does not establish password exposure or privilege escalation. This is an additive development feature, not a claim that an already-installed PyPI release contains the new command.

Network scan quick start

pip install adpentest

# Dry-run — preview what would execute, no actual tool runs
adpentest --target 10.0.0.1 --mode dry-run --scope-confirmed

# Active scan with auto DC detection
adpentest --target corp.local --mode active --scope-confirmed

# View scan history
adpentest --history

# View only current verified CVE findings
adpentest --cve-report

Common Commands Reference

# === SCANNING ===
adpentest --target 10.0.0.1 --mode dry-run --scope-confirmed        # Preview (no execution)
adpentest --target corp.local --mode active --scope-confirmed        # Full active scan
adpentest --target 10.0.0.1 --mode active --scope-confirmed --timeout 600  # Custom timeout

# === WINRM PROFILING ===
adpentest --winrm-check --target dc.corp.local --mode active --scope-confirmed --table
adpentest --winrm-check --target dc.corp.local --mode active --scope-confirmed \
  --winrm-auth negotiate --winrm-user admin@corp.local --winrm-password-env PASS \
  --winrm-exec-check --db-path winrm.db --html-report winrm.html

# === EVTX LOG IMPORT ===
adpentest --evtx-import Security.evtx --db-path scan.db              # Single file
adpentest --evtx-import /exports/ --db-path scan.db --evtx-json out.json  # Directory + JSON

# === KERBEROS TICKETS ===
adpentest --obtain-tickets --ticket-domain corp.local --ticket-user researcher \
  --ticket-kdc dc.corp.local --ticket-spn cifs/server.corp.local \
  --mode active --scope-confirmed --table
adpentest --ticket-inventory --ticket-cache FILE:tickets/krb5.ccache --table

# === PRIVILEGE AUDIT ===
adpentest --audit-auth kerberos --target dc.corp.local --obtain-tickets \
  --ticket-domain corp.local --ticket-kdc dc.corp.local \
  --mode active --scope-confirmed --db-path audit.db

# === LDAP SPN ENUMERATION ===
adpentest --ldap-spn-auto dc.corp.local --ldap-spn-save spns.json
adpentest --ldap-spn-data spns.json                                  # Offline analysis

# === DNS ENUMERATION ===
adpentest --dns-enum --target corp.local --dns-enum-save dns.json --table

# === REPORTS & HISTORY ===
adpentest --history                                                   # All past runs
adpentest --history --history-limit 5                                 # Last 5 runs
adpentest --cve-report                                                # CVE findings
adpentest --run-details RUN_ID                                        # Specific run
adpentest --target corp.local --mode active --scope-confirmed --html-report report.html

# === EXPORT DATABASE ===
adpentest --export-db /path/to/export/ --db-path scan.db             # JSON export
adpentest --export-db /path/to/export/ --volume-size 1               # 1 MiB volumes

Confirmed CVE findings

The CVE report, HTML findings, and dashboard show only confirmed findings. An open port, service banner, signing observation, or high correlation score does not establish a specific CVE. All built-in heuristic scanners return assessment: "unverified" until target-specific proof is available. Passive correlations are retained under passive_cve_scan.observations; matches contains no unverified candidates. Raw tool observations remain available.

Supply inventory collected from the target with --cve-evidence FILE.json. The file is an array of proofs keyed by exact CVE and target. Each proof must include this structure, replacing placeholders with observed facts:

[
  {
    "cve": "CVE-2025-33073",
    "target": "192.0.2.10",
    "method": "vendor-version-and-patch-inventory",
    "checked_at": "<UTC timestamp of the inventory>",
    "vendor": "<exact vendor in the official record>",
    "product": "<exact product in the official record>",
    "version": "<observed product/build version>",
    "platform": "<platform if the official record restricts it>",
    "patch_state": "missing",
    "prerequisites_verified": true,
    "advisory_url": "<vendor advisory listed in the official record>",
    "evidence": {
      "product_version": {"source": "inventory.json", "sha256": "<SHA-256 of inventory.json bytes>", "value": "<same observed version>"},
      "patch_inventory": {"source": "inventory.json", "sha256": "<same file digest>", "value": {"complete": true, "installed": [], "missing": ["<applicable vendor patch>"]}},
      "prerequisites": {"source": "inventory.json", "sha256": "<same file digest>", "value": ["<CVE-specific condition verified on this target>"]}
    }
  }
]

Each source names a local collector export relative to the selected manifest's directory. An export has collection_method: "authenticated-inventory", the same cve, target, checked_at, vendor, product, platform, and advisory_url as its proof, plus an evidence object mapping the three kinds to their actual values. For example:

{
  "collection_method": "authenticated-inventory",
  "cve": "CVE-2025-33073",
  "target": "192.0.2.10",
  "checked_at": "<UTC timestamp of collection>",
  "vendor": "<vendor>", "product": "<product>", "platform": "<platform>",
  "advisory_url": "<official advisory URL>",
  "evidence": {
    "product_version": "<observed version>",
    "patch_inventory": {"complete": true, "installed": [], "missing": ["<applicable patch>"]},
    "prerequisites": ["<verified CVE-specific condition>"]
  }
}

The operator must select authentic exports from a trusted authenticated collector, including the applicable vendor patch and prerequisite checks. The verifier checks their bytes, binding, freshness, complete patch inventory, and consistency; a file digest by itself does not prove the truth of a capture. Absolute paths, traversal, and paths outside that directory are rejected. Imported JSON cannot select an evidence manifest or authorize its own files.

The verifier fetches the official CVE List record, requires PUBLISHED, checks CVE identity, advisory, product, platform, and affected version range, recomputes SHA-256 over the fetched response bytes, rejects unexpected redirects, and uses the record's severity. Reserved, rejected, missing, mismatched, or unverifiable records do not qualify. Inventory and record verification expire after 24 hours; metadata refreshes at least hourly when used. Only exact versions and numeric semver ranges without status changes are currently supported; custom/git/Maven ordering stays unverified. The inventory proof confirms applicability and missing updates; it does not perform exploitation. Existing historical rows are retained, and legacy vulnerable=true flags without this proof are excluded from current reports.

To revalidate history or a saved report, explicitly supply the current local manifest again. Missing local files, changed bytes, expired inventory, record changes, and legacy confirmation schema 1 remain unverified. SQLite table layouts and existing CLI arguments are preserved; JSON adds result_table and confirmation policy schema 2. Default output remains JSON.

python -m adpentest --history --cve-evidence evidence/proofs.json
python -m adpentest --run-details RUN_ID --cve-evidence evidence/proofs.json --table
python -m adpentest --report-input prior-report.json --cve-evidence evidence/proofs.json --table --html-report report.html

The WebForms dashboard delegates verification to the same Python policy. Administrators can set absolute AdPentestPythonPath, AdPentestWorkingDirectory, and AdPentestCveEvidencePath in app settings. The evidence path is also passed to new scans. Without a configured manifest or a working verifier, no imported CVE is displayed as confirmed.

Kerberos tickets and all-results tables

Install the optional cross-platform ticket client with python -m pip install -e '.[kerberos]' from this checkout. --obtain-tickets requests a TGT for the supplied account and normal TGS only for explicit --ticket-spn values. Dry-run lists planned requests. Active requests require --scope-confirmed, the realm/account/KDC, a private output directory, and a password entered with a secure prompt or read from an explicitly named environment variable. Passwords are never placed in command arguments.

python -m adpentest --obtain-tickets --ticket-domain lab.example --ticket-user researcher --ticket-kdc dc.lab.example --ticket-spn cifs/server.lab.example --table
python -m adpentest --obtain-tickets --ticket-domain lab.example --ticket-user researcher --ticket-kdc dc.lab.example --ticket-spn cifs/server.lab.example --ticket-output-dir private-tickets --mode active --scope-confirmed --table
python -m adpentest --ticket-inventory --ticket-cache FILE:private-tickets/example.ccache --table

Ticket inventory reads local FILE ccaches, including available and expired tickets; other cache backends remain explicitly unsupported. Acquisition and inventory may be combined with --target to include metadata in a scan's JSON, HTML and SQLite tool results. Credential caches are saved separately with mode 0600 in a 0700 directory on Unix; use a directory restricted to the account by ACLs on Windows. Reports include client, service, ticket kind, encryption type, status and expiry, without passwords, keys or ticket bytes.

--table, HTML and WebForms show all CVE candidates, SMB configuration observations, tool outcomes and ticket metadata with their status. Unverified CVEs have informational severity and do not affect CVE risk or active-CVE counts. Successful Kerberos authentication does not establish a vulnerability.

Features

Core Capabilities

  • Auto DC Detection — discovers Domain Controllers via DNS SRV records, LDAP RootDSE probes, port fingerprinting, and subnet sweep
  • Multi-threaded execution — 16 parallel workers for tool execution, 32 workers for port/DNS/credential tasks (10-15x speedup)
  • 40+ AD/SMB/Kerberos/ADCS/Email/WinRM tools — cross-platform binary tools + pure Python implementations
  • 7 CVE scanners — automated detection of critical AD vulnerabilities (CVSS 7.5-9.4)
  • WAF detection & bypass — identifies WAF/CDN vendors and attempts bypass via HTTP spoofing, raw LDAP/Kerberos, TCP fragmentation
  • SQLite scan history — persistent storage of all scan runs, tool results, and CVE findings
  • Auto-install — missing tools installed automatically via apt/pip/git
  • WinRM profiling — anonymous discovery + negotiate/Kerberos authenticated checks, cross-platform
  • EVTX import — Windows event logs → structured JSON → SQLAlchemy ORM → SQLite
  • Privilege audit — Kerberos-authenticated remote token inspection with DB persistence
  • LDAP SPN enumeration — live LDAP SPN collection and offline analysis
  • DNS enumeration — standalone DNS-only AD enumeration without credentials
  • Diagnostic storage — ORM-backed persistence for all tool results with outbox fallback
  • Output volume splitting — automatic 20 MiB volume splitting for large JSON exports
  • Database export — --export-db exports scan history as JSON volumes
  • Safety — dry-run is the default mode; --scope-confirmed required for authorization

Attack Vectors

CategoryToolsDescription
Reconnaissancenmap, masscan, enum4linux-ng, rpcdump, bloodhound-python, ldapdomaindumpNetwork & AD enumeration
SMBsmbclient, smbmap, crackmapexec, impacketNull sessions, share enum, signing detection, credential testing
KerberosGetUserSPNs, AS-REP roast, Kerberoast, kerbruteSPN enum, ticket extraction, user enumeration
ADCScertipy (find, shadow, ESC1, ESC3, ESC9)Certificate template analysis & exploitation
EmailSMTP/POP3/IMAP enum & auth testingUser discovery, credential testing, Exchange detection
Privilege EscalationACL scanner, GPO abuse, delegation chain, auto privescPermission analysis & escalation paths
PersistenceGolden/silver ticket, DCshadow, skeleton key, DSRM, SID historyDomain persistence techniques
WinRMwinrm_check, negotiate, kerberosAnonymous discovery, authenticated profiling, privilege audit
EVTX Importevtx_importWindows event log parsing, JSON conversion, ORM persistence
Diagnosticsdiagnostic_storage, export_dbORM persistence, outbox fallback, JSON volume export
Coercion & RelayPetitPotam, PrinterBug, NTLM relayAuthentication coercion attacks
CVE Scanning7 dedicated scannersCertighost, ResetNightmare, NTLM bypass, RC4, RPC RCE

Installation

From PyPI

pip install adpentest

From Source

git clone https://github.com/netanelcyber/AdPentestAI-Python.git
cd AdPentestAI-Python
pip install -e .

Dependencies

PackageVersionPurpose
httpx>= 0.27HTTP client for EWS/web enumeration
dnspython>= 2.4DNS resolution with SRV record support
ldap3>= 2.9LDAP operations (RootDSE, anonymous bind)
SQLAlchemy>= 2.0, < 3ORM for diagnostic storage and EVTX import
pywinrm>= 0.5, < 1Cross-platform WinRM client (negotiate auth)
python-evtx>= 0.7Windows Event Log (EVTX) parsing
packaging>= 21.0Version handling

Optional (Kerberos): pip install adpentest[kerberos]

Standard library modules used: smtplib, poplib, imaplib, socket, concurrent.futures, subprocess, sqlite3, json.


Usage

Basic Scans

# Dry-run (check tools, detect DCs, preview commands — no actual execution)
adpentest --target 10.0.0.1 --mode dry-run --scope-confirmed

# Active scan with auto DC detection
adpentest --target corp.local --mode active --scope-confirmed

# Custom timeout and no auto-install of missing tools
adpentest --target 192.168.1.10 --mode active --scope-confirmed --timeout 600 --no-auto-install

# Custom DNS servers
adpentest --target corp.local --mode active --scope-confirmed --dns-server 1.1.1.1,8.8.8.8

# Connect via VPN before scanning
adpentest --target 10.10.10.1 --mode active --scope-confirmed --vpn lab.ovpn

Scan History & Reports

# Show all past scan runs
adpentest --history

# Show last 5 runs
adpentest --history --history-limit 5

# Show all vulnerable CVE findings across all runs
adpentest --cve-report

# Show details for a specific run
adpentest --run-details run-8824073e5124-20260904055457

# Use custom database path
adpentest --history --db-path /path/to/custom.db

HTML Pentest Report Generation

Generate an executive-ready, standalone, and interactive HTML penetration test report (<100KB):

# Generate report during active scan
adpentest --target corp.local --mode active --scope-confirmed --html-report report.html

# Generate report from an existing JSON output file
python -m adpentest.report_generator scan_results.json report.html
  • 0.0 - 10.0 Executive Risk Score with CVSS & severity metrics gauge
  • Interactive Dark / Light mode toggle & print-optimized layout
  • Target architecture & Domain Controller detection breakdown
  • Categorized security findings with remediation advice
  • Collapsible tool execution logs with timing and duration metrics

Lab Setup

# Interactive lab setup orchestrator
adpentest --setup-labs

Output Format

All scan output is JSON:

{
  "status": "completed",
  "run_id": "run-abc123-20260901120000",
  "db_path": "~/.adpentest/scan_history.db",
  "dc_detection": {
    "dc_count": 2,
    "detected_domain": "corp.local",
    "domain_controllers": [...]
  },
  "execution": {
    "result_count": 35,
    "completed": 28,
    "failed": 7
  }
}

See examples/sample-dry-run-output.json for a complete example.


WinRM Profiling

Run anonymous WinRM discovery on one authorized target, with optional negotiate or Kerberos authentication:

# Anonymous discovery (works on Windows and Linux)
adpentest --winrm-check --target dc.corp.local --mode active --scope-confirmed --table

# With Kerberos authentication and diagnostics
adpentest --winrm-check --target dc.corp.local --mode active --scope-confirmed \
  --winrm-auth kerberos --winrm-diagnostics --winrm-domain corp.local \
  --db-path winrm.db --html-report winrm.html

# Negotiate auth with explicit test account
adpentest --winrm-check --target dc.corp.local --mode active --scope-confirmed \
  --winrm-auth negotiate --winrm-user testuser@corp.local \
  --winrm-password-env WINRM_PASS --winrm-exec-check

No admin required for discovery. Anonymous WinRM discovery works without credentials or elevated privileges on both Windows and Linux. It probes endpoints, detects WS-Man, extracts NTLM metadata, and reports TLS status — all without authentication. Opt-in authenticated checks (negotiate/Kerberos) use an explicit authorized test account for remote token inspection.

# No admin, no credentials — anonymous discovery only
adpentest --winrm-check --target dc.corp.local --mode active --scope-confirmed --table

# Regular domain user — negotiate auth (no admin needed to probe)
adpentest --winrm-check --target dc.corp.local --mode active --scope-confirmed \
  --winrm-auth negotiate --winrm-user regularuser@corp.local \
  --winrm-password-env PASS --table

See the WinRM guide for all options.


EVTX Log Import

Import Windows Event Log (EVTX) files into the SQLite database:

# Import a single EVTX file
adpentest --evtx-import Security.evtx --db-path scan.db

# Import a directory of EVTX files
adpentest --evtx-import /path/to/evtx-exports/ --db-path scan.db

# Import with JSON output for inspection
adpentest --evtx-import Security.evtx --db-path scan.db --evtx-json events.json

No admin required. EVTX import is an offline operation — it reads exported .evtx files from disk. You only need read access to the EVTX file and write access to the SQLite database. Export EVTX files from any Windows machine using Event Viewer (Save All Events As...) or wevtutil epl as a regular user for logs your account can read (Security log requires admin, but Application, System, and others do not).

# Import logs you exported as a regular user
adpentest --evtx-import Application.evtx System.evtx --db-path analysis.db

# Query imported events
sqlite3 analysis.db "SELECT event_id, time_created, computer FROM evtx_events ORDER BY time_created DESC LIMIT 20"

The pipeline: EVTX binary → structured JSON → SQLAlchemy ORM → SQLite. Duplicate files are deduplicated by SHA-256. Dirty (open/unclean) EVTX files are rejected. All events are indexed by event ID, timestamp, computer, channel, and provider for efficient querying.


Privilege Audit

Kerberos-authenticated privilege auditing with DB persistence:

# Privilege audit with Kerberos
adpentest --audit-auth kerberos --target dc.corp.local \
  --obtain-tickets --ticket-domain corp.local --ticket-kdc dc.corp.local \
  --mode active --scope-confirmed --db-path audit.db

The audit chain: Kerberos auth → WinRM probe → remote token inspection → privilege assessment → SQLite persistence.


LDAP SPN Enumeration

Live LDAP-based SPN collection and analysis:

# Auto-collect and analyze SPNs from a domain
adpentest --ldap-spn-auto dc.corp.local --ldap-spn-save spns.json

# Offline analysis of previously collected data
adpentest --ldap-spn-data spns.json

Queries servicePrincipalName=* via anonymous LDAP bind. Outputs account/SPN pairs with service type classification.

--ldap-spn-save also saves empty results and collection failures, with collection.error and collection.entry_count in the JSON. Exit code 1 means collection failed or was partial; exit code 2 means a save or argument error. collection.connection identifies the attempted endpoint, timeouts and error category, with a PowerShell TCP check on connection failure. WinError 10060 means a timeout; check DC reachability, routing/VPN and the LDAP listener. Explicit --ldap-spn-port values are honored with --ldap-spn-ssl as well. Anonymous access may be refused by AD. --ldap-spn-complete records an operator assertion and does not change LDAP permissions. See the SPN guide for PowerShell commands and the existing large-output volume behavior.


DNS Enumeration

Standalone DNS-only AD enumeration — no credentials required:

# DNS enumeration for a domain
adpentest --dns-enum --target corp.local --dns-enum-save dns-report.json --table

Discovers DCs, KDCs, Global Catalog servers, Kerberos password change, and other AD services via SRV records.


Export Database

Export the scan history database as JSON, with automatic volume splitting for large exports:

# Export to a directory (auto-splits at 20 MiB per volume)
adpentest --export-db /path/to/export/ --db-path scan.db

# Custom volume size (1 MiB)
adpentest --export-db /path/to/export/ --volume-size 1

CVE Scanners

The framework includes 7 built-in CVE scanners that run as part of every scan. All scanners are safe and read-only — they use port probes, anonymous LDAP queries, and raw protocol checks only.

CVENameCVSSDescription
CVE-2026-59270Spring LDAP9.4Hardcoded credentials in Spring Security embedded LDAP (UnboundIdContainer)
CVE-2026-54121Certighost8.8AD CS enrollment bypass — certificate enrollment for arbitrary computer accounts
CVE-2025-54918NTLM LDAP Bypass8.1NTLM authentication bypass on DC LDAP — privilege escalation to SYSTEM
CVE-2026-33826AD RPC RCE8.0Windows AD RPC remote code execution via improper input validation
CVE-2026-27912ResetNightmare8.0Kerberos kpasswd password reset bypass via UPN collision — full domain takeover
CVE-2026-24294NTLM Reflection7.8NTLM reflection via SMB port multiplexing (Server 2025 / Win 11 24H2)
CVE-2026-20833Kerberos RC47.5KDC accepts RC4-HMAC encryption — enables Kerberoasting attacks

What Each Scanner Checks

CVE-2026-59270 — Attempts LDAP bind with known hardcoded credentials (uid=admin,ou=system / secret) on ports 389, 636, 53389, 33389, 10389, 8389. Reports exposed entry count.

CVE-2026-54121 — Queries AD CS Enrollment Services and certificate templates via LDAP. Identifies templates with ENROLLEE_SUPPLIES_SUBJECT flag or risky enrollment configurations.

CVE-2025-54918 — Checks if LDAP accepts NTLM/GSS-SPNEGO authentication without enforced signing. Extracts DC functional level and domain context.

CVE-2026-33826 — Probes RPC endpoint mapper (port 135), confirms AD DC via LDAP, checks for exposed RPC-related ports (135, 593, 445, 139).

CVE-2026-27912 — Checks if kpasswd (port 464) and Kerberos (port 88) are open. Queries ms-DS-MachineAccountQuota to assess exploitation feasibility.

CVE-2026-24294 — Sends SMB2 Negotiate to detect protocol version and signing mode. Checks for alternative SMB ports (8445, 9445, etc.) indicating port multiplexing.

CVE-2026-20833 — Sends raw Kerberos AS-REQ with RC4 (etype 23), AES256 (etype 18), and AES128 (etype 17) to detect which encryption types the KDC accepts.


WAF Detection & Bypass

When scanning targets behind WAF/CDN services, the framework automatically:

  1. Detects WAF vendor — checks HTTP headers and body content for signatures of 17+ WAF vendors (Incapsula/Imperva, Cloudflare, Akamai, AWS WAF, Azure Front Door, Sucuri, etc.)
  2. Attempts bypass via 5 technique layers:
    • HTTP bypass — header spoofing (X-Forwarded-For, X-Real-IP, CF-Connecting-IP), User-Agent rotation, path obfuscation, verb tampering
    • Raw LDAP — BER-encoded LDAPv3 anonymous bind directly to port 389
    • Raw Kerberos — AS-REQ with TCP framing to port 88
    • TCP fragmentation — 1 byte per TCP segment with TCP_NODELAY
    • Email/HTTP — OWA, EWS NTLM handshake, Autodiscover, ActiveSync, MAPI probing

If raw LDAP or Kerberos bypasses the WAF, the framework extracts domain info and adjusts DC detection confidence accordingly.


Scan History Database

All scan data is automatically stored in SQLite at ~/.adpentest/scan_history.db.

Database Schema

scan_runs — One row per scan execution:

  • run_id, target, mode, started_at, finished_at, status
  • dc_count, live_hosts, tools_executed, tools_succeeded, tools_failed
  • cves_checked, cves_vulnerable

tool_results — One row per tool execution:

  • tool, host, is_dc, fqdn, status, duration_sec, output, error

cve_findings — One row per CVE check:

  • cve_id, target, cvss, severity, vulnerable, impact, details_json

Querying Directly

# Open the database
sqlite3 ~/.adpentest/scan_history.db

# All vulnerable findings
SELECT cve_id, target, cvss, severity, impact FROM cve_findings WHERE vulnerable=1 ORDER BY cvss DESC;

# Scan history summary
SELECT run_id, target, mode, status, tools_executed, cves_vulnerable, started_at FROM scan_runs ORDER BY started_at DESC;

# Tool success rate
SELECT tool, COUNT(*) as runs, SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as ok FROM tool_results GROUP BY tool ORDER BY runs DESC;

DC Detection Strategies

The framework uses a multi-strategy pipeline to discover Domain Controllers:

StrategyMethodConfidence
DNS SRVQueries _ldap._tcp.dc._msdcs.<domain>High (0.9)
LDAP RootDSEAnonymous bind to extract domain/forest infoHigh (0.9)
Port fingerprintChecks Kerberos (88), LDAP (389/636), GC (3268/3269)Medium (0.7)
Subnet sweepKerberos port 88 scan on /24 → /23 → /22Medium (0.6)

When WAF is detected blocking ports, the bypass engine runs automatically. If raw LDAP/Kerberos bypasses succeed, confidence is adjusted to 0.7 ("waf-bypassed"); otherwise 0.1 ("waf-blocked").


Tool Registry

Available Tools (35+)

Binary tools: nmap, masscan, enum4linux-ng, rpcdump, smbclient, bloodhound-python, certipy, ldapdomaindump, kerbrute, crackmapexec, smbmap, impacket (secretsdump, psexec)

Windows-native: powershell_ldap_enum, powershell_smb_enum, powershell_ad_recon

Kerberos: GetUserSPNs, AS_REP_roast, kerberoast

ADCS: certipy_shadow, certipy_esc1, certipy_esc3, certipy_esc9

Email: smtp_enum, smtp_auth_test, pop3_auth_test, imap_auth_test, email_server_discovery

Exploitation: ntlm_null_session, auto_privesc, golden_ticket, silver_ticket, delegation_abuse, trust_enumeration, trust_abuse, petitpotam, printerbug, ntlm_relay, acl_scanner, acl_exploit, gpo_abuse, delegation_chain, sid_history, dsrm_backdoor, dcshadow, golden_gmsa, skeleton_key

CVE scanners: cve_2026_59270, cve_2026_54121, cve_2025_54918, cve_2026_33826, cve_2026_27912, cve_2026_24294, cve_2026_20833


SMB protocol version testing

The built-in smb_version_test tool negotiates SMB 2.0.2, 2.1, 3.0, 3.0.2, and 3.1.1 on TCP 445 and independently checks SMBv1. It uses the current Python interpreter and is included in the careful active tool set. Dry-run only previews its command; active execution sends negotiation requests without authenticating or accessing shares.

The API is also available independently of the full scan workflow:

from adpentest.core import test_smb_versions

result = test_smb_versions("192.0.2.10", timeout=5.0)

Existing result keys are retained. Support and security fields use true for an observed positive, false for an explicit negative, and null when the probe is inconclusive. Each entry in dialect_results retains its negotiation error and status code. max_dialect is the highest successfully observed dialect; partial failures return completed-with-errors. Signing and encryption fields describe that dialect. Encryption capability does not establish share encryption enforcement, and SMBv1 support does not confirm a specific CVE.

Wire formats follow Microsoft's SMB2 NEGOTIATE request and response specifications, including SMB 3.1.1 preauthentication and encryption contexts.

Email Protocol Enumeration

Pure Python email enumeration using standard library (no external dependencies):

  • SMTP VRFY — discover valid usernames via VRFY command
  • SMTP RCPT TO — validate recipients via RCPT TO
  • Credential testing — automatic fallback chain: SMTP → POP3 → IMAP
  • Exchange detection — OWA, EWS NTLM handshake (extracts domain/DC/forest from NTLM challenge), Autodiscover, ActiveSync, MAPI
  • Parallel testing — 32 concurrent workers for credential testing

Ports scanned: 25, 465, 587 (SMTP), 110, 995 (POP3), 143, 993 (IMAP).


DNS Configuration

Priority Order

  1. CLI arguments (--dns-server, --dns-timeout) — highest priority
  2. Environment variables (DNS_SERVERS, DNS_TIMEOUT)
  3. System default DNS — auto-detected
  4. Public DNS fallback — Google (8.8.8.8, 8.8.4.4), Cloudflare (1.1.1.1, 1.0.0.1)
# CLI
adpentest --target corp.local --mode active --scope-confirmed --dns-server 192.168.1.1,8.8.8.8 --dns-timeout 5.0

# Environment
export DNS_SERVERS=192.168.1.1,1.1.1.1
export DNS_TIMEOUT=5.0
adpentest --target corp.local --mode active --scope-confirmed

Architecture

Single-File Design

All framework logic is in adpentest/core.py. This monolithic approach provides clear dependency flow, centralized tool registry, unified error handling, and easy deployment.

Execution Pipeline

Input: --target 10.0.0.1 --mode active --scope-confirmed
  │
  ├── Scope validation (dry-run vs active)
  ├── Tool discovery (scan $PATH)
  ├── SQLite run initialization
  │
  ├── DC Detection (multi-strategy)
  │   ├── DNS SRV queries
  │   ├── LDAP RootDSE probe
  │   ├── Port fingerprint (+ WAF detect/bypass)
  │   └── Subnet sweep (/24 → /23 → /22)
  │
  ├── Domain discovery + FQDN resolution
  ├── Email server discovery (MX + port scan)
  │
  ├── Parallel Tool Execution (ThreadPoolExecutor, 16 workers)
  │   ├── AD tools against DCs (prioritized)
  │   ├── CVE scanners against all targets
  │   └── Results → SQLite (tool_results + cve_findings)
  │
  └── Output: JSON + SQLite database

Threading Model

PoolWorkersPurpose
Tool execution16AD diagnostic tools in parallel
Port scanning32Concurrent TCP port checks
DNS resolution32Concurrent DNS queries
Credential testing32SMTP/POP3/IMAP auth testing

Contributing

Contributions are welcome! See CONTRIBUTING.md for setup instructions and CODE_OF_CONDUCT.md for community guidelines.

Check the open issues for tasks labeled good-first-issue or help-wanted.

Adding a New CVE Scanner

  1. Add scanner function scan_cve_YYYY_NNNNN(target, timeout) returning a dict with cve, cvss, severity, vulnerable, impact, remediation
  2. Add tool name cve_YYYY_NNNNN_short_name to AD_TOOLS set
  3. Add to PIP_PACKAGES (empty list for pure Python)
  4. Add to EXECUTABLES (python3/python/python.exe)
  5. Add build_ad_command handler

Adding a New Tool

  1. Add tool name to AD_TOOLS set
  2. Add package mapping to PIP_PACKAGES/APT_PACKAGES/WINGET_PACKAGES
  3. Add executable names to EXECUTABLES dict
  4. Implement command building in build_ad_command()

License

MIT


Disclaimer: This tool is designed for authorized penetration testing and security research only. Users are responsible for obtaining proper authorization before testing any systems. The authors assume no liability for misuse.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
3.4.720 Oct 202610

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
netanelcyber/adpentestai-python

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:48 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:fb6a31a466518356d76c420854b368546e5a09c9b33ebd70edf97fb5d0afec2e