Skip to content

cumakurt/adar

Repository files navigation

ADAR — Active Directory Attack & Reconnaissance Tool

License: AGPL v3 Python 3.10+

For authorized penetration testing use only. Unauthorized use against systems you do not own or have permission to test may be illegal.
Turkish documentation: README.tr.md


Architecture Overview

adar/
├── core/
│   ├── engine.py              # Main orchestration engine (ScanEngine)
│   ├── result_store.py        # Async-safe user aggregation & dedup
│   └── noise_controller.py   # Adaptive rate limiting & jitter
├── techniques/
│   ├── base.py                # Abstract BaseTechnique
│   ├── dns_enum.py            # [T1] DNS SRV record queries
│   ├── ldap_enum.py           # [T1] LDAP anonymous bind + paged dump
│   ├── kerberos_enum.py       # [T1] Kerberos AS-REQ user probing (wordlist or built-in)
│   ├── smb_enum.py            # [T1] SMB null session probe
│   ├── samr_enum.py           # [T2] MS-SAMR user enumeration
│   ├── rid_cycling.py         # [T2] SID+RID brute-force (500-2000)
│   ├── oxid_resolver.py       # [T2] OXID ServerAlive2 interface enum
│   ├── ldap_auth_enum.py      # [T3] Authenticated LDAP full attribute dump
│   ├── asreproast_enum.py     # [T3] AS-REP Roasting — hashcat hash dump
│   ├── kerberoast_enum.py     # [T3] Kerberoasting SPN accounts
│   ├── sysvol_enum.py         # [T3] SYSVOL/GPO script & Groups.xml parse
│   ├── adcs_enum.py           # [T4] ADCS cert template enum + ESC1/2/3/4 vuln detection
│   ├── azure_enum.py          # [T4] Azure AD GetCredentialType user enum
│   ├── smtp_enum.py           # [T4] SMTP VRFY/EXPN user validation
│   ├── owa_timing.py          # [T4] OWA/EWS HTTP timing side-channel
│   ├── printer_spooler.py     # [T4] MS-RPRN job owner enum + PrinterBug detection
│   └── ldap_referral.py       # [T2] Forest/trust referral chase
├── intelligence/
│   ├── dc_fingerprint.py      # DC service & capability detection
│   └── technique_selector.py  # Tier-aware technique pipeline builder
├── output/
│   └── reporter.py            # Rich terminal + JSON + CSV + HTML
├── types_/
│   └── models.py              # Pydantic v2 models & enums
└── adar.py                    # Click CLI entry point

Installation

From GitHub (recommended):

git clone https://github.com/cumakurt/adar.git
cd adar
python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e .
adar --help

From source (requirements only):

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python adar.py --help

Requires Python 3.10+. See requirements.txt for dependencies.


Usage

Basic scan (no credentials)

Domain is auto-discovered if omitted (LDAP/SMB/Kerberos/rDNS).

python adar.py -t 192.168.1.10
python adar.py -t 192.168.1.10 -d corp.local

Without credentials, all unauthenticated tactics run: Tier 1–2 and credential-free Tier 4 (DNS, LDAP anon, Kerberos AS-REQ, SMB null, LLMNR/passive listener, OXID, SAMR, RID cycling, DNS LDAP dump, Global Catalog, SCCM, MS-RPRN). With default --noise high, techniques run at maximum speed unless you explicitly lower the noise budget.

Kerberos, Azure and OWA user enumeration

If no wordlist (-w) is given, Kerberos uses the embedded smart list (administrator, guest, krbtgt, etc.); Azure enum and OWA timing also use the embedded list when no wordlist is provided (see Tier 4 details below).

python adar.py -t 192.168.1.10 -d corp.local -w /path/to/users.txt

Authenticated scan

python adar.py -t dc01.corp.local -d corp.local \
  -u admin -p 'Password1!' \
  -f json -f html -o ./reports/

Note: Tier 3 techniques (ldap_auth, kerberoast, etc.) are required for full user discovery. They run only with --profile default or --profile full. --profile stealth uses only Tier 1–2; no user enum even when credentials are provided.

Stealth mode (IDS evasion)

python adar.py -t 10.0.0.5 -d lab.test \
  --noise very_low --timeout 15 -w users.txt

Pass-the-Hash (NT hash)

python adar.py -t 10.0.0.5 -d corp.local \
  -u admin --hash aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0

CLI Parameters

Parameter Short Default Description
--target -t required DC IP or hostname
--domain -d AD domain (auto-discovered if omitted)
--username -u Username
--password -p Password
--hash NTLM hash
--wordlist -w User list for Kerberos, Azure AD, OWA timing, SMTP VRFY
--profile default default (all tiers), stealth (T1–2 only), full, soc-full
--noise high very_low / low / medium / high
--timeout 10 Connection timeout (seconds)
--output-dir -o . Report output directory
--format -f terminal,json,html Output format (repeatable)
--concurrent 3 Concurrent techniques per tier
--listen-time 60 (stealth: 300) Passive listener duration (seconds)
--verbose -v false Debug logging

Example JSON Output

{
  "username": "admin",
  "confidence": "confirmed",
  "found_by": ["kerberos_enum", "ldap_anon"],
  "attributes": {
    "email": "admin@corp.local",
    "display_name": "Admin",
    "groups": ["Domain Users", "IT Staff"],
    "enabled": true
  },
  "timestamp": "2024-01-15T10:23:41Z"
}

Technique Details

Unauthenticated techniques (Tier summary)

Tier Technique Description
T1 DNS enum SRV records, zone transfer attempt
T1 LDAP anon Anonymous bind + user search
T1 Kerberos enum AS-REQ user existence check (wordlist or built-in)
T1 SMB null Null session, OS/domain info
T1 LLMNR/NBT-NS listener Passive; name queries and NTLM capture
T1 Passive traffic mDNS/NBNS passive listen
T2 LDAP referral Forest/trust referral chase
T2 OXID resolver RPC endpoint list
T2 SAMR MS-SAMR user list (null/auth)
T2 RID cycling SID+RID account name resolution
T2 DNS LDAP dump ADIDNSdump-style DNS record dump
T2 Global Catalog GC bind + user search
T2 SCCM enum SCCM/MDT MP and NAA discovery
T4 Printer Spooler MS-RPRN job owner enum, PrinterBug check

Tier 3 (LDAP auth, AS-REP Roasting, Kerberoasting, SYSVOL, vulnerable accounts) requires credentials (-u/-p or --hash). ADCS in T4 requires credentials; Azure enum and OWA timing do not require credentials and use the embedded smart list when no wordlist is given (see “Azure and OWA details” below).


Enumeration Techniques — Detailed

Each technique is described with method (how it works) and rationale (why it is used).

Tier 1 — Unauthenticated, minimal noise

Technique Method Rationale
dns_enum Queries standard AD DNS SRV records (_kerberos._tcp, _ldap._tcp, _ldap._tcp.dc._msdcs, _gc._tcp, etc.) via the target as DNS server. Optionally probes TXT and zone transfer. Confirms DC presence and discovers additional DCs/forest members without any authentication. Purely passive from an AD auth perspective; only DNS traffic.
ldap_anon Binds to LDAP (port 389) with anonymous authentication. Tries multiple strategies: (1) paged user search with full attributes, (2) minimal attributes (sAMAccountName) with alternate filters, (3) well-known accounts (Administrator, Guest, krbtgt) by DN, (4) CN=Users subtree. Many misconfigured or legacy DCs allow anonymous LDAP bind; this yields a direct list of user objects when ACLs permit. Very low noise.
kerberos_enum Sends Kerberos AS-REQ (Authentication Service Request) for each candidate username (wordlist or embedded smart list). Interprets KDC response: KDC_ERR_PREAUTH_REQUIRED (25) → user exists; KDC_ERR_C_PRINCIPAL_UNKNOWN (6) → user does not exist. The KDC reveals user existence without requiring a password. Industry-standard user enumeration method; wordlist-driven and throttleable.
smb_null Establishes an unauthenticated (null) SMB session to port 445 (empty username/password). Retrieves NetBIOS domain name, DNS hostname, and OS version via SMB calls. Confirms that null session is allowed, which is a prerequisite for SAMR/RID cycling on older DCs. Does not enumerate users itself but enriches DC fingerprint.
llmnr_listener Passive only (no packet injection). Binds to LLMNR (UDP 5355, multicast 224.0.0.252), NBT-NS (UDP 137), and mDNS (UDP 5353). Captures hostname queries and, when present, NTLM Type-1/2/3 messages (usernames and optionally NTLMv2 hashes). Equivalent to Responder “analysis” mode: observes what names hosts request and any NTLM traffic on the wire. Zero risk of poisoning; useful for user/hash discovery in shared segments.
passive_traffic Fully passive — sends no packets. Sniffs mDNS (UDP 5353) and NBNS (UDP 137) on the local segment. Extracts machine names and infers computer accounts (HOSTNAME$) and possible usernames from naming conventions. Complements LLMNR listener with multicast/broadcast-only capture. Reveals hostnames and naming patterns that often map to AD users; requires CAP_NET_RAW.

Tier 2 — Passive / side-channel / low auth

Technique Method Rationale
ldap_referral Queries the domain’s trustedDomain objects via LDAP to list forest and external trusts. For INBOUND/BIDIRECTIONAL trusts, follows LDAP referrals to the trusted DC and attempts anonymous bind and base DN / user enumeration. Trust map is essential for cross-domain and forest escalation. Referral chase can yield users in trusted domains when anonymous bind is allowed there.
oxid_resolver Single RPC call to IObjectExporter::ServerAlive2 on port 135 (RPC Endpoint Mapper). Parses the response for network interface strings (IPs and hostnames). Reveals alternate hostnames and IPs the DC exposes; used as recon for later techniques and for pivot targets. Very low noise (one call).
samr_enum Uses MS-SAMR over the \pipe\samr SMB named pipe. Connects with null session or provided credentials, opens domain handle, and enumerates users via SamrEnumerateUsersInDomain (paged). SAMR is the canonical way to list domain users over the network. Null session works on legacy DCs; modern DCs require credentials. Results are CONFIRMED when authenticated.
rid_cycling (1) Resolves domain SID via LSA or SAMR. (2) Builds SID+RID combinations for RIDs 500–2000 (configurable). (3) Uses MS-SAMR LookupRids in batches to resolve RID → account name. Filters out group RIDs (512–520), keeps users. When SAMR enumeration is restricted, RID cycling still resolves known RIDs (e.g. 500=Administrator) and discovers additional accounts by brute-forcing RID space.
dns_ldap_dump adidnsdump-style: queries LDAP partitions DC=DomainDnsZones and DC=ForestDnsZones for DNS nodes. Parses dnsRecord binary blobs, builds hostname→IP map, and derives service account candidates from naming (e.g. svc-, sql-, web-). AD-integrated DNS is stored in LDAP; dumping it reveals hostnames and hidden records. Service account names inferred from hostnames are high-value targets. Works anonymous when allowed; better with credentials.
global_catalog Connects to Global Catalog (port 3268 or 3269 for LDAPS). Search base ""; queries for user objects across the entire forest. Uses paged search with user attributes. GC holds a partial replica of every domain in the forest; one connection can enumerate users from all child domains without knowing their DNs. Anonymous possible on some DCs; credentials improve coverage.
sccm_enum (1) LDAP: finds SCCM Management Points and sites. (2) HTTP: probes MP endpoints for XML that may contain usernames. (3) SMB: checks MDT shares for Bootstrap.ini / CustomSettings.ini with NAA credentials. SCCM/MDT often store deployment and NAA credentials in plaintext. Discovering MPs and parsing config files yields service accounts and sometimes passwords.

Tier 3 — Credential-required

Technique Method Rationale
ldap_auth Binds to LDAP (389) or LDAPS (636) with provided credentials (Simple or NTLM). Performs paged search for all user objects with a full attribute set. With valid credentials, LDAP is the highest-fidelity source of user and group data. Single technique for complete user dump and attributes.
asreproast (1) LDAP (authenticated): finds users with DONT_REQUIRE_PREAUTH. (2) Sends AS-REQ for each such user (no preauth). (3) Extracts the encrypted AS-REP part and outputs hashcat format. Accounts without preauth can be “roasted”: the KDC returns an encrypted ticket that can be cracked offline.
kerberoast (1) LDAP (authenticated): queries users with servicePrincipalName set (and not disabled). (2) Uses provided credentials to get a TGT, then requests TGS for each SPN. (3) Extracts RC4-encrypted service ticket part in hashcat format. Service accounts with SPNs get TGS tickets encrypted with their password-derived key; these hashes can be cracked offline. Standard Kerberoasting.
sysvol_enum Connects via SMB with credentials to SYSVOL and NETLOGON. Recursively walks shares for GPO-related files. Parses Groups.xml and other GPO XML for cpassword (GPP encrypted password); decrypts with Microsoft’s published AES key. GPP often contained credentials; cpassword is decryptable. Finding plaintext GPP credentials is critical for privilege escalation and lateral movement.
ldap_vuln_accounts LDAP (authenticated): searches for accounts with sensitive userAccountControl flags and adminCount=1. Scans description for regex patterns indicating embedded passwords. Weak UAC settings and credentials in description fields are common misconfigurations. This technique flags high-value and easily abused accounts.

Tier 4 — Specialised / advanced

Technique Method Rationale
adcs_enum LDAP (authenticated): reads Configuration partition for certificate templates and CAs. Evaluates templates for ESC1–8. Extracts enrollable principals from ACEs. AD CS misconfigurations (ESC1–8) allow privilege escalation. Enumeration identifies vulnerable templates and high-value accounts that can enroll.
azure_enum Calls the unauthenticated GetCredentialType API on login.microsoftonline.com for the target domain. Sends candidate usernames (embedded list or wordlist); interprets IfExistsResult (0/5/6 = exists, 1 = not found). Only runs if the domain is registered in Azure (OpenID config probe). Hybrid and cloud-only Azure AD accounts can be enumerated via this public API.
smtp_enum Probes SMTP (port 25, fallbacks 587/465/2525). Tries VRFY first; if disabled (501/502), falls back to EXPN. For each candidate, parses reply: 2xx = user exists, 5xx = not found. Rate-limited with jitter. Legacy and misconfigured SMTP servers reveal valid mailboxes without authentication.
owa_timing Timing side-channel: discovers OWA/EWS endpoints. Sends auth requests with known-invalid usernames to establish a baseline response time. For each candidate, compares average response time; significantly slower responses indicate valid account. Confidence POSSIBLE due to false positives under load. Exchange/OWA often take longer to respond for valid users than invalid ones. Allows user enumeration without valid credentials when other methods are locked down.
printer_spooler Uses MS-RPRN over \pipe\spoolss. Calls EnumPrinters and EnumJobs to list printers and print job owners (usernames). Optionally checks OpenPrinterEx without credentials to assess PrinterBug (SpoolSample) NTLM relay surface. Print jobs are owned by real AD accounts; enumerating job owners reveals users and often privileged or service accounts. PrinterBug check identifies relay targets.

Azure and OWA enumeration — when they run, how to test

Both techniques run when their preconditions are met. They use the embedded smart username list when no wordlist is provided.

Azure enum (azure_enum)

  • When it runs: (1) Target domain must be registered in Azure AD (verified via OpenID config probe). (2) Candidate usernames come from -w wordlist if provided, otherwise from the embedded smart list.
  • How to verify: Request https://login.microsoftonline.com/{domain}/.well-known/openid-configuration; look for microsoftonline.com or login.windows.net in the issuer field. If not found, the technique is skipped.
  • How to test: If the domain is in Azure, POST user@domain to the GetCredentialType API (/common/GetCredentialType). IfExistsResult: 0/5/6 → user exists, 1 → not found.
  • Summary: If the domain is not an Azure AD tenant, Azure enum is skipped. Example: adar -t dc -d corp.local --profile full (uses embedded list); add -w users.txt to extend with a file.

OWA timing (owa_timing)

  • When it runs: (1) OWA must be reachable on the target: ports 443 or 80 open and an OWA/EWS endpoint discoverable. (2) Candidates come from wordlist if provided, otherwise from the embedded smart list.
  • How it is discovered: Check that 443/80 is open on the target, then probe: /owa/auth.owa, /owa/, /EWS/Exchange.asmx, /autodiscover/autodiscover.xml, /Microsoft-Server-ActiveSync. The first URL that does not return 5xx is used as the OWA endpoint.
  • How to test: Establish a timing baseline with known-invalid usernames (e.g. nonexistent_user_xzqj7). For each candidate, send an OWA login POST and measure response time; values clearly above the baseline (e.g. ~80 ms + 2σ) are treated as “likely valid” (timing side-channel).
  • Summary: If the target has no HTTP/HTTPS or OWA (e.g. target is only a DC), OWA timing is skipped or ends with “No OWA endpoint discovered”. To test OWA, the target must serve Exchange/OWA; -w users.txt is optional (embedded list is used otherwise).

Noise levels

Level Use case Delay
very_low Stealth — passive/DNS 0.5s + jitter
low Normal pentest 0.2s + jitter
medium Fast scan 0.05s + jitter
high Maximum speed 0s + jitter

Confidence scores

Score Meaning
confirmed Definitive — LDAP attribute dump or KDC_ERR_PREAUTH_REQUIRED
probable Likely valid — multiple sources
possible Weak signal — single source, indirect

License

GNU Affero General Public License v3.0 (AGPL-3.0) — see LICENSE. Use only for authorized security testing.

Developer

About

Active Directory reconnaissance & attack tool for authorized pentesting — LDAP, Kerberos, user enum, Kerberoasting, AS-REP Roasting, risk scoring. T1–T4 techniques.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages