This presentation was initially delivered as part of the One Identity Unite User and Partner Conference in September 2024 in San Diego. In this session, I'll be hacking Active Directory, showing a full attack chain that starts with nothing but a machine on the internal network and ends with a golden ticket attack that grants the enterprise admin privileges that are valid for more than 4,000 years.
My name is AJ Lindner. I'm a solutions architect with One Identity, and I specialize in our Active Directory management and security solutions. Now, before we get started, why should you trust me on this topic? I'm not a professional penetration tester or an offensive security expert, and I don't have any red team experience.
But I've been using Active Directory since before I was born, I know how to search things on Google and YouTube, and I installed Kali Linux on my Windows computer from the Microsoft Store. Now, all jokes aside, the point of this presentation is that none of the attacks I'm about to show are difficult to perform. Really, anybody with a little technical knowledge and time on their hands can follow any number of great tutorials or guides and run these tools and attacks very easily.
Now, a big reason for that, as Dan Conrad likes to say, is that Active Directory is really a Single Sign-On solution, not so much a security solution. And there are a lot of quirks with how it's designed that we as an attacker can take advantage of.
So let's attack AD. I'll be performing an assumed breach pentest, which means I'm not breaking into the internal network. I'm given a machine that's already connected. My goal is to gain admin privileges in the domain and ideally establish some type of persistence.
I'll get my initial domain user privileges by performing a password spray attack. Then I'll move around the environment and eventually elevate my privileges by Kerberoasting roasting a service account and cracking its password.
With those privileges, I'll set up a bypass for the default Windows security that will allow me to drop malicious software on a server that I can then use to perform a pass-the-hash attack against an even higher-privileged account. And finally, I'll set up some persistence by creating my own domain admin account and exporting a Kerberos ticket. Once the attack chain is complete, I'll finish by discussing some of the tactics and configuration options available to protect against these attacks.
The environment itself is a set of isolated virtual machines on my own personal computer. Anybody looking to test these attacks yourself, do not do so on company devices or networks, even in VMs. Now, when you see other labs, tutorials, or examples of a lot of these attacks, they're very often being performed against intentionally vulnerable environments, often including old versions of Active Directory.
In this attack chain, our domain controller is a brand-new, fully-patched Windows Server 2022 machine with no intentional misconfigurations or added vulnerabilities. I simply installed the operating system and all patches and updates and converted it to a domain controller. I didn't do any additional configuration. So what we're seeing is basically default Active Directory.
I've also got a SQL application server-- same deal, except I have opened port 445 internally just for some of the attacks that I'm doing, which is fairly common for a wide range of functionality. And finally, I have my Kali Linux machine that's connected to the network.
As an attacker, I've done some prep work, and I'm going in with a few assumptions. So the first is I've created a file containing a list of potential usernames that may exist in the environment using open-source intelligence tools like Linkedin2Username.
I'm also just assuming that AD is using the default config. And by default, AD only requires a seven-character minimum length for passwords and does require its own composition rules. Also, although I won't necessarily be taking advantage of this today, by default, AD does not have a lockout policy. And finally, this is Active Directory we're talking about, so I know I'll be able to run tools that utilize or take advantage of the SMB protocol.
OK, let's begin our attack by getting access to some domain user credentials. To start, I'm going to do some scanning and reconnaissance in the network so that I can gather information on the environment and identify potential targets and potential attack methods. I'll start with a tool called Nmap to scan for available hosts, open ports, and running services. Then I'll look to gather information about the Active Directory domain and build a list of known valid usernames that I can try to gain control of.
As I mentioned, if this were an older domain or otherwise had a vulnerable version of SMB running, like SMB version 1, I might be able to do this with a number of tools using an SMB null session. Essentially, I could authenticate to the domain as no one and read the entire directory. However, as we'll see from our scanning, that won't be possible in this domain.
Instead, I'm going to use a tool called Kerbrute to perform user enumeration. This tool exploits the way Kerberos works by sending a ticket-granting ticket request to the key distribution center for a user, but with no pre-authentication. Essentially, I'm saying, hey, I'm this user. Please grant me a ticket to access this resource. But I haven't authenticated.
Lucky for me, Kerberos will then respond in two different ways. "Principal unknown" means the username in that ticket-granting ticket is not valid. If it is a valid username, it will respond with a pre-authentication prompt. So using Kerbrute, I'll take my list of potential usernames that I prepared earlier and determine which of them actually exist in the Active Directory domain.
Once I have a list of valid usernames, then I need to try and get some passwords. Because there's no lockout policy, I could perform a brute-force attack where I take my big list of usernames and either some big list of passwords or some rules to generate incremental passwords and try every single password against every single user. Obviously, this attack can be time-consuming, incredibly noisy, and trigger account lockouts if there's policies in place.
Alternatively, many attackers today are successfully gaining access with a password spray attack, using a single password against all users, or perhaps a very small list designed to bypass account lockout mechanisms while making significantly less noise, which is what I'm going to do today.
First, a quick ifconfig command shows me that my machine has an IP address of 10.0.0.3 and info about the subnet I'm on, which I can then use to scan the network with a basic Nmap command.
Checking the scan results, I see a machine at 10.0.0.1, which certainly looks like a domain controller. I see another at 10.0.0.101 with port 135 open and another at 10.0.0.102 that has a few ports open, including RDP, 10.0.0.254, which is most likely a networking device, and, of course, my own machine at 10.0.0.3.
I'm interested in a few of these results. So now I'll run another more advanced scan just on the devices I'm interested in and get some additional information.
Scrolling through the output, I can confirm that 10.0.0.1 is a domain controller, DC01.dev.lab, And most likely running Windows Server 2022.
10.0.0.101 is most likely a domain-joined workstation of some sort. And 102 appears to be a domain-joined SQL server also running Windows Server 2022.
So time to target that domain controller. I'm going to use a tool called CrackMapExec, which we'll see a lot in this demonstration, to see if I can connect over SMB. Of course I can. But unfortunately for me, this domain controller has SMB signing enabled and SMB V1 disabled.
So I won't be able to connect with a null session. No big deal. Now that I have the domain info, I can use Kerbrute to enumerate valid users.
As you can see, it's incredibly fast and was able to confirm that 663 out of the 815 usernames in my file do in fact exist inside the domain. Using Kerbrute once again, I'll run a password spray attack against that list of users with the obviously very secure password "Password1" with a capital P and an exclamation mark at the end. That meets all of AD's default password requirements, and I get six successful hits in under half a second.
I'll do this again with another common password format, the name of the company and the current year, which gets me four more hits just as fast. I'm pretty happy about that, so I'll take control of Joy Erdman's account.
Now that I've become Joy, let's see what she can get me access to. One thing for sure-- I can enumerate the domain and identify other possible targets. To do this, I'll use CrackMapExec once again to read through the domain. But since I have valid domain credentials, I can also just query LDAP to look for privileged or exploitable accounts.
While I of course want to check out privileged users like domain admins, I also want to identify any service principals that have published SPNs, which makes them potentially vulnerable to a Kerberoasting attack. Using a script from Impacket, I would be able to get the NTLM encrypted TGS rep tickets for those accounts. And then I could attempt to crack them and get plaintext credentials.
Running CrackMapExec over SMB against the domain controller with Joy Erdman's credentials, I can now provide the users parameter to easily get all the user accounts that exist in the domain. I can do this for computers as well and again for the password policy to confirm or disprove the assumptions that I made earlier.
I can also use LDAP search to run queries, for example, finding all the domain admins and making a note of their usernames in case I come across them sometime later. I can also query for what might be service accounts, in this case, any accounts that begin with svc underscore, and it looks like I may have found the service account for that SQL server that I identified earlier.
So using Impacket and Joy's credentials, I can perform a Kerberoasting attack and see if any of those produce results. And sure enough, that SQL service account is there for me to take. I will copy that ticket out to a file and use that in the next step.
That next step is, of course, cracking that result to get a cleartext password. There's a lot of powerful tools for performing offline cracking. I'll be using John the Ripper with a big list of common passwords, but Hashcat is also another very popular option.
Once I have that password, then I'll see what that account gets me access to. In this case, it will be able to RDP into the SQL server, where it also happens to have local admin permissions, meaning I will effectively own a domain-joined machine on the network.
Although John and Hashcat both have tons of options for generating, incrementing, substituting, and doing all sorts of crazy things to guess passwords, I'm very simply going to run it against my ticket file and pass it my own password list. John instantly recognizes that it's a Kerberos TGS hash and very quickly finds a match from the file.
To test it real quick, I'll simply attempt to authenticate over SMB using CrackMapExec once again, but this time to that SQL Server instead of the DC. And sure enough, it's successful.
Now I'll try it again, but I'll do so while executing a command on that server to identify the local administrators. And sure enough, I can run the command because I am a local administrator. All right. I'm in a great spot now, but I still need to get further.
Now that I own this machine, I can probably deploy something to escalate my privileges even further. If I was a smarter man, I may develop and compile my own custom binaries that might replace another running service, for example. Or if I were a highly advanced threat actor hitting a major target, I might burn a zero-day, or I may have other types of obfuscated or modified scripts that are really robust at avoiding detection.
But in my case, I have standard script kiddie tools that Microsoft and every antivirus under the sun will absolutely notice and immediately remove as soon as I try to copy them over or run them at all. So I will just tell Windows Security to ignore a folder and then load up whatever exploits I want into that folder.
I will start by running another command on that SQL server through CrackMapExec. But this time I'm running PowerShell to set the Windows Temp folder as an exclusion path for Windows Security.
With that finished, I'll use another Impacket script to open an interactive client on that machine, again via SMB protocol, and use that client to copy over a tool called Mimikatz.
Now, to spare you from any more command line, I'll go ahead and RDP to that server and open Windows Security to show that exclusion rule.
And for sanity, while I'm here, I'll add one that specifically excludes the Mimikatz executable. Mimikatz is a ridiculously powerful tool that enables some awesome exploits, but it can be a massive pain to deploy, even in a personal lab environment. With Mimikatz and my admin privileges, I'll be able to dump LSASS, which will give me access to information stored in memory, containing signed-in users and often their password hashes.
With that information, I can then perform a pass-the-hash attack, which allows me to impersonate a user, in this case one of the domain admins that I identified earlier, by only using their password hash without even needing to crack it. Back in my RDP session, I'll navigate to that Temp folder and run Mimikatz as an administrator.
Now, the most important thing to do any time you launch Mimikatz interactively is to get coffee. And then the actual most important thing is to run the privilege::debug command to give yourself system privileges and gain access to read LSASS. Now I can run the sekurlsa::logonpasswords command and start the fun. Scrolling through the output here, I see a lot of different accounts, some with hashes or potentially even plaintext passwords.
The most interesting one, though, is this aj account, which I noted earlier was a domain admin. And sure enough, there's an NTLM hash right there that I can grab. With that, I can then run the sekurlsa::pth command to perform a pass-the-hash attack.
I'll include the username, the domain, and the NTLM hash. When that finishes, I'll get a new command prompt window by default. But I also could have provided an executable or a command to run instead.
Now, don't get confused. When I run whoami, it looks like I'm still the SQL service account. However, I have all the privileges of the aj account in this command prompt window, including domain admins.
This is a big win so far, but I'd like to set up some persistence. My access is great. I have admin rights in the domain. But it's pretty temporary and fairly limited.
I also may not be able to repeat any step of this process or pass-the-hash attack specifically so easy in the future. And there are tons of ways I can lose access to the session I have right here. So while I have those permissions, I can go ahead and create my own domain admin account so I can sign in whenever I want.
So back over to that command prompt that is running with domain admin privileges, I'll run a net user command to create a new domain user called not_a_hacker and a net group command to make him a domain admin. Now I'm finished with my service account. So instead, I can RDP directly over to the domain controller as this new domain admin user.
Mission complete. I have my own domain admin. I can do whatever I want with it, but I want to take things one step further by getting myself a persistent ticket with a golden ticket attack.
To keep things simple, just keep in mind that when you access services on the domain, you're not authenticating directly to that service, but you're instead using what's called a ticket-granting ticket that was issued to you by the Kerberos key distribution center, which you authenticate against.
Those ticket-granting tickets are encrypted using the password hash for a special built-in account, KRBTGT. Basically, with the right information, including the KRBTGT account's password hash, I can create my own ticket-granting ticket impersonating any user I want with any permissions I want and make it valid for however long I want.
So how about a ticket that gives me enterprise admin rights and is valid for more than 4,000 years? So I'm going to flip back to that SQL server, which has that elevated command prompt running with aj's domain admin privileges that I got earlier after the pass-the-hash attack, and we'll perform a golden ticket attack.
First, I need to grab some missing information, starting with the SID, or Security Identifier of the Domain, which all domain users have access to. So I'll just copy the domain portion of my user SID after running whoami.
Next, I need the KRBTGT account's password hash. Now, this does require elevated privileges. However, I'm a domain admin. I have permissions to sync domain controllers, and I can use Mimikatz once again with the lsadump::dcsync sync command against that account, and I get its password hash.
And finally, I can run the kerberos::golden command and provide all the information for the ticket I'd like to create. So I need a valid user to impersonate, the fully qualified domain name, the domain SID, the KRBTGT password hash, then, optionally, any group memberships that this ticket should grant, which in this case are well-known administrative groups, including enterprise and domain admins, the file name to output the ticket to, and the expiration time, which we can see is set pretty high.
And now that our ticket is created and saved to a file, we can also see the output information about that ticket, including the fact that it's valid until the year 6107. Finally, very quickly, I can use Mimikatz to perform a pass-the-ticket attack with that golden ticket file or hang on to it and perform this some time later in the future.
All right. Now that my attack is finished, let's discuss some of the remediation tactics that can help prevent these methods from succeeding. And the first one is, of course, just throw out AD and switch to Linux. OK, that's likely not feasible.
So the real first one is fix your passwords. Attacks like password spraying and cracking password hashes are so viable because passwords are so terrible. For more in-depth information on this, you can check out my other presentation from Unite 2024 on password security. But for some quick advice, utilize a privileged access management solution, like One Identity Safeguard, to protect accounts that have high privileges.
For your regular user accounts, fall in line with the recommendations that NIST provided over seven years ago for password standards, most of which are set to become strict requirements rather than simple recommendations in the upcoming revision of those standards. And that new revision suggests a 15-character minimum password length but requires at least 8.
Check passwords against a dictionary to ensure that they're not just a single dictionary word. And also combine that with a custom deny list, including common things like the name of your company. Regularly compare passwords against breach corpuses, like the free and open-source Have I Been Pwned service, to ensure that no accounts have a password that has been exposed in a breach.
Unless you are subject to other regulations that require you to do so, do not require arbitrary complexity requirements or arbitrary scheduled password rotations for end user accounts. And for Active Directory specifically, make sure you enable an account lockout policy that's disabled by default if you haven't already done so. And you can use a self-service password reset solution, like One Identity Password Manager, to enforce these rules for your end users.
It's also incredibly important to delegate least privileged access, reducing or eliminating native Active Directory and local system privileges wherever possible. One Identity Active Roles is designed for this, acting as a proxy where incredibly fine-grained permissions can be assigned without existing directly on the user's Active Directory account.
Service accounts also need severe controls and restrictions. Again, use a PAM solution to securely set vault and rotate cryptographically secure passwords for these accounts. Avoid assigning any privileges to a service account that aren't absolutely needed, especially local or domain admin rights.
Wherever possible, use a group managed service account instead of a traditional user account for your service accounts. And if your service account absolutely requires domain admins or other extensive privileges, it should not have a published SPN.
Additionally, implement a solution for just-in-time privilege elevation to prevent pass-the-hash attacks. This ensures that when a privileged account is not being actively used by an administrator, it doesn't have any permissions or even the ability to authenticate whatsoever. And it only gains those rights and that ability when it's checked out for use by an administrator.
On the configuration side, upgrade your servers and your forest functional levels and get on top of your patching. As I've mentioned before, older versions of Windows Server and older forest functional levels may include vulnerabilities by default that require extra work to resolve on your end that don't exist by default in newer versions. Set up alerts for detection and response, and build programs and policies around those alerts so that you can catch and shut down these attacks before they succeed.
Specifically for the user enumeration and password spray attacks that I performed earlier, you can enable alerting on the domain controller for event ID 4625, "an account failed to log on," and Kerberos logging for ID 4771, "Kerberos pre-authentication failed."
Quest Change Auditor for Active Directory can help immensely in this process, not only for alerting on any number of changes occurring in AD, but even preventing specified changes from occurring at all. Take the time to review, identify, and remediate any misconfigurations, especially legacy issues. As much as possible, prevent direct access to domain controllers. And where needed, restrict that access to only certain designated accounts, ideally via a privileged sessions appliance like One Identity Safeguard.
If you haven't already, enable and require both SMB and LDAP signing and, again, disable SMB version 1. Perform regular penetration tests to identify gaps in your security posture. Have backups and test them. If you haven't tested your backups, you don't have backups.
Deploy modern EDR and SIEM systems, and utilize those to detect and prevent these and other common attacks. And finally, golden ticket attacks work by using that KRBTGT account's password hash. You can invalidate the tickets generated from this attack by rotating that account's password, sometimes with a PAM solution or, more commonly, with any number of scripts that are available directly from Microsoft or otherwise that are purpose-built for this exact scenario.
Note that because the KRBTGT account has a password history of 2, to fully and properly invalidate those tickets, you need to reset the password twice. The commonly available scripts will perform an initial password reset, wait for full replication of that password change to all domain controllers, and then perform the secondary reset.
I'll close this out with some useful offensive and defensive tools, some reference docs, and some useful links for following up. Quick disclaimer, though-- these offensive tools and the sites that I'm about to show you are legitimate, but I can't guarantee that when you go back to click on them that they have not become compromised somehow.
Some of these sites will be flagged as dangerous, and many of these tools will be blocked as malware. Be careful. All of my testing was performed in an isolated virtual environment on private personal hardware.
So here are a bunch of incredibly useful offensive tools for attacking Active Directory. Many of these were shown today, including Mimikatz, Kerbrute, John the Ripper, Impacket, and CrackMapExec. Others are alternatives to some of these or entirely different tools to compromise AD, and a bunch of these are available by default in Kali Linux.
Responder, for example, is a commonly used tool that essentially waits for somebody to try connecting to a fileshare that doesn't exist. When they do, it responds like, hey, I'm that file share, but you need to authenticate. And then it steals their credentials.
Bloodhound is also another big one. It's both an offensive and defensive tool. It basically analyzes AD to build out attack paths, which attackers can use to quickly identify their route to success and defenders can use as a guide to eliminate those issues. Quest also sells an enterprise version of Bloodhound, which I'd highly suggest considering.
On the defensive side, beyond the Quest and One Identity products that I previously mentioned, Quest also offers Security Guardian, which is designed to reduce your Active Directory attack surface, and Recovery Manager for AD, which helps you quickly and easily recover in the event of a catastrophic attack.
And here's some additional reference documentation for some of the attacks shown in this presentation and some that were not but are otherwise very common. LDAP Wiki in particular is a great reference if you're looking to dive deep into Kerberos, for example, among other things.
And finally, some incredibly useful links for understanding exactly how common Active Directory attacks work and exactly how you can defend against them-- and if you want to watch someone who actually really knows what they're doing, attack AD, and explain it in some more depth, I'd highly recommend this YouTube video on David Bombal's channel featuring Remi Solberg.
If you have any questions, please feel free to reach out to One Identity. And thank you to all the wonderful sponsors for One Identity Unite 2024.