Internal Network & Active Directory · intermediate · ~12 min
**What you will learn** - Explain the four workhorse Active Directory (AD) credential attacks — password spraying, Kerberoasting, AS-REP roasting, and credential reuse / pass-the-hash — and the exact precondition each one needs. - Read a threat model that shows which AD asset is protected, where the trust boundary sits, and which insecure assumption each attack abuses. - Detect each attack from Windows Security logs (Event IDs 4625, 4768, 4769, 4776) and describe the signals that separate abuse from normal noise. - Apply and *verify* the standard defenses: managed service-account passwords, LAPS, enforced Kerberos pre-authentication, and tiered administration. - Distinguish decoding a ticket or hash from *cracking* it, and state why a lab is the only place to reproduce any of this.
Security objective. The asset you are protecting is the set of domain credentials — user passwords, service-account passwords, and the NTLM password hashes stored on domain members. The threats are attackers who already have a low-privilege foothold (a single domain user, or local admin on one workstation) and want to escalate to more accounts and, ultimately, to Domain Admin. By the end of this lesson you will be able to detect these attacks in logs and prevent them by removing the weak or exposed secrets they depend on.
Active Directory (AD) is the Windows service that manages users, computers, groups, and logins across an organization. This lesson covers the credential attacks that most often compromise AD domains in real engagements. They are:
What they share: they all abuse weak or exposed secrets, not flaws in the cryptography. Kerberos and NTLM do exactly what they were designed to do; the attacker exploits a password that is guessable or a hash that was left reachable.
This builds directly on your prerequisites. From "Kerberos and NTLM authentication" you already know that Kerberos issues a TGT and then per-service TGS tickets, and that NTLM stores a password as an unsalted hash — those two facts are exactly what Kerberoasting and pass-the-hash abuse. From "LDAP and domain enumeration" you know how to query the directory (for example, to list accounts that have a Service Principal Name, or SPN) — that enumeration is the step that tells an authorized tester which accounts are even roastable.
Authorization first. Everything here is for systems you own or are explicitly authorized in writing to test. Labs run on localhost, containers, or an intentionally-vulnerable AD lab (for example a self-built Windows Server domain controller with lab workstations, or a purpose-built training range). Never run any of this against a production domain or a third party.
In authorized engagements these are the attacks that actually take over domains. They rarely need a memory-corruption exploit or a zero-day. They need one predictable password, one service account with a weak secret, one account with pre-authentication accidentally disabled, or one local-admin password shared across every desktop.
Because they are configuration and password problems, understanding the precondition for each attack tells you both how to find it (when authorized) and how to close it. That symmetry is the whole point of this lesson: the same knowledge that lets a red-teamer prove the risk lets a blue-teamer eliminate it.
The defenses are practical and shippable: long random managed passwords for service accounts (gMSAs), LAPS so every machine has a unique local-admin password, keeping Kerberos pre-authentication enforced, tiering admin accounts so a workstation compromise cannot reach a domain controller, and monitoring the handful of Event IDs that reveal each attack. A defender who does these five things removes almost the entire class — which is why professionals treat this lesson as a defensive checklist first and an offensive catalog second.
Each attack below is taught as: definition, plain explanation, how it works, when it applies (and when it does not), and a pitfall. A shared threat model and knowledge checks follow.
Definition. Trying one password against many accounts, deliberately staying under the account-lockout threshold.
Plain explanation. Classic brute force hammers one account with thousands of guesses and locks it out fast. Spraying flips the shape: pick a single plausible password (like a season-plus-year) and try it once against every user. In a large directory, someone is almost always using it.
How it works. The attacker enumerates valid usernames (often from the prerequisite LDAP lesson), reads the domain's lockout policy, then tries a single guess per account and pauses ("low and slow") so no account reaches its bad-password count. Each failed attempt is a logon failure on the domain controller (DC).
When it applies / when not. Applies wherever accounts allow weak passwords and lockout is lenient or windows reset quickly. It does not work well against accounts protected by MFA, or where a low lockout threshold plus a long observation window makes even one guess-per-account risky to the attacker.
Pitfall (defender). A lockout threshold set too aggressively becomes a self-inflicted denial of service — a sprayer can lock out the whole company on purpose. Tune lockout and add detection; do not rely on lockout alone.
Definition. Requesting a Kerberos service ticket (TGS) for an account that has a Service Principal Name (SPN), then cracking that ticket offline to recover the service account's password.
Plain explanation. Any authenticated domain user may ask the DC for a service ticket to any service. Part of that ticket is encrypted with the target service account's password-derived key. Take the ticket offline and guess passwords until one decrypts it correctly.
How it works. (1) An authenticated user requests a TGS for an SPN (a Kerberos TGS-REQ). (2) The DC returns a ticket encrypted with the service account's key. (3) The attacker extracts the encrypted portion and runs an offline dictionary/brute-force attack on their own machine. Because the cracking happens offline, it triggers no lockout and no noise on the target.
When it applies / when not. Applies to any account that has an SPN and a crackable (human-chosen, short) password. It does not meaningfully apply to accounts with 25+ character random managed passwords (gMSA/dMSA) — those are computationally infeasible to crack — nor to computer accounts, which already use long random passwords.
Pitfall. People assume requesting the ticket is the attack. It is not — requesting a TGS is normal Kerberos traffic. The damage only happens if the password is weak enough to crack. That is why the fix is password strength, not blocking ticket requests.
Definition. Recovering crackable material from accounts that have Kerberos pre-authentication disabled, without needing any valid credentials.
Plain explanation. Normally, before the DC will hand out an initial ticket, the client must prove it knows the password (pre-authentication). If an account has pre-auth turned off, the DC will return an AS-REP containing a blob encrypted with the account's password key to anyone who asks — no login required.
How it works. (1) The attacker finds accounts with the "do not require Kerberos pre-authentication" flag (via LDAP). (2) They send an AS-REQ for that account. (3) The DC replies with an AS-REP whose encrypted part can be cracked offline, just like Kerberoasting — but with the extra danger that no authentication was needed to obtain it.
When it applies / when not. Applies only to accounts explicitly configured without pre-authentication (a legacy or compatibility setting). It does not apply to normal accounts, which enforce pre-auth by default.
Pitfall. The setting is often enabled years ago for a since-retired application and forgotten. Treat any account with pre-auth disabled as an audit finding even if nobody remembers why it exists.
Definition. Using a reused password — or the recovered NTLM hash of a password — to authenticate to additional machines.
Plain explanation. NTLM authentication proves you know the hash, not the plaintext. So if an attacker recovers a local-admin NTLM hash from one machine and that same local-admin credential exists on many machines, the hash alone opens all of them. This is the engine of lateral movement — hopping host to host.
How it works. (1) Attacker gets local admin on one host and reads cached credential material. (2) The same local-admin secret is reused across the fleet (a common misconfiguration). (3) The attacker authenticates to the next host with the hash — no cracking required — and repeats.
When it applies / when not. Applies wherever a credential (especially local admin) is shared across machines, or where privileged accounts log on to lower-trust hosts and leave reusable material behind. It does not apply where every machine has a unique local-admin password (LAPS) and admin tiers never expose high-privilege credentials to low-trust hosts.
Pitfall. Rotating the plaintext password everywhere but keeping it identical does not help — identical passwords produce identical hashes. Uniqueness per machine (LAPS) is what breaks the chain.
TRUST BOUNDARY (authentication)
|
ENTRY POINTS v PROTECTED ASSETS
------------ +-------------+ ----------------
low-priv domain user ----> | Domain | user passwords
local admin on 1 host ----> | Controller | -> service-account secrets
network position ----> | (AD / KDC) | NTLM hashes on members
+-------------+ path to Domain Admin
|
+--------------------------+--------------------------+
| | | |
spraying Kerberoast AS-REP roast pass-the-hash
(guess weak (crack SPN (crack pre-auth- (reuse hash across
password) account pw disabled acct) shared-cred hosts)
OFFLINE) OFFLINE, no auth)
Insecure assumptions abused:
- "nobody uses a guessable password" -> spraying
- "a ticket request is harmless" -> Kerberoasting (weak SPN pw)
- "pre-auth is always on" -> AS-REP roasting
- "one local-admin password is convenient" -> pass-the-hash
Knowledge check 1. What asset is protected in this threat model, and what is the trust boundary the attacks are trying to cross? (The domain's credentials and the path to Domain Admin; the boundary is authentication at the DC / KDC.)
Knowledge check 2. Which insecure assumption makes Kerberoasting possible, and why is requesting the ticket itself not the vulnerability? (The assumption that a service account's human-chosen password is strong; the request is normal Kerberos — the weakness is a crackable password.)
Knowledge check 3. Which Windows Security events would you correlate to distinguish a password spray from a single user mistyping their password, and why must this only be reproduced in an authorized lab? (A burst of Event ID 4625 / 4768 pre-auth failures across many distinct accounts from one source in a short window, versus repeated 4625s on one account; running it live would be unauthorized access and could lock out real users.)
The building blocks are LDAP filters (to find roastable accounts) and Kerberos message types (to reason about tickets). These are read-only enumeration concepts — safe to know, lab-only to run.
# LDAP filter: accounts that run a service (have an SPN) — Kerberoastable candidates
(&(objectClass=user)(servicePrincipalName=*))
# LDAP filter: accounts with Kerberos pre-auth DISABLED — AS-REP roastable
# 0x400000 (4194304) = DONT_REQ_PREAUTH bit in userAccountControl
(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))
Kerberos message types you should recognize (from the prerequisite auth lesson):
| Message | Meaning | Relevant attack |
|---|---|---|
| AS-REQ / AS-REP | Initial authentication; issues a TGT | AS-REP roasting (when pre-auth is off) |
| TGS-REQ / TGS-REP | Request a service ticket using the TGT | Kerberoasting (ticket encrypted with SPN account key) |
Windows Security Event IDs you will use for detection:
| Event ID | Meaning | Signals |
|---|---|---|
| 4625 | Account failed to log on (NTLM/interactive) | Spraying: many accounts, one source |
| 4768 | Kerberos TGT requested (AS) | Pre-auth failures; AS-REP roast requests |
| 4769 | Kerberos service ticket requested (TGS) | Kerberoasting: many SPN tickets, esp. weak crypto |
| 4776 | NTLM credential validation | Spraying / pass-the-hash over NTLM |
These are the workhorse AD attacks. Almost all of them abuse passwords rather than software exploits. Use them in authorized labs only.
Spraying tries one common password against many accounts. It is the reverse of brute force, which tries many passwords against one account.
It works because, in a large organization, someone is almost always using a predictable password like Spring2026!.
The attacker stays under the account lockout threshold by going "low and slow" — few attempts, spread out over time — so accounts do not lock.
Defenders spot it as bursts of failed-logon events (Event ID 4625) across many accounts.
Kerberos is the protocol AD uses to issue login tickets. A Service Principal Name (SPN) marks an account as one that runs a service.
The attack: request a service ticket (TGS) for an account that has an SPN. That ticket is encrypted with the service account's password hash. The attacker takes the ticket away and cracks it offline.
Offline cracking is powerful because it triggers no lockout and makes no noise on the target. Service accounts with weak passwords fall quickly.
Defense: give service accounts long, random, managed passwords (25+ characters), and keep an eye on accounts that have SPNs.
Some accounts have Kerberos pre-authentication disabled. Pre-authentication is the step where you prove who you are before AD responds.
With it disabled, the account returns crackable material to anyone, with no authentication needed.
Defense: do not disable pre-authentication, and use strong passwords.
A single local admin password reused across many machines is a gift to an attacker. So is a recovered NTLM hash (the stored form of a Windows password).
Either one lets the attacker authenticate to many hosts. This is the engine of lateral movement — moving from machine to machine inside the network.
Defense: LAPS (a unique local admin password per machine), tiered admin accounts, and the Protected Users security group.
Every attack here converts "a weak or exposed secret somewhere in the domain" into access.
Strong, unique, managed passwords plus monitoring blunt the entire class.
This is a concept lesson, so the "code" is a detection query plus a verification workflow, not an exploit. We show the defensive shape: detect the attack, remediate, then prove the fix rejects the bad condition and accepts the good one. No working attack tooling is provided.
The insecure state that enables Kerberoasting is a service account with a short, human-chosen password. Shown only so you can recognize and remove it:
# LAB ONLY — the misconfiguration, for recognition. Do NOT create this in production.
# A service account whose password is a crackable dictionary word:
New-ADUser -Name "svc-legacyapp" -SamAccountName "svc-legacyapp" `
-AccountPassword (ConvertTo-SecureString "Summer2026!" -AsPlainText -Force) `
-Enabled $true
SetSPN -S "MSSQLSvc/legacyapp.lab.local:1433" "svc-legacyapp"
# Result: any domain user can request this account's TGS and crack "Summer2026!" offline.
Replace the human-chosen password with a group Managed Service Account (gMSA): AD generates and rotates a 120+ character random password automatically, so there is nothing crackable.
# SECURE: gMSA with an AD-managed, auto-rotated, non-crackable password.
# (KDS root key is a one-time domain setup step.)
New-ADServiceAccount -Name "gmsa-legacyapp" `
-DNSHostName "legacyapp.lab.local" `
-PrincipalsAllowedToRetrieveManagedPassword "AppServers"
SetSPN -S "MSSQLSvc/legacyapp.lab.local:1433" "gmsa-legacyapp$"
# Install on the app host, then retire the old svc-legacyapp account.
# CHECK A (reject): no enabled user account should have an SPN AND a crackable-length password.
# List remaining SPN-bearing *user* accounts (should be empty or only gMSAs '$').
Get-ADUser -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName |
Select-Object SamAccountName, ServicePrincipalName
# EXPECTED: svc-legacyapp is gone; only gmsa-legacyapp$ remains (a managed account).
# CHECK B (reject): no account should have pre-auth disabled (AS-REP roastable).
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} -Properties DoesNotRequirePreAuth |
Select-Object SamAccountName
# EXPECTED: empty result set.
# CHECK C (accept): the service still authenticates using the managed account.
# On the app host, confirm the service starts and obtains tickets under gmsa-legacyapp$.
Test-ADServiceAccount -Identity "gmsa-legacyapp"
# EXPECTED: True (managed password works; good input still accepted)
Explanation of expected output. Check A proves the crackable service user is gone (attack precondition removed). Check B proves no account leaks AS-REP material. Check C proves you did not break the application — the service still authenticates, just with a password no dictionary can guess. A remediation that also breaks the service is not a fix; the accept test is what stops you from shipping an outage.
Walking the three-part workflow above:
New-ADUser ... "Summer2026!" creates a service identity with a guessable password. SetSPN attaches a Service Principal Name, which is the flag that makes the account Kerberoastable: any domain user can now request a TGS encrypted with this account's key.Summer2026! derives the very key that encrypts the ticket. Offline, an attacker tries dictionary words until one decrypts the ticket's known-plaintext portion correctly — success reveals the password. Nothing on the DC records a "crack"; only the earlier TGS request (4769) is logged.New-ADServiceAccount tells AD to generate and rotate the password itself. The generated secret is ~120 characters of randomness, so the same offline crack would run effectively forever. PrincipalsAllowedToRetrieveManagedPassword scopes which hosts may fetch it — least privilege.Get-ADUser -Filter {ServicePrincipalName -like "*"} returns every user object still carrying an SPN. After remediation the crackable user is absent; a managed account shows with a trailing $. If a human user account still appears here, the vulnerability is not fixed.DoesNotRequirePreAuth -eq $true surfaces AS-REP-roastable accounts. An empty result means the trust boundary (pre-authentication) is enforced everywhere.Test-ADServiceAccount returning True proves the managed account can actually authenticate — the service keeps working. This is the step beginners skip, and it is what separates a real remediation from a broken one.| Stage | Attack precondition present? | Service still works? |
|---|---|---|
| After part 1 (vulnerable) | Yes — crackable SPN account | Yes |
| After part 2 (fix) | No — managed random password | Not yet re-verified |
| After part 3 (verify) | Confirmed absent (A, B) | Confirmed working (C) |
Mistake 1 — "We blocked TGS requests, so Kerberoasting is fixed."
Mistake 2 — Setting the lockout threshold to 3 to stop spraying.
Mistake 3 — Rotating a shared local-admin password to a new value... everywhere the same.
Mistake 4 — "I decoded the ticket/hash, so it is cracked."
Mistake 5 — "The scanner reported no AD issues, so we are secure."
When a defense or a lab detection does not behave as expected, work through these:
userAccountControl bit query is exact — verify you used 4194304 (0x400000). No results is the good state in production; in a lab, confirm the flag was actually set on the test account.Test-ADServiceAccount returns False after a gMSA fix. The host is not in PrincipalsAllowedToRetrieveManagedPassword, or the KDS root key has not propagated (it needs up to 10 hours by default, or force it in an isolated lab). The account is fine; the authorization to retrieve is missing.Questions to ask when it fails: Is auditing actually enabled on the DC? Am I looking at the right log source? Did I remove the precondition (weak/exposed secret) or just a symptom? Did I re-test that legitimate authentication still works (the accept case)? Is this behavior expected only because I am in a controlled lab?
Security & safety — detection, logging, and authorization.
What to log (for each authentication decision):
What to NEVER log:
Events that signal abuse:
How false positives arise:
Authorization checklist (before any lab exercise):
API_KEY=<development-placeholder>.Lab cleanup / reset:
Remove-ADUser svc-legacyapp; Remove-ADServiceAccount gmsa-legacyapp.Authorized real-world use case. An internal security team runs a sanctioned AD assessment against a staging domain that mirrors production. Working from signed scope, they enumerate SPN accounts and pre-auth-disabled accounts (read-only LDAP), demonstrate in an isolated lab copy that one legacy service account's password is crackable, then hand the finding to engineering. Engineering migrates it to a gMSA and the team re-tests to confirm the account is no longer crackable and the app still runs. The deliverable is a remediation with a retest, not a trophy.
Professional best-practice habits
| Habit | Beginner | Advanced |
|---|---|---|
| Validation | Confirm auditing is on before testing detection | Baseline normal SPN/logon traffic so alerts have low false positives |
| Least privilege | One service account per service | Tiered admin model; gMSA with scoped retrieval principals |
| Secure defaults | Keep Kerberos pre-auth enforced | Prefer AES over RC4; disable RC4 where feasible |
| Logging | Enable 4625/4768/4769/4776 | Correlate by source + account diversity with a SIEM; alert on RC4 TGS bursts |
| Error handling | Moderate lockout + reset window | Lockout tuned against DoS abuse; MFA on exposed logons |
| Passwords | Long service-account passwords (25+) | AD-managed gMSA/dMSA (100+ char auto-rotated) + LAPS fleet-wide |
Across all of these, the professional rule holds: never claim a domain is "completely secure," and never treat a clean scanner run as proof. You prove a control works by testing that it rejects the bad condition and still accepts legitimate use.
All tasks are lab-only, on a domain you built and own or an authorized training range. Each ends by remediating and verifying — the defensive conclusion is required.
Beginner 1 — Enable and read the right logs.
Beginner 2 — Inventory roastable accounts (read-only).
4194304.Intermediate 1 — Spray detection rule.
Intermediate 2 — Remediate a weak service account.
Test-ADServiceAccount = True).Challenge — Close the pass-the-hash path.
Main concepts. Four credential attacks dominate real AD compromises: password spraying (one password, many accounts, under lockout), Kerberoasting (crack an SPN account's password offline from its service ticket), AS-REP roasting (crack material from pre-auth-disabled accounts with no login), and credential reuse / pass-the-hash (reuse a password or NTLM hash to move laterally). Every one abuses a weak or exposed secret, not the cryptography.
Key checks/commands. LDAP filters find the preconditions: (servicePrincipalName=*) for roastable accounts and the userAccountControl:...:=4194304 filter for pre-auth-disabled accounts. Detection lives in Event IDs 4625, 4768, 4769, 4776 (and 4740 for lockout). Remediation verification uses Get-ADUser -Filter (reject tests) and Test-ADServiceAccount (accept test).
Common mistakes. Blocking Kerberos instead of strengthening passwords; over-aggressive lockout that becomes a DoS; rotating a shared password to a new identical value; confusing decoding a blob with cracking a password; trusting a clean scanner run.
What to remember. The shared cure is strong, unique, managed secrets plus monitoring: gMSAs for service accounts, LAPS for local admins, enforced pre-authentication, tiered admin, and correlation-based detection. Test on systems you own or are authorized to test, in isolated labs, and always prove a fix by confirming it rejects the bad condition and still accepts legitimate use. Nothing is ever "completely secure" — you demonstrate control effectiveness, you do not declare victory.