90% of the Global Fortune 1000 companies use Active Directory as their primary method of authentication and authorization. This plays a vital role in the infrastructure of many companies and of often though of as the source of truth in their environments.
I will be covering some basic Active Directory enumeration using a tool called Bloodhound which allows an attacker or red teamer to analyse the Active Directory rights, relationships and privileges. It will then also map out Active Directory objects for us to review in the form of attack graphs. Two common attacks covered in this blog are token impersonation attacks and kerberoasting.
Shortest path to Domain Admins
The first graph we will review maps out the shortest path from users to the Domain Admins group via group memberships, sessions, administration, ACLS, etc. We will look at the highlighted path below with the assumption that the user fcastle has been owned; we have logon credentials for this user. We have also marked this user in BloodHound as being owned.
We can see below from the highlighted attack path that fcastle is an admin to the machine Spiderman where the Domain Admin Master has a session.
If we take a look at the shortest path from owned principles to Domain Admin, we see the exact route we will be taking to compromise the user Master to get domain admin.
It is extremely dangerous for Domain Admins to be logged into non Domain Controllers. Using BloodHound we can enumerate exactly where a Domain Admin is logged in and can target those machines specifically such as ThePunisher and Spiderman as shown in the graph below. If we have credentials as a low level user on a machine where a Domain Admin has a session, we could perform a token impersonation attack and impersonate that user.
Token Impersonation attack
Before we can pull off the token impersonation attack we need to get a shell on the machine. For this we will use the Psexec Metasploit module and provide the logon credentials for the fcastle user.
We catch a Meterpreter session on the host ThePunisher, due to how I set up this portion of my attack lab, the machine name may differ from the machine name in the BloodHound attack path. Once on the machine we are able to dump hashes that are in memory as part of our post exploitation information gathering process.
We can load a tool in Metasploit called incognito which is used to impersonate user tokens.
There are typically two types of tokens that are stored on a machine:
→ Delegate tokens which are created for logging into a machine or using RDP.
→ Impersonate tokens which are non interactive and capture the security information of client processes.
As well as using the Incognito tool, we also have the option to load other tools such as Mimikatz and PowerShell if we needed to.
We will list out the available tokens for us to impersonate with the following command:
We notice that whilst on the machine ThePunisher, we have a token for the user Master that we can impersonate. We remember from our Bloodhound attack paths above that the user Master has a session on this machine and therefore a token. To impersonate this token we use the command below.
When we check what user we are running as and what groups we are apart of, we notice that we are now the user marvel\master and that we are part of the Domain Admins group.
The token we just impersonated is a delegate token created when we log on via RDP, these tokens are available until the machine is restarted. This happens when we log into a server and don't log out or reboot that server. The token sits on that server until we reboot it so we can move laterally and then elevate privileges.
A remediation technique for this is to implement tiered accounts and use these accounts to log into servers and only use Domain Admin accounts to log into the Domain Controller. If a Domain Admin logs into a server and that server is then compromised, an attacker can then log into that server as a low level user and impersonate the Domain Admin account.
A further remediation is that we must employ local administrator restrictions, we used Psexec to get a shell on the machine ThePunisher as the fcastle user. This was successful as the user fcastle is a local administrator to the machine, SMB relay attacks, Psexec and Smbexec tools fail if the user we are attacking is not a local administrator. Restricting the use of local administrators would prevent us from getting onto the computer and performing these attacks.
Overview of the Kerberos protocol
The Domain Controller acts as the KDC (Key Distribution Centre), we also have a user that needs to authenticate to the Domain Controller.
When a user authenticates to the Domain Controller, they request a Ticket Granting Ticket (TGT) and they provide their NTLM hash (username and password) to the KDC.
The Domain Controller sends back a TGT encrypted with the TGT hash.
⇒ The KDC holds the keys
We now have an application server, and a user wants to access a service which has an SPN (Service Principal Name).
To access this service the user needs to request a Ticket Granting Service Ticket (TGS) from the Domain Controller. This is done by sending the users TGT with their request.
The Domain Controller knows the server account hash and encrypts the TGS and sends it to requested user.
The Domain Controller doesn't know if we have access to the server or not, it just provides the user with a ticket.
To authenticate to the application server we provide our TGS, which is then decrypted using its own server hash and checks if we have access or not
To kerberoast a user, we want to get their TGS and decrypt the server accounts hash. When looking at the Bloodhound graph to list out all of the Domain Admins below, we notice that the account SQLService is a Domain Admin. We want to look closer into this account to see what other attacks we can perform on it.
Looking at what accounts are kerberoastable, we see we have the SQLService account which is also a domain admin, so we will target this account now.
Another graph that displays this information nicely for us is the Kerberoastable member of high value groups graph. This shows us the memberships of the SQLService group and that it is a Domain Admin.
We can use the GetUserSPNs tool to get Service Principal Names that are associated with normal user accounts. We can then attempt to crack the ticket hash that is returned which is encrypted with the users password.
python2 /usr/share/doc/python-impacket/examples/GetUserSPNs.py marvel.local fcastle:Password1 -dc-ip 10.0.1.4 -request
Below we see that we have received the hash of the TGS for the SQLService account, and we can now crack the kbr5tgs hash using hashcat.
Running the hashcat command below we crack the ticket and see that the password is Mypassword123#.
hashcat -m 13100 tgthash.txt /usr/share/wordlists/rockyou.txt -O
Now we have the plaintext password for the SQLService account, we have successfully performed a kerberoast attack. A common issue with service accounts is that the passwords were weak and historically set and are rarely changed. This in combination means that the kbr5tgs hash is easy to crack, even worse is that this user is a Domain Admin.
Some common remediations are to employ strong password policies for service accounts with a length of at least 25 characters and to change the passwords regularly. Service accounts should also not be part of the Domain Admins group and should be set up with the principle of least privilege.
Shortest path to high value targets
Bloodhound also shows us shortest paths in the domain to high value targets such as Domains Admins and high privileged groups. The below graph highlighted shows us how we can move from the user pparker to the user Master which is a Domain Admin, and then shows us how we can move laterally to the user tstark which is also a Domain admin. The graph highlights the group memberships of these Domain Admin users and what we can access with these group memberships.
We have walked through a simple analysis of an Active Directory Domain using bloodhound and have performed some basic attacks from the information we have gathered. Bloodhound by default has a number of analysis options and graphs that can be drawn out and analysed further to understand the structure of a domain.
I hope I explained my method clearly and provided justified reasoning for the actions I took. If you have any feedback, I would love to hear it as I want to keep improving.