TL;DR this is a sample scenario of how a lowly Domain User can take over a domain by simply abusing ACLs in AD.
Welcome to Part V of our Auditing AD series.
Part II: Who can reset the CISO’s password?
Part III: Who can execute DCSync?
Part VIII: SDDL, what is it, does it matter?
Part IX: Do you know who owns your domain?
Part XI: Free ways to simplify auditing AD
Part XII: Sidenote on arcane rights like Self
Part XIII: Sidenote on the ScriptPath right
Part XIV: Self & so called “Effective Permissions”
Part XV: Inheritance Explained & an Example
Part XVI: Summary of our Auditing AD Series
Annex D: Mishky’s Blue Team Auditor
Annex E: Even ChatGPT gets this stuff wrong
Annex F: Get-ADPermission Cheatsheet
Auditing Windows domains in general and AD in particular can be boring. ACLs in AD can be even more so. IMHO AD is the very basis of Identity & Access Management (IAM) in Windows domains, and if you don’t have IAM then you don’t have cybersecurity. However it is not a sexy, exciting topic so I am not sure it gets much attention. Often there is really no product to sell, just effective querying via PowerShell, so it may not get much vendor attention.
Why it is vital
This lab exercise shows how a lowly Domain User can take over the domain by merely enumerating AD and then abusing poorly configured ACLs. They are aided by a rather messy AD architecture as well. We are using Paramount Defenses VM with a fictional company’s AD pre-populated in the image. This VM is available here.
I found it to be an educational experience on enumerating ACLs and showing just how critical they are.
I had been learning ACLs during the Auditing AD series on this blog and I came across something interesting in our lab VM; two groups are explicitly denied privileges on several high value AD objects such as the Domain Admins group and the domain root.
Additionally, the IT Contractors group is a member of the Contractors group. Therefore everyone in both groups is denied the specified privileges on the domain root.
So why would IT CTRs and CTRs be explicitly denied certain privileges on high value AD objects? Is it because they are CTRs and not regular employees? Or is it because their accounts were over privileged earlier and rather than just fix the underlying issue the decision was made to try a bandaid fix via a couple Deny statements?
To answer that question we will do two things:
- Pick a member of the IT Contractors group at random
- Assume Compromise
In this case it really doesn’t matter if our lucky winner was the victim of a phishing attack, got blue falconed by a co-worker, or is a disgruntled insider. Their account is compromised. What could happen?
In this case we landed on Isabella Shaw. She’s a member of IT Contractors, and several other groups. So what access does she have and is there an escalation path?
BloodHound is a great free tool that will get us a lot closer to an answer. It shows relationships in AD graphically:
In this case it will show us a path from Isabella Shaw’s account to the Domain Admins group:
There we have it. BloodHound just did the hard work for us. Isabella Shaw can move laterally through two other accounts and then modify the Domain Admins group. In this case our lucky winners for lateral movement are Kim Goodman and Elizabeth Brown.
All that’s left to do is verify the relevant ACLs and execute the attack. We can do this using just PowerShell and optionally using PowerView as it greatly aids in enumerating ACLs.
We start by enumerating Isabelle Shaw’s privileges and confirming that she can indeed reset Kim Goodman’s password.
This can be easily done in PowerView’s Invoke-ACLScanner. This handy tool can scan all the ACLs in the domain to find any privileges the user or the groups they are a member of might possess. In this case we are looking specifically for rights on Kim Goodman’s account, so to speed things up I told PowerView to only check that AD object.
Please note that Microsoft Defender [formerly known as Windows Defender] will stop PowerView from running. However anyone can Google the AMSI bypass, copy/paste it, and then import and run PowerView just fine.
We see that Isabella Shaw is a member of IT EMEA Admins and that group can reset Kim Goodman’s password.
We can now login as in Kim Goodman and continue to move laterally. First let’s confirm that Kim Goodman can take over Elizabeth Brown’s account via another password reset.
We see that Kim is a member of the group ‘IT Contingency Support Team’, and that group has privileges to reset Elizabeth’s password.
On a sidenote, we can also see this in the builtin PowerShell AD module commands. An attacker or disgruntled insider does not have to use PowerView. PowerView just makes thing slightly easier since PowerShell is focused on viewing the ACLs on a given AD object, whereas PowerView is focused on finding out all privileges over all AD objects possessed by a given account.
Kim Goodman now takes over Elizabeth Brown’s account.
The process is then repeated. We confirm that Elizabeth Brown has privileges on the Domain Admins group. Elizabeth then takes advantage of this ACL and adds herself to the Domain Admins group.
Things get a bit messy at this point. Elizabeth is in numerous other groups and some of these are denied privileges in other ACLs. However she can get around this by simply creating a new user account and adding that user to Domain Admins. She’s a Domain Admin now after all. She has privileges.
Elizabeth can now run her CLI of choice as JaneTemp, grab the krbtgt hash, and impersonate any user she wants for the next 10 years.
The kicker; even doing this manually, confirming the privileges between each lateral movement, and taking screenshots and notes along the way … this only took me about an hour in the lab. A clever attacker would script it and seize control of the domain within minutes, if not seconds. They could even script the deployment of ransomware via a scheduled task in Group Policy to run immediately after sufficient privileges were gained. That’s what the attackers did in the Colonial Pipeline ransomware infection last summer.
Enumerating AD to find the escalation path is what takes time, not the attack itself. Since various AD objects are constantly reading AD, this would be quite difficult to catch in practice. All Domain Users, aka all Authenticated Users, can read AD. This means everyone can enumerate AD. A clever attacker or disgruntled insider will likely know the domain better than management does very quickly, possibly better than even the sysadmins know it.
Therefore preventing this kind of attack revolves around a couple critical tasks.
- Properly architecting the domain hierarchy from the get go
- Properly architecting groups and their privileges from the get go
- Barring that, effectively auditing AD to find what was setup wrong
- Actually fixing it, and then auditing again to verify
Auditing effectively can be done on the cheap with BloodHound, PowerView, and/or PowerShell itself. It can be done with a paid tool like the one this vendor sells [the same vendor who provided this VM & AD environment we used in the lab]. The key is it needs to be done. Sooner or later an attacker will likely get a foothold on the domain via phishing, drive drops, malware, a disgruntled insider, or any number of other ways. Don’t let a compromise of one Domain User or one domain workstation turn into a compromise of the entire domain!