// AD Fundamentals
Active Directory (AD) is Microsoft's directory service used by most enterprise environments to manage users, computers, groups, and policies. Understanding how it works is essential for detecting attacks against it.
Domain Controller (DC)
The server that hosts AD DS. It handles authentication, authorisation, and stores the directory database (NTDS.dit). Compromising a DC means full domain compromise.
Kerberos
The default authentication protocol in AD. Uses tickets (TGT, TGS) issued by the KDC on the DC. Most AD attacks target Kerberos due to its complexity.
NTLM
Legacy authentication protocol still supported. Uses NT hashes instead of tickets. Pass-the-Hash and relay attacks abuse NTLM authentication.
Service Principal Names (SPNs)
Unique identifiers for services running in AD. A service account with an SPN can be Kerberoasted � any domain user can request a service ticket for it.
NTDS.dit is the Active Directory database file stored at C:\Windows\NTDS\NTDS.dit on Domain Controllers. It contains all user credentials (NT hashes). DCSync and Volume Shadow Copy attacks target this file.
// Key Windows Event IDs
Most AD attack detection relies on Windows Security Event Logs. These are your primary detection source � knowing which event IDs matter and what they mean is fundamental.
| Event ID | Log | Description | Why it matters |
|---|---|---|---|
| 4624 | Security | Successful logon | Logon Type 3 (network) and Type 10 (remote interactive) are high-value for lateral movement |
| 4625 | Security | Failed logon | High volume = brute force or password spray |
| 4648 | Security | Logon using explicit credentials | Indicates runas or credential passing � common in lateral movement |
| 4662 | Security | Object accessed in AD | DCSync generates replication permission access events |
| 4672 | Security | Special privileges assigned to logon | Admin-level access � watch for unexpected accounts |
| 4688 | Security | Process creation | Requires audit policy enabled with command-line logging � catches malicious tooling |
| 4698 | Security | Scheduled task created | Common persistence mechanism post-compromise |
| 4720 | Security | User account created | Attacker-created accounts for persistence |
| 4728 / 4732 | Security | Member added to security group | 4728 = domain group, 4732 = local group � watch for additions to Domain Admins |
| 4768 | Security | Kerberos TGT requested (AS-REQ) | AS-REP Roasting � look for requests with RC4 encryption from non-DCs |
| 4769 | Security | Kerberos service ticket requested (TGS-REQ) | Kerberoasting � multiple 4769 events with RC4 encryption type (0x17) for service accounts |
| 4776 | Security | NTLM authentication attempted | Pass-the-Hash and NTLM relay � check for failures then success from same source |
| 7045 | System | New service installed | Malware and lateral movement tools often install as services (PsExec, Cobalt Strike) |
Many of these events require Advanced Audit Policy to be configured. By default, some subcategories like Process Creation and Directory Service Access are not enabled. Check your GPO audit settings � silent logging = blind detection.
// Kerberoasting
Any authenticated domain user can request a Kerberos service ticket (TGS) for any service account that has an SPN registered. The ticket is encrypted with the service account's NT hash. An attacker requests the ticket, saves it, and cracks it offline � no interaction with the target account needed.
Attack flow
| Step | What happens |
|---|---|
| 1. Enumerate SPNs | Attacker queries AD for accounts with SPNs using setspn -T domain -Q */* or tools like BloodHound/PowerView |
| 2. Request service tickets | Attacker requests TGS tickets for identified service accounts � this is a legitimate Kerberos operation |
| 3. Export tickets | Tickets saved to disk using Mimikatz, Rubeus, or Impacket's GetUserSPNs.py |
| 4. Offline cracking | Tickets cracked using Hashcat or John � RC4-encrypted tickets crack significantly faster than AES |
Detection
Look for Event ID 4769 with encryption type 0x17 (RC4-HMAC). Legitimate Kerberos in modern environments uses AES256 (0x12) � RC4 requests for service accounts are suspicious, especially in bulk.
SecurityEvent
| where EventID == 4769
| where TicketEncryptionType == "0x17"
| where ServiceName != "krbtgt"
| where ServiceName !endswith "$"
| summarize count() by Account, ServiceName, IpAddress, bin(TimeGenerated, 1h)
| where count_ > 5
Mitigation: Use Managed Service Accounts (MSAs) or Group Managed Service Accounts (gMSAs) � their passwords are 240 characters long and auto-rotated, making cracking infeasible. Enforce AES256 for service accounts and set Account is sensitive and cannot be delegated on privileged accounts.
// AS-REP Roasting
AS-REP Roasting targets accounts that have Kerberos pre-authentication disabled � a flag set on the account in AD. When pre-authentication is disabled, the KDC will respond to an AS-REQ with an encrypted TGT without first verifying the requester knows the password. An attacker can request this encrypted blob and crack it offline.
This differs from Kerberoasting in that the attacker doesn't even need valid domain credentials � only network access to a DC � making it useful for initial access or unauthenticated enumeration.
Attack flow
| Step | What happens |
|---|---|
| 1. Identify vulnerable accounts | Enumerate accounts with Do not require Kerberos preauthentication set � using tools like Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} or Impacket's GetNPUsers.py |
| 2. Request AS-REP | Send an unauthenticated AS-REQ to the DC � the KDC responds with a TGT encrypted with the account's password hash |
| 3. Offline cracking | Crack the returned hash with Hashcat (-m 18200) or John the Ripper |
Detection
AS-REP Roasting generates Event ID 4768 (Kerberos TGT requested) with encryption type 0x17 (RC4-HMAC) and a pre-authentication type of 0. Legitimate TGT requests use AES256 and always include pre-authentication.
SecurityEvent
| where EventID == 4768
| where PreAuthType == "0"
| where TicketEncryptionType == "0x17"
| where AccountName !endswith "$"
| project TimeGenerated, AccountName, IpAddress, Computer
Mitigation: Audit all accounts with pre-authentication disabled using Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true}. There are very few legitimate reasons for this setting � enable pre-authentication on all accounts unless there is a specific technical requirement. Enforce AES256-only Kerberos to make cracking significantly harder.
// Pass-the-Hash (PtH)
NTLM authentication doesn't require the plaintext password � only the NT hash. An attacker who extracts a user's NTLM hash (via Mimikatz, secretsdump, or a memory dump) can authenticate as that user to any service accepting NTLM without cracking the hash.
Common tools used
| Tool | Usage |
|---|---|
| Mimikatz | sekurlsa::pth � spawns a process authenticated with the supplied hash |
| Impacket (wmiexec, smbexec, psexec) | Remote execution using hash authentication over SMB/WMI |
| CrackMapExec | Spray a hash across a network range to find where it's valid |
Detection
PtH creates a Type 3 (Network) logon using NTLM. Look for Event ID 4624 with Logon Type 3 and Authentication Package = NTLM, particularly from workstations authenticating to other workstations (east-west movement).
SecurityEvent
| where EventID == 4624
| where LogonType == 3
| where AuthenticationPackageName == "NTLM"
| where WorkstationName != ""
| where Computer !contains "DC"
| summarize count() by Account, WorkstationName, IpAddress, bin(TimeGenerated, 30m)
// Pass-the-Ticket (PtT)
Similar to PtH but targets Kerberos. An attacker extracts a valid Kerberos ticket from memory (TGT or TGS) and injects it into a new session � allowing them to authenticate as the ticket's owner without knowing the password.
Tickets are extracted using Mimikatz (sekurlsa::tickets /export) or Rubeus (dump) and injected with Mimikatz (kerberos::ptt) or Rubeus (ptt).
Detection
PtT is harder to detect than PtH. Look for Kerberos logons (4624 Logon Type 3 with Kerberos) where the source IP doesn't match the account's normal behaviour. Ticket reuse from unusual IP addresses or at unusual times are the primary indicators.
If a TGT is stolen and used, look for Event ID 4768 (TGT requested) from an IP that is not the account's normal machine. The legitimate machine won't re-request a TGT if one is already cached � a second TGT request from a different host for the same account is suspicious.
// DCSync
DCSync abuses the DS-Replication-Get-Changes-All permission to impersonate a Domain Controller and request password data for any account in AD � including krbtgt and all Domain Admin hashes. An attacker needs to have this permission, which by default only DCs, Domain Admins, and Enterprise Admins hold.
Executed via Mimikatz: lsadump::dcsync /domain:corp.local /user:krbtgt
Detection
DCSync generates Event ID 4662 on the Domain Controller when a non-DC account accesses replication permissions. Look for access to the DS-Replication-Get-Changes (1131f6aa-9c07-11d1-f79f-00c04fc2dcd2) and DS-Replication-Get-Changes-All (1131f6ad-9c07-11d1-f79f-00c04fc2dcd2) properties by non-DC accounts.
SecurityEvent
| where EventID == 4662
| where ObjectType contains "domainDNS"
| where Properties contains "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"
or Properties contains "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"
| where Account !contains "Domain Controllers"
| project TimeGenerated, Account, SubjectUserName, IpAddress
DCSync is often the final step before full domain compromise. An attacker with krbtgt's hash can create Golden Tickets � valid Kerberos tickets for any account that last up to 10 years and survive password resets.
// Golden & Silver Tickets
| Golden Ticket | Silver Ticket | |
|---|---|---|
| Forged using | krbtgt NT hash | Service account NT hash |
| Grants access to | Any service in the domain | Specific service on a specific host |
| Passes through DC? | No � forged TGT bypasses the KDC | No � forged TGS bypasses the DC entirely |
| Detection difficulty | Hard � no KDC log for ticket usage | Very hard � no DC logs at all |
| Mitigation | Rotate krbtgt password twice | Rotate service account password |
Golden Ticket detection
Look for Kerberos tickets with anomalous attributes � Mimikatz-generated Golden Tickets have a default lifetime of 10 years, which is detectable. Event ID 4769 will appear when the forged TGT is used to request service tickets. Compare ticket lifetimes against your domain's policy (typically 10 hours).
Microsoft Defender for Identity (MDI) has built-in Golden Ticket detection using a behavioural baseline. If you have MDI deployed, it will alert on anomalous ticket attributes automatically.
// LDAP Enumeration & BloodHound
Before executing attacks, adversaries enumerate AD to identify attack paths � privileged accounts, misconfigured delegations, group memberships, and trust relationships. BloodHound is the most common tool for this, using SharpHound to collect data via LDAP queries.
What gets enumerated
| Target | Why attackers care |
|---|---|
| Domain Admins / Enterprise Admins | Primary privilege escalation target |
| Accounts with SPNs | Kerberoasting candidates |
| Accounts with no pre-auth (AS-REP Roastable) | Can request encrypted TGT hash without credentials |
| Unconstrained delegation | Compromise these machines to steal TGTs of any user authenticating to them |
| AdminSDHolder | Accounts protected by SDProp � modifying AdminSDHolder propagates to all protected accounts |
| ACL misconfigurations | GenericAll, WriteDACL, WriteOwner on sensitive objects enables privilege escalation |
Detection
SharpHound (BloodHound's collector) generates a large volume of LDAP queries in a short time � typically thousands of queries within minutes. Event ID 1644 in the AD Directory Service log captures expensive or inefficient LDAP queries. NetFlow anomalies showing sustained LDAP (port 389/636) from a workstation to the DC are also indicative.
SecurityEvent
| where EventID == 4662
| where OperationType == "Object Access"
| summarize QueryCount = count() by SubjectUserName, IpAddress, bin(TimeGenerated, 5m)
| where QueryCount > 200
| sort by QueryCount desc
// Detection Summary
| Attack | Primary Event ID | Key indicator |
|---|---|---|
| Kerberoasting | 4769 | RC4 (0x17) encryption type for service ticket requests |
| AS-REP Roasting | 4768 | Pre-authentication not required � RC4 TGT requested |
| Pass-the-Hash | 4624 | Logon Type 3, NTLM auth, workstation-to-workstation |
| Pass-the-Ticket | 4624 | Kerberos logon from unexpected source IP |
| DCSync | 4662 | Replication permission access by non-DC account |
| Golden Ticket | 4769 | Ticket lifetime anomaly; access to services without prior 4768 |
| BloodHound / Enumeration | 1644 / Netflow | High-volume LDAP queries from a single workstation |
| Persistence (new admin) | 4728 / 4720 | Account added to Domain Admins or new account created |
| Persistence (scheduled task) | 4698 | New scheduled task on DC or server |
| Lateral movement (PsExec/WMI) | 7045 / 4688 | New service or suspicious process on remote host |
// Hardening Quick Wins
Rotate the krbtgt password twice. Running the rotation twice invalidates all existing Kerberos tickets, including any Golden Tickets an attacker may have generated. Do both rotations with a gap of at least the maximum ticket lifetime (default 10 hours) between them.
Tier your AD model. Privileged Access Workstations (PAWs) for Tier 0 (DC admins), separate accounts for each tier. Domain Admin accounts should never log into workstations � LSASS on every machine an admin touches holds their credentials in memory.
Enable Protected Users security group. Accounts in Protected Users cannot use NTLM, cannot use RC4 for Kerberos, and cannot be delegated. Enrol privileged accounts immediately.
Deploy Microsoft Defender for Identity (MDI). MDI has built-in detections for Kerberoasting, DCSync, Golden Tickets, Pass-the-Hash, and BloodHound enumeration using network traffic analysis and event log telemetry.
Disable NTLM where possible. NTLM v1 should be disabled domain-wide. NTLM v2 should be restricted via GPO (Network Security: LAN Manager authentication level = NTLMv2 only). Where NTLM is not needed (modern kerberos-capable environments), block it entirely.