Password Auditing in AWS Directory Service

Fingerprint Icon

What is AWS Directory Service

If you want to have an Active Directory (AD) domain within your AWS platform, there are two primary options. The first option is to set up some EC2 instances, install Windows on them, and then build your own AD from scratch. However, this comes with the usual costs and overheads of managing, patching and maintaining multiple domain controllers.

So a common alternative is to use AWS Directory Service, which is essentially a managed Active Directory environment hosted by AWS, where AWS run the domain controllers for you. This means that you do not have to personally manage any of the infrastructure; significantly reducing the overhead of running AD. This does, however, come with a few downsides.

Due to the domain controllers being fully managed by AWS, you do not have any direct access to them. This also means that don’t get full control over the domain, meaning that while you have delegated permissions within certain OUs, you do not have full Domain Admin rights.

Password Auditing

In most circumstances, the lack of full Domain Admin rights isn’t a significant issue. However, when it comes password auditing, it becomes a problem. In order to carry out offline password auditing, there are two main approaches that we normally use:

  • We can take a copy of the NTDS.dit database and extract the hashes from there, as discussed in our Active Directory password auditing guide. This does, however, require access to the domain controllers or their backups.
  • We can pretend to be a new domain controller and ask the existing domain controllers to replicate a copy of the database for us. This technique would be done through tools like Mimikatz or Impacket, usually known as DCSync, but it requires Domain Admin rights.

Since we neither have access to the domain controllers nor full Domain Admin rights, we are unable to perform either of these methods with AWS Directory Service, and AWS does not provide any managed mechanism for us to perform password audits. I’ve been unable to find any public guides on how to carry out password auditing in this kind of environment, although that doesn’t necessarily mean that there aren’t any out there.

We could conduct online attacks, such as password spraying, to target very weak candidates like “Password1”, while being mindful of account lockout policies. But this approach becomes inefficient as the passwords become more secure and more challenging to guess and, it is far more limited than offline password auditing.

However, based on some recent experimentation, it is possible to carry out effective password auditing with AWS Directory Service, and the same methods should also work in other similar managed AD setups. But first, we need to take a step back and revisit an old friend: Kerberoasting.

Targeted Kerberoasting

Kerberoasting is useful technique that’s been around for years, and is generally well known to pentesters. There are a lot of resources explaining it in great detail, such as this excellent article by Sean Metcalf on the AD Security site, who was one of the pioneers of this technique.

I won’t repeat their full explanation, but for our purposes the key points are:

  • We need to be able to authenticate against Active Directory to carry out the attack, but do not need any additional privileges.
  • We can use Kerberoasting to obtain a ticket, which can then be used for offline attacks in order to retrieve the password for the associated user account.
  • The targeted account must have a Service Principal Name (SPN) configured.

The last point is the most crucial limitation, and since SPNs would normally only exist on accounts used to run services (especially things like Microsoft SQL Server), that means that it is quite rare to find them on individual user accounts. While it it’s a useful technique for general Active Directory attacks, it doesn’t initially appear to be very helpful in solving our problem. However, we can work around this limitation with a less common variant of the attack called Targeted Kerberoasting.

The idea behind Targeted Kerberoasting is simple: if you have sufficient privileges within Active Directory (specifically write access to the user object), then you can create a new SPN for a user without needing to know their password. There are a couple of different tools that can be used for this, including the Get-DomainSPNTicket function in PowerSploit, and the targetedKerberoast Python script based on Impacket.

Crucially for our purposes, you do not require full administrative rights in the domain itself - you just need to have permissions over the user objects. And while there are a small number of user objects you will not have control over in an AWS Directory Services environment (such as the built-in Administrator account), you do have permissions for all user and service accounts that you create.

Pulling it Together

Using Targeted Kerberoasting, we now have a process that we can use to carry out password auditing against AWS Directory Services:

  • Authenticate with a privileged account (such as a member of “AWS Delegated Administrators”).
  • Create an SPN for a target user (unless they already had one).
  • Kerberoast the target user to obtain a TGS ticket.
  • Remove the SPN we just created.
  • Carry out offline cracking against the ticket to try and obtain the target user’s password.

However, there are a few key limitations of this process compared to the normal methods that would be used in a traditional Active Directory environment:

  • It’s somewhat noisier and more intrusive, as we must create SPNs for all users individually.
  • The SPNs allow any other authenticated user to carry out the same Kerberoasting attack we’re doing, so they need to be removed quickly and there’s a small window of exposure while they exist.
  • We can’t do any analysis from the tickets like we can with NTLM hashes (such as identifying users with duplicate passwords without having to crack the hashes).
  • Cracking the tickets is significantly slower than cracking NTLM hashes.

But while it’s not perfect, it is a significant improvement over not being able to do anypassword auditing, beyond spraying a few passwords against the domain in an online attack.

Case Study

CODA was asked to carry out an assessment of an environment hosted in AWS, which was using AWS Directory Service to manage internal user accounts. The environment had been in production use for several years, and had undergone multiple previous IT health checks. The environment has a strong password policy and a high minimum password length, so it was generally assumed by the client that users would have strong passwords. However, due to the limited privileges in Active Directory and the lack of access to the domain controller, it did not appear that password auditing had previously been performed.

Using a highly privileged service account, it was possible to perform a targeted Kerberoasting attack against approximately 900 enabled user accounts in the AWS Directory Services domain, and then to carry out password cracking on an (relatively small) EC2 instance within the environment.

The high minimum password length meant that many of the passwords remained uncracked, however, approximately 20% of the users had passwords that were based on a weak and predictable pattern. This included not just low privileged users, but also members of several highly privileged groups. These passwords would not only be susceptible to offline cracking attacks but could also be guessed or derived by an internal user with sufficient knowledge of the environment.

Many of these accounts had been using weak passwords for a significant period of time, but the lack of password auditing in previous assessments or internal processes meant that they had never been identified. In this specific case the presence of MFA on the perimeter of the environment would have made this difficult for an external attacker to exploit; but a malicious inside could certainly have taken advantage of it.