Get-ADPermission vs Get-Acl & dsacls Cheatsheet

Rich
7 min readAug 1, 2023

TL;DR Explanation of Get-ADPermission vs Get-Acl vs dsacls with examples.

Welcome to the annexes of our Auditing AD Series!

Part I: 3 warm up questions to get us started

Part II: Who can reset the CISO’s password?

Part III: Who can execute DCSync?

Part IV: Who can modify the Domain Admins group?

Part V: P0wning a domain in minutes via ACL abuse (why auditing matters)

Part VI: Why Allow statements matter a LOT more than Deny ones

Part VII: Sneaky persistence via hidden objects in AD

Part VIII: SDDL, what is it, does it matter?

Part IX: Do you know who owns your domain?

Part X: Who can push ransomware via Group Policy?

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 A: Scrubbing Group Policy for local admins

Annex B: What Property Sets in AD are, & why they matter

Annex C: Dangerous Rights & RE GUIDs Cheatsheet

Annex D: Mishky’s Blue Team Auditor

Annex E: Even ChatGPT gets this stuff wrong

Annex F: Get-ADPermission Cheatsheet

Annex G: Mishky’s Red Team Enumerate & Attack tools

Background

ChatGPT gave us incomplete information and failed to explain ‘Get-ADPermission’, however with CW6 Google’s help we explored Get-ADPermission and Add-ADPermission in the lab. Get-ADPermission uses similar syntax to Get-Acl, however the output is different. Hence the first thing we did was translate it. Please note that the two don’t show all rights the same, for example ‘Reset Password’ doesn’t show up in Get-ADPermission at all.

This is likely because Add-ADPermission is intended for delegating rights over inboxes and Get-ADPermission is intended for checking the same. However ChatGPT mentioned them and we were curious, so this is what we put together.

+---------------------------------+--------------------------------------+
| Get-Acl | Get-ADPermission |
+---------------------------------+--------------------------------------+
| ActiveDirectoryRights | Access Rights |
| InheritanceType | InheritanceType |
| ObjectType | Properties | |
| InheritedObjectType | InheritedObjectType |
| ObjectFlags | |
| AccessControlType | Deny [True or False] |
| IdentityReference | User |
| IsInherited | IsInherited |
| InheritanceFlags | |
| PropagationFlags | |
| | ChildObjectTypes |
+---------------------------------+--------------------------------------+

Note; Get-ADPermission shows the AD object that the ACE is applied to in the ACE as the ‘Identity’.

It makes more sense with an example. Here are three different ways of showing Organization Management’s rights on Domain Admins:

How to even use Get-ADPermission

ChatGPT left this part out, but to even use this one requires the Exchange Management Shell. Once Exchange is setup one can connect and use this shell via:

#Establish a connection to the Exchange server:
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://TestExchange.test.local/PowerShell/ -Authentication Kerberos -Credential $UserCredential
Import-PSSession $Session -DisableNameChecking

#Once you're done just:
Remove-PSSession $Session

Disconnecting isn’t all that important in a home lab or test environment, but in a large production environment one wouldn’t want to leave too many sessions hanging.

Next we will show some other examples. We will use Set-Acl to grant the right and then show how to check with Get-Acl, Get-ADPermission, and dsacls.

Self

#Give a user Self over a given group
$victim = (Get-ADGroup "Test" -Properties *).DistinguishedName
$acl = Get-ACL $victim
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser -Identity "Mishka").SID

#Allow Self with specific GUID
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $user,"Self","ALLOW",([GUID]("bf9679c0–0de6–11d0-a285–00aa003049e2")).guid,"None",([GUID]("00000000–0000–0000–0000–000000000000")).guid))

#Apply above ACL rules
Set-ACL $victim $acl

Check via Get-Acl, Get-ADPermission, & dsacls:

#Compare Get-Acl to Get-ADPermission & dsacls using Mishka's Self rights on Test group

(Get-Acl (Get-ADGroup "Test").DistinguishedName).Access | Where-Object {($_.IdentityReference -like "*Mishka*")}

Get-ADPermission (Get-ADGroup "Test").DistinguishedName | Where-Object {($_.User -like "*Mishka*")} | Format-List

dsacls (Get-ADGroup "Test").DistinguishedName | Select-String "Mishka"

Reset Passwords & re-enable user accounts in an OU

#Give a group Password reset & re-enable over a given OU
$victim = (Get-ADOrganizationalUnit "ou=Test,ou=VIPs,dc=test,dc=local" -Properties *).DistinguishedName
$acl = Get-ACL $victim
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup -Identity "Service Desk").SID

#Allow specific password reset
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $user,"ExtendedRight","ALLOW",([GUID]("00299570–246d-11d0-a768–00aa006e0529")).guid,"Descendents",([GUID]("bf967aba-0de6–11d0-a285–00aa003049e2")).guid))

#Allow enabling accounts
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $user,"WriteProperty","ALLOW",([GUID]("a8df73f2-c5ea-11d1-bbcb-0080c76670c0")).guid,"Descendents",([GUID]("bf967aba-0de6–11d0-a285–00aa003049e2")).guid))

#Apply above ACL rules
Set-ACL $victim $acl

Check via Get-Acl, Get-ADPermission, & dsacls:

#Compare Get-Acl to Get-ADPermission & dsacls using Service Desk's rights on Test OU

(Get-Acl (Get-ADOrganizationalUnit "ou=Test,ou=VIPs,dc=test,dc=local").DistinguishedName).Access | Where-Object {($_.IdentityReference -like "*Service Desk*")}

Get-ADPermission (Get-ADOrganizationalUnit "ou=Test,ou=VIPs,dc=test,dc=local").DistinguishedName | Where-Object {($_.User -like "*Service Desk*")} | Format-List

dsacls (Get-ADOrganizationalUnit "ou=Test,ou=VIPs,dc=test,dc=local").DistinguishedName | Select-String "Service Desk"

Check a user account in that OU via Get-Acl, Get-ADPermission, & dsacls:

#Compare Get-Acl to Get-ADPermission & dsacls using Service Desk's rights on Test Dummy Jr

(Get-Acl (Get-ADUser "TestDummy").DistinguishedName).Access | Where-Object {($_.IdentityReference -like "*Service Desk*")}

Get-ADPermission (Get-ADUser "TestDummy").DistinguishedName | Where-Object {($_.User -like "*Service Desk*")} | Format-List

dsacls (Get-ADUser "TestDummy").DistinguishedName | Select-String "Service Desk"

Group Membership Property Set

Let’s try ‘Group Membership’. This includes WriteProperty Member, aka the ability to add & remove users from a group, but is so arcane that even BloodHound missed it.

#Give Mishka Membership rights on Test group
#WriteProperty with ObjectType = BC0AC240–79A9–11D0–9020–00C04FC2D4CF
#Give a user Membership over a given group
$victim = (Get-ADGroup "Test" -Properties *).DistinguishedName
$acl = Get-ACL $victim
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser -Identity "Mishka").SID

#Allow WriteProperty with Membership GUID BC0AC240–79A9–11D0–9020–00C04FC2D4CF
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $user,"WriteProperty","ALLOW",([GUID]("BC0AC240–79A9–11D0–9020–00C04FC2D4CF")).guid,"None",([GUID]("00000000–0000–0000–0000–000000000000")).guid))

#Apply above ACL rules
Set-ACL $victim $acl

Check via Get-Acl, Get-ADPermission, & dsacls:

#Compare Get-Acl to Get-ADPermission & dsacls using Mishka's Self rights on Test group

(Get-Acl (Get-ADGroup "Test").DistinguishedName).Access | Where-Object {($_.IdentityReference -like "*Mishka*")}

Get-ADPermission (Get-ADGroup "Test").DistinguishedName | Where-Object {($_.User -like "*Mishka*")} | Format-List

dsacls (Get-ADGroup "Test").DistinguishedName | Select-String "Mishka"

Add-ADPermission

Even though Add-ADPermission was probably intended for setting rights such as ‘Send As’ or ‘Receive As’, it can be used to delegate other rights over a user account.

Add-ADPermission -Identity “Test Dummy” -User “Mishka” -AccessRights ExtendedRight -ExtendedRights “Send As”

For example we can delegate Mishka the right to set a logon script on another user:

Add-ADPermission -Identity “Test Dummy” -User “Mishka” -AccessRights WriteProperty -Properties ScriptPath

Check:

Get-ADPermission -Identity “Test Dummy” | Where-Object {($_.User -like “*Mishka*”)} | Format-List

Add-ADPermission & Get-ADPermission work pretty well for this, however they start to break down for checking things like Reset Password as we saw earlier. They also don’t work well for delegating rights on a group.

Summary

The Exchange Management Shell is an interesting part of Exchange, and I’m sure we will spend more time with it as we get into M365 and Exchange hybrid. IMHO it is not a replacement for Get-Acl, Set-Acl, and dsacls. As we saw in ‘Ownership Matters’ and ‘Ownership & so called Effective Permissions’ dsacls has it uses to this day.

We didn’t try out enumerating every ‘Dangerous Right’ with Get-ADPermission, however in our sample set of ExtendedRight, Self, and various WriteProperty GUIDs it was too incomplete to use in Mishky’s Red or Blue Team tools. It failed to enumerate the ‘Reset Password’ ExtendedRight, for example, which is a pretty serious shortcoming.

It does do a nice job of resolving GUIDs into commonly understood names for the rights that it does enumerate fully. It is also useful for delegating and checking rights strictly related to Exchange such as ‘Send As’ or ‘Receive As’.

References

Connect remotely to Exchange Management Shell: https://learn.microsoft.com/en-us/powershell/exchange/connect-to-exchange-servers-using-remote-powershell?view=exchange-ps

Control Access Rights, aka ExtendedRight: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1522b774-6464-41a3-87a5-1e5633c3fbbb

Validated Writes, aka Self: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/20504d60-43ec-458f-bc7a-754eb64446df

ScriptPath GUID: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-ada3/c640630e-23ff-44e7-886f-16df9574039e

Property Sets & RE GUIDs: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/177c0db5-fa12-4c31-b75a-473425ce9cca

Rights matched to GUIDs: https://www.powershellgallery.com/packages/DSACL/1.0.0/Content/DSACL.psm1

--

--

Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.