Rachit Arora
Active Directory: ACLs
Apr 11, 2024Access Control List Model ( ACL )
Enables control on the ability of a process to access objects and other resources in active directory based on:
- Access Token a. Security Context of a process b. Identitiy and privs of user
- Security Descriptors
- SID of principal that is the object owner
- SID of the owner primary group
- (Optional) DACL (Discretionary Access Control List)
- (Optional) SACL (System Access Control List)
PS C:\> $(Get-ADUser anakin -Properties nTSecurityDescriptor).nTSecurityDescriptor | select Owner,Gro
up,Access,Audit | Format-List
Owner : CONTOSO\Domain Admins
Group : CONTOSO\Domain Admins
Access : {System.DirectoryServices.ActiveDirectoryAccessRule, System.DirectoryServices.ActiveDirectoryAccessRule,
System.DirectoryServices.ActiveDirectoryAccessRule, System.DirectoryServices.ActiveDirectoryAccessRule...}
Audit :
An ACL is a list of ACEs (Access Control Entry). The ACEs of the SACL defines the access attempts that are going to generate logs, and they can be useful from a defensive perspective.
However, the most important part is the DACL, that is usually present in all the objects, whose ACEs determines the users/groups that can access to the object, and the type of access that is allowed. Usually when someone refers to the object ACL, it means the DACL
DACL
Defines the permissions trustees (a user or group) have on an object.
DACL Structure
The access control list consists of multiple individual permissions known as ACEs Access Control Entries.
Each entry has a permission type (allow or deny), a principal account (who is this permission for — user, group, computer), what objects the principal account can access, and the access rights [read, write, Full Control].
SACL
SACL - Logs success and failure audit messages when an object is accessed.
Every object have Security Descriptors
ACEs
Each ACE has several parts:
- ACE type: Specifies if the ACE is for allowing or denying access (or logging access in case of SACL).
- Inheritance: Indicates if the ACE is inherited.
- Principal/Identity: Indicates the principal (user/group) for which the ACE is applied. The principal SID is stored.
- Rights: Indicates the type of access the ACE is applying.
- Object type: A GUID that indicates an extended right, property, or child object depending on the Access Mask flags. Is set to zero if not used.
- Inheritance type: The type of object class that can inherit the ACE from this object
PS C:\Users\Administrator> $(Get-ADUser anakin -Properties nTSecurityDescriptor).nTSecurityDescriptor.Access[0]
ActiveDirectoryRights : GenericRead
InheritanceType : None
ObjectType : 00000000-0000-0000-0000-000000000000
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : None
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SELF
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
On the other hand, ACEs can be inherit from parent objects of the database (OUs and containers), and actually, most of the ACEs that apply to objects are inherited. In case of a inherited access contradicts an explicit ACE (not inherited), then the explicit ACE determines the access rule. Thus, the precedence is the following for ACEs:
- Explicit deny ACE
- Explicit allow ACE
- Inherited deny ACE
- Inherited allow ACE
Active Directory object permissions
Some of the Active Directory object permissions and types that we as attackers are interested in:
GenericAll - full rights to the object (add users to a group or reset user’s password)
GenericWrite - update object’s attributes (i.e logon script)
WriteOwner - change object owner to attacker controlled user take over the object
WriteOwner - change object owner to attacker controlled user take over the object
AllExtendedRights - ability to add user to a group or reset password
ForceChangePassword - ability to change user’s password
Self (Self-Membership) - ability to add yourself to a group
There are many extended rights, but here are ones of the most :
- User-Force-Change-Password: Change the user password without knowing the current password. For user objects. Do not confuse with User-Change-Password right, that requires to know the password to change it.
- DS-Replication-Get-Changes: To replicate the database data. For the domain object. Required to perform dcsync.
- DS-Replication-Get-Changes-All: To replicate the database secret data. For the domain object. Required to perform dcsync
ACL attacks
Change the user password
Make user Kerberoasteable
Execute malicious script
Add users to group
Modify ACLs
GPO abuse
There are more, would be writing a different blog for that
Enumerating ACLs
# The GUID resolver parameter gets the group ID of the requested object.
Get-DomainObjectAcl -SamAccountName studentl -ResolveGUIDs
# Get the ACLs associated with the specified prefix to be used for search
Get-DomainObjectAcl -SearchBase "LDAP://CN=Domain Admins,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local" -ResolveGUIDs -Verbose
# Check the Domain Admins permission - PowerView as normal use
Get-DomainObjectAcl -Identity 'Domain Admins' - ResolveGUIDs | ForEach-Object {$_ | Add-Member NoteProperty 'IdentityName' $(Convert-SidToName $_.SecurityIdentifier);$_} | {$_.IdentityName -match "student1"}
# ActiveDirectory Module
(Get-Acl -Path 'AD:\CN=Domain Admins,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local').Access | ?{$_.IdentityReference -match 'student1'}
# We can also enumerate ACLs using ActiveDirectory module but without resolving GUIDs (ADModule)
(Get-Acl 'AD:\CN=Administrator,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local').Access
#To filter through a specific type of permission, use the equal (-eq) operator and pass it the permission type such as “GenericAll.
Get-ObjectAcl student181 | Where-Object ActiveDirectoryRights -eq "GenericAll"
Get-ObjectAcl student181 | select IdentityReference, ActiveDirectoryRights | Where-Object ActiveDirectoryRights -eq "GenericAll"
# Search for interesting ACEs
Find-InterestingDomainAcl -ResolveGUIDs
Get-PathAcl -Path "\\dcorp-dc.dollarcorp.moneycorp.local\sysvol"
# Get The ACLs associated with specified LDAP path
Get-ObjectAcl -ADSpath "LDAP://CN=Domain Admins, CN=Users, DC=dollarcorp, DC=monycorp, DC=local" -ResolveGUIDS -Verbose
#Search For Interesting ACEs
Invoke-ACLScanner -ResolveGUIDS
Invoke-ACLScanner -ResolveGUIDS | ?{$_.IdentityReferenceName -match "RDPUsers"}
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "studentx"}
AdminSDHolder
AdminSDHolder is an special object in the database whose DACL is used as template for the security descriptor of privileged principals.
Every 60 minutes, the SDProp (Security Descriptor Propagator) examines the security descriptor of these privileged principals, and replace their DACL with a copy of AdminSDHolder DACL (if they differ). This is done in order to prevent modifications on the DACLs of these principals, but if you are able to add custom ACEs to the AdminSDHolder DACL, then these new ACEs will also being applied to the protected principal
By default the following principals are “protected” by AdminSDHolder:
- Account Operators
- Administrator
- Administrators
- Backup Operators
- Domain Admins
- Domain Controllers
- Domain Guests
- Enterprise Admins
- Enterprise Key Admins
- Enterprise Read-Only Domain Controllers
- Key Admins
- krbtgt
- Print Operators
- Read-only Domain Controllers
- Replicator
- Schema Admins
- Server Operators
Privileges
In Active Directory, some privileges can be also abused (mainly in the Domain Controllers):
SeEnableDelegationPrivilege
SeBackupPrivilege
SeRestorePrivilege
SeTakeOwnershipPrivilege
SeDebugPrivilege
SeImpersonatePrivilege
check the token-priv repository of FoxGlove that includes a paper describing them and PoCs to exploit them, highly recommended resource.
Additional resources
https://www.harmj0y.net/blog/
https://zer1t0.gitlab.io/posts/attacking_ad/
https://dirkjanm.io/
https://adsecurity.org/