TL;DR DACLs are the very basis of security in Windows. We have seen some misinformation out there though, so this is a ‘break it down Barney style’ primer on DACLs.
Welcome to Part XIX of our ‘Back to the Basics’ series!
Part I: NTDS.dit vs SAM
Part II: Ownership Matters
Part III: Recovering from a Crash
Part IV: Setting up a Simple Honeypot Account
Part V: Automating DC Deployment
Part VI: Sometimes it’s the dumbest thing
Part VII: Merry Christmas, macros, & Base64
Part VIII: Why old 0 Days make great teaching tools
Part IX: PowerShell & PS1s without PowerShell.exe
Part X: Ownership & so called “effective permissions”
Part XI: Windows Event Forwarding & SACLs
Part XII: Poorly planned honeypots & other Bad Ideas
Part XIII: Setting up a simple honey token
Part XIV: Smartcards and Pass-the-Hash
Part XV: Forwarding logs to Sentinel & basic alerts
Part XVI: Automating VM deployments in Hyper-V
Part XVII: Migrating the lab from ESXi to Hyper-V
Part XVIII: Centrally managing Hyper-V & Live Migrations
Part XIX: DACL Primer
Background
None of this is new, in fact none of it is even new here. We already ran a 16 part series on auditing DACLs in AD, added 7 annexes to it, ran a few exercises on querying and abusing DACLs in NTFS, created Red and Blue Team queries, and created Mishky’s AD Range that includes enumeration and abuse of DACLs on AD CS templates.
Back when I was first studying up for the MCSA I was creating and configuring test.local and of course Googling a lot. I read Sean Metcalf’s excellent material, William Panek’s book, countless articles on Microsoft Learn, and I stumbled on a certain vendor’s blog. I was probably Googling “AD security” or something similar.
Back then I thought they were really smart. They certainly think they are, one can tell from the language they use. The thing was, the more I learned and as I progressed through MCSA, CRTP, etc the more I realized a few things:
- They don’t actually show how to do anything. It’s all marketing and the point is always “buy our expensive tool”.
- Their methodology, and hence their tool, has issues.
- What they’re saying about great, free tools like BloodHound is disingenuous.
However I would not have bothered writing a Back to the Basics article on DACLs just because of that. We already covered most of the above in our Auditing AD Series, not to mention our Get-Acl and Set-Acl cheatsheets. A recent post I saw on LinkedIn prompted this.
Apparently a Back to the Basics primer on DACLs is required.
An example ACE
Invoke-Command -VMName "US-DC" {Import-Module ActiveDirectory ; Set-Location AD: ; (Get-Acl (Get-ADOrganizationalUnit -Filter {Name -eq "Server_Admins"}).DistinguishedName).Access | Where-Object {$_.IdentityReference -like "*Helpdesk*"} } -Credential $ChildDomainAdminCredObject
- ActiveDirectoryRights: Pretty self explanatory, see our ‘Dangerous Rights’ cheatsheet for more info
- InheritanceType: 3 possible values, listed below. See this for more info
_________________________________________________________________________
| None | applies only to the OU |
| Descendents | applies only to the objects in the OU, not the OU itself |
| All | applies to the OU and the objects in it |
-------------------------------------------------------------------------
- ObjectType: GUIDs specify specific attributes, extended rights, etc. See SelfADSI or similar cheatsheet.
- InheritedObjectType: specifies what type of AD object the right applies to. All 0s means all objects.
_______________________________________________________________
| Object Class | GUID |
| -----------------------|--------------------------------------|
| Organizational Units | bf967aa5–0de6–11d0-a285–00aa003049e2 |
| Computer | bf967a86–0de6–11d0-a285–00aa003049e2 |
| User | bf967aba-0de6–11d0-a285–00aa003049e2 |
| Groups | bf967a9c-0de6–11d0-a285–00aa003049e2 |
| Contacts | 5cb41ed0–0e4c-11d0-a286–00aa003049e2 |
---------------------------------------------------------------
- ObjectFlags: 3 possible values; None, ObjectTypePresent, InheritedObjectAceTypePresent
- AccessControlType: either ‘Allow’ or ‘Deny’
- IdentityReference: who has this right, shown as <domain>\<account or group>
- IsInherited: Pretty self explanatory, False means the right is set at this object, not inherited
- InheritanceFlags: 3 possible values; None, ContainerInherit, ObjectInherit
- PropagationFlags: 3 possible values; None, NoPropagateInherit, InheritOnly
What’s a child container vs a child leaf object? Excellent question. A child container object can contain other objects, a leaf cannot. Example containers are OUs, examples of leafs are users, computers, printers, etc. Yes, Microsoft can be maddening with their verbiage. An OU is also a container, but a container is also something like the Users container that exists in AD by default.
This example gives the Helpdesk Tier II group Reset Password and Enable rights on user accounts in the Server_Admins OU. Why would helpdesk be able to reset Server Admins passwords? Another excellent question, and why this example comes from Mishky’s AD Range.
An example NTFS DACL
Invoke-Command -VMName "Research-DC" {(Get-Acl "C:\HTTPsCertificates.json").Access} -Credential $CousinDomainAdminCredObject
This also comes from Mishky’s AD Range and shows the DACL on an exported AD CS template. Guess what rights everyone else has on this file, “effective” or otherwise?
An important note RE DACLs in Windows
Windows uses DACLs for everything from AD to NTFS to registry keys. There are even DACLs that dictate what groups are allowed to use WMI.
All others are implicitly denied if there is no ACE allowing them access. This means there are always deny statements in Windows DACLs even if they are not explicitly stated.
That’s what makes this statement by a certain vendor on LinkedIn so nonsensical.
If the Iron Dome was like Windows then all one would have to do is avoid putting an ACE in their DACL that allows hostile fire.
More odd statements from that vendor
Here is a small sample of statements from over the years.
Missing the forest for the trees
This is actually a rather funny saying when it’s applied to Active Directory.
The reason I had thought that this vendor sounded smart at first was because I didn’t yet know how to enumerate, abuse, set, tweak, etc DACLs and SACLs.
Once I learned a little though I realized something; so called “effective permissions” are really just a subset of permissions.
Free tools like BloodHound aren’t inaccurate at all. They are letting you know that an Allow statement is there, because one is there. The beauty of BloodHound lies in the ‘so what’. It maps out how an attacker could get from A to B by abusing a daisy chain of misconfigured Allows in DACLs to escalate their privileges. At the same time it shows the Blue Team where the ‘choke points’ are in these escalation paths so they can prioritize what to fix first. It does all this for free.
All the Deny statements in the world mean jack all if the attacker can seize ownership, if they can leave the group that is denied, or if they can modify the DACL. If a group should not have certain rights then don’t put an allow statement in that gives it to them. If a user should not have certain rights then do not put them in the group that holds those rights.
If you fix the Allows then you don’t have to worry about the Denys. If you don’t fix the Allows then Denys are likely to only make your Misconfiguration Debt worse, and leave gaps a clever attacker can slip through.
Deny in a default AD environment
Microsoft knows. That’s why this is just about the only Deny in a default AD environment.
Import-Module ActiveDirectory
Set-Location AD:
$Objects = (Get-ADObject -Filter * -Properties *).DistinguishedName
ForEach($Object in $Objects)
{
If((Get-Acl $Object).Access | Where-Object {$_.AccessControlType -eq "Deny"})
{
$Object
(Get-Acl $Object).Access | Where-Object {$_.AccessControlType -eq "Deny"}
}
}
Why is it there? Another excellent question. Ever wondered what this checkbox does in the background?
Summary
However as we already saw, there’s a huge number of implicit Deny statements on every object in AD, every file, every registry key, etc etc. If someone is not the Owner, can’t seize ownership by nature of being an Administrator, and is not given a right in an Allow ACE then they do not have that right.
Some call that “bloody inaccurate”, but it is how Windows works, not to mention SWs, RTRs, FWs, etc etc.
Some though are just interested in marketing, and believe that APTs don’t already know this stuff.
Here at test.local we like free. It’s why our Medium isn’t paywalled, it’s why everything we have done is on GitHub, it’s why Linus Torvalds is our hero and we don’t particularly care for Steve Jobs.
To Microsoft’s credit, they give away evaluation copies of their stuff for free. Their exams are cheap and renewal is free. Microsoft Learn contains a wealth of information for free. PowerShell is open source. Today Microsoft has more employees contributing to open source on GitHub than either Google or Red Hat.
Microsoft has really turned their ship around and come a long way from the laughing stock security wise that they were in the 90s and early 00s. They’re a completely different company now. They are no longer the “open source is cancer” company of Steve Ballmer. Hell even he has now admitted that he was wrong.
References
An ACE up the Sleeve whitepaper: https://specterops.io/wp-content/uploads/sites/3/2022/06/an_ace_up_the_sleeve.pdf
SelfADSI: http://www.selfadsi.org/deep-inside/ad-security-descriptors.htm
Attributes matched to GUIDs: https://learn.microsoft.com/en-us/windows/win32/adschema/attributes-all
Extended Rights matched to GUIDs: https://learn.microsoft.com/en-us/windows/win32/adschema/extended-rights
Self Rights, aka Validated Writes, matched to GUIDs: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/20504d60-43ec-458f-bc7a-754eb64446df
Property Sets matched to GUIDs: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/177c0db5-fa12-4c31-b75a-473425ce9cca
InheritanceFlags: https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.inheritanceflags?view=net-8.0
ObjectFlags: https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.objectaceflags?view=net-8.0
PropagationFlags: https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.propagationflags?view=net-8.0
Container vs leaf: https://www.serveracademy.com/blog/what-is-active-directory/#:~:text=Container%20AD%20Objects%20%E2%80%93%20these%20are,User%2C%20Computer%2C%20and%20printer.