One-Way Trust Account Abuse
Reversing a one-way trust by extracting the trust account credentials from the TDO
Theory
When a one-way trust is established between a trusting domain (B) and a trusted
domain (A), Windows automatically creates a trust account (DOMAIN_B$) in the
trusted domain (A). The password of that account is stored in the
TDO
of the trusting domain (B), in cleartext and as Kerberos keys.
An attacker holding Domain Admin on the trusting domain (B) can therefore extract those credentials and authenticate to the trusted domain (A), reversing the expected direction of the one-way trust.
This requires full compromise of the trusting domain. Domain Admin (or equivalent) is a prerequisite, so this extends an existing compromise rather than establishing one.
Practice
1. Extract TDO credentials
The password stored in the TDO on the trusting domain is the same as the
password of the trust account (DOMAIN_B$) on the trusted domain, so extracting
it yields valid credentials there.
What comes out differs by tool, and that determines the authentication options in step 2:
- UNIX-like:
tdo_dumpreturns the trust account's actual Kerberos AES-256/AES-128 keys and NT hash, so AES-based Kerberos authentication works. - Windows: Mimikatz returns inter-realm trust keys. Only the
rc4_hmac_ntvalue corresponds to the trust account NT hash and can be used to request a TGT. The AES keys shown are inter-realm derivations and cannot.
tdo_dump (Python) works remotely over Directory Replication Services (DRS) and returns the full Kerberos keys of the trust account (see the Almond write-up).
It needs two GUIDs: the TDO object for the trusted domain, and the ntDSDSA
object of the trusting DC.
# Retrieve the TDO GUID
ldeep ldap -u "$USER" -p "$PASSWORD" -d "$DOMAIN" -s ldap://"$DC_IP" \
search "(objectClass=trustedDomain)" objectguid,distinguishedname
# Retrieve the ntDSDSA GUID
ldeep ldap -u "$USER" -p "$PASSWORD" -d "$DOMAIN" -s ldap://"$DC_IP" \
-b "CN=Configuration,DC=domain,DC=lab" search "(name=NTDS Settings)" objectguid,distinguishedname
# Extract the credentials
python3 tdo_dump.py -u "$USER" -d "$DOMAIN" -t "$DC_HOST.$DOMAIN" -p "$PASSWORD" \
--tdo-guid "$TDO_GUID" --dsa-guid "$DSA_GUID"The tool returns the trust account password in cleartext, as an NT hash, and as Kerberos AES-256/AES-128 keys.
2. Authenticate to the trusted domain
With the trust account's Kerberos keys, authenticate to the trusted domain. The trust account cannot authenticate over NTLM, so Kerberos is the only option. The inter-realm keys are of little use here since the attacker already controls the trusting domain.
The trust account name is the NetBIOS name of the trusting domain followed by
$. Following the example above, the account created in domain A for the
trusting domain B is DOMAIN_B$. Request a TGT for it on the trusted domain
using the credentials from step 1.
That TGT then supports authenticated recon and further attacks against the trusted domain, exactly as any other domain account would.
For the ticket mechanics, see Pass-the-Ticket and Pass-the-Key.