The Group Membership Property Set, even more arcane than the Self privilege
TL;DR explanation of the Group Membership Property Set, and how it allows a user to change a group’s membership.
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: Domain dominance in minutes via ACL abuse (i.e. why auditing AD 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
The Group Membership Property Set right, or privilege, might be even more obscure than the Self right we covered back in Parts XII and XIV. I saw almost nothing about it on Google, it’s not even listed in Active Directory Users & Computers (ADUC), in fact about the only mention of it I found was buried in Microsoft’s documentation. The description of what it meant and what privileges it actually gave was buried in a PDF on Microsoft Learn.
According to the PDFs, the Group Membership Property Set includes Member and MemberOf. Hence the right grants the exact same privileges as WriteProperty Member, in other words it allows one to change the membership of the group.
In PowerShell parlance:
WriteProperty
+-------------------------+--------------------------------------+
| Right | ObjectType |
+-------------------------+--------------------------------------+
| Member | bf9679c0–0de6–11d0-a285–00aa003049e2 |
| Membership Property Set | BC0AC240-79A9-11D0-9020-00C04FC2D4CF |
+-------------------------+--------------------------------------+
Please note that in practice both of these rights grant a user or group the exact same privilege; the ability to change the membership of a given group.
However the second right is so obscure that it didn’t even show up in BloodHound.
Enough theory, let’s demo it
We will give a regular old Domain User the Group Membership Property Set on a group and then show that it allows them to modify the group membership. We will do this in PowerShell, not only because we here at test.local are partial to it but because I flat out could not find this right in ADUC.
Import-Module ActiveDirectory
Set-Location AD:
#Give a user WriteProperty 'Membership' on a given group
$victim = (Get-ADGroup "VIPs" -Properties *).DistinguishedName
$acl = Get-ACL $victim
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser "Mishka").SID
#Allow specific WriteProperty 'Membership'
$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
Confirm via the query below:
(Get-Acl (Get-ADGroup “VIPs”).DistinguishedName).Access | Where-Object {$_.IdentityReference -like “*mishka*”}
Alt using dsacls:
dsacls “cn=vips,ou=vips,dc=test,dc=local” | Select-String -Pattern “mishka” -Context 1
Sidenote; I am probably just preaching to the choir, but bear in mind that PowerShell commands like Get-Acl return objects. However legacy cmd.exe commands like dsacls return strings. This is a very important distinction once you start parsing the output.
Contrast the above with ADUC, which doesn’t even show the right.
Next, we will jump on a domain workstation as Mishka and see if we can indeed add her to the group VIPs.
$env:USERNAME
(Get-ADGroupMember "VIPs").SamAccountName
Add-ADGroupMember -Identity "VIPs" -Members $env:USERNAME
(Get-ADGroupMember "VIPs").SamAccountName
Checking for this
Interestingly enough BloodHound didn’t pick this up. I put in the VIPs group as the target, Mishka as the starting point, and did not get a path.
PowerView’s Invoke-AclScanner picks it up.
Invoke-ACLScanner | Where-Object {($_.IdentityReference -like “*Mishka*”) -and ($_.ObjectDN -like “*VIPs*”)}
One of the really nice features of PowerView’s Invoke-ACLScanner is that it can show you the names instead of the GUIDs.
Get-ObjectAcl -SamAccountName VIPs -ResolveGUIDs | Where-Object {($_.IdentityReference -like "*Mishka*")}
Invoke-ACLScanner -ResolveGUIDs | Where-Object {($_.IdentityReference -like "*Mishka*") -and ($_.ObjectDN -like "*VIPs*")}
‘Mishka’s PowerView’, both the Blue Team and Red Team versions, picks it up. We started on that project back in Part X of this series and have been tweaking it as we go along.
The Red Team version is here. We borrowed the idea and the initial code from Trimarc’s AD CS check, then tweaked it so it checks:
- Nested groups
- Groups like Domain Users, Authenticated Users, etc just in case something was badly misconfigured
- Dangerous Rights held by the given user on any AD object
The Blue Team version checks for Dangerous Rights held by any non-whitelisted users/groups. Much like Trimarc’s AD CS check, one white lists the groups that have been delegated control of OUs like the service desk and then simply checks if anyone else has rights that shouldn’t. Much like the Red Team version it shows any offending ACEs and the object to which it is applied. One can then easily remove the ACE thereby mitigating the incorrectly granted privilege.
The initial working version is in Part XI of this series.
Summary
There are some incredibly arcane rights that exist in Windows as the system is quite granular. This particular one borders on being a sneaky persistence mechanism as it’s not listed in ADUC and doesn’t show up in BloodHound, yet it allows someone to change a group’s membership, for example Domain Admins.
References
Microsoft on Property Sets: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/177c0db5-fa12-4c31-b75a-473425ce9cca
Ascii Table easy creation: https://ozh.github.io/ascii-tables/