š”ļø Authorization
Once a client was able to resolve the target hostname and get authenticated, the target service/program/computer should be now aware about its permissions, that is, know the user username and SID, and the groups it belongs to. Once this information is known, the program can decide if the user has enough privileges to access to certain objects.
ACLs
Security descriptor
But, how is it possible to check if the user has access to an object? By checking itsĀ security descriptor. In Active Directory, each object of the database has an associatedĀ security descriptorĀ in itsĀ NTSecurityDescriptorĀ property. The security descriptor is stored in aĀ binary format, but it can also be translated to aĀ Security Descriptor String Format.
The security descriptor contains the following security information:
- 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 user -Properties nTSecurityDescriptor).nTSecurityDescriptor | select Owner,Gro
up,Access,Audit | Format-List
Owner : ETHERDRAKE\Domain Admins
Group : ETHERDRAKE\Domain Admins
Access : {System.DirectoryServices.ActiveDirectoryAccessRule, System.DirectoryServices.ActiveDirectoryAccessRule,
System.DirectoryServices.ActiveDirectoryAccessRule, System.DirectoryServices.ActiveDirectoryAccessRule...}
Audit :
Get security descriptor of user object
As you can see, there could be two ACL (Access Control List) in each security descriptor: DACL and SACL. 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.
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 user -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
ACE of user account
Therefore,Ā ACEs can be used to grant access, but also to restrict it. It should be note that in case a principal is both allowed and denied access by different ACEs, then the deny ACE has preference and the access is denied.
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
There is an special case that is not limited by ACEs, and is the objectĀ owner. TheĀ owner has implicit permission to modify the ACEsĀ of an object (WriteDacl right).
Moreover, it must be also taken into account that in case of the security descriptor has no DACL (DACL set to NULL), everyone has any access to the object. However if the security descriptor has an empty DACL (no ACEs in the DACL), then no one has access to the object.
Rights
TheĀ following rightsĀ can be specified in a ACE:
- Delete: Delete the object.
- ReadControl: Read the security descriptor, except the SACL.
- WriteDacl: Modify the object DACL in the security descriptor.
- WriteOwner: Modify the object owner in the security descriptor.
- CreateChild: Create child objects. For containers.
- DeleteChild: Delete child object. For containers.
- ListContents: List child objects. For containers. The object is hidden from user if this right nor ListObject are not granted.
- ReadProperty: Read the property orĀ property setĀ specified in object type. If object type is zero, then all properties can be read. It does not allow to read theĀ confidential properties.
- WriteProperty: Modify the property specified in object type. If object type is zero, then all properties can be modified.
- WritePropertyExtended: Execute aĀ validated write. Maybe the most interestingĀ validated writeĀ is theĀ Self-MembershipĀ for groups, that allows to add your current user to the group with the ACE.
- DeleteTree: Delete all the child objects with a delete-tree operation.
- ListObject: List the object. The object is hidden from user if this right nor ListContents are not granted.
- ControlAccess: Special permission that can be interpreted in many different ways, based on the object type. In case the object type is a GUID of aĀ confidential property, it gives permission to read it. If is the GUID of anĀ extended rightĀ registered in the database schema, then the right is given. In case the object type is null (GUID is all zeros) then all the extended rights are granted.
There are also some generic rights that encompass several rights:
- GenericRead: ReadControl, ListContents, ReadProperty (all), ListObject.
- GenericWrite: ReadControl, WriteProperty (all), WritePropertyExtended (all).
- GenericExecute: ReadControl, ListContents.
- GenericAll: Delete, WriteDacl, WriteOwner, CreateChild, DeleteChild, DeleteTree, ControlAccess (all), GenericAll, GenericWrite.
There are manyĀ extended rights, but here are ones of the most interesting:
- 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.
PS C:\Users\Administrator\Downloads> (Get-Acl 'AD:\DC=etherdrake,DC=local').Access[49]
ActiveDirectoryRights : ExtendedRight
InheritanceType : None
ObjectType : 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : ETHERDRAKE\Domain Controllers
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
DS-Replication-Get-Changes-All right in domain
The previous example shows an ExtendedRight ACE, that gives DS-Replication-Get-Changes-All in domain for the Domain Controllers group.
As you can imagine, when someone says that the Domain Admins group has admin privileges in the domain, that means that is a group for which there are a lot of ACEs in objects given a lot of rights, so you can assume that belonging to the Domain Admin group, you can perform a lot of privilege actions, but ultimately are the DACLs of the objects the ones that determines the power of a group/user.
Apart from the database objects, in Windows machines, there are also manyĀ securable objectsĀ that also are protected by local DACLs that are managed by the local computer. Among these objects are the files/directories, the processes, registry keys or services. But since theĀ Domain AdminsĀ are added by default to localĀ AdministratorsĀ group in the machines, is usual that a domain admin can access to any local object in a Windows computer. You can use tools likeĀ Get-Acl,Ā icaclsĀ to check file ACLs.
ACL attacks
Due to the huge amount of ACLs that can be in a domain, it can be complex to manage them. This can produceĀ several misconfigurationsĀ that could allow an attacker toĀ elevate privilegesĀ in the domain, or even in the forest (remember that domains of the same forest are connected so you can add ACE refer to principals of other domains). Let's review some misconfigurations:
- Change the user password: If you have User-Force-Change-Password or GenericAll rights over an user object, you can take over the account by setting a new password.
- Make user Kerberoasteable: If you can write an SPN in theĀ ServicePrincipalNameĀ property of an user then you can perform theĀ KerberoastĀ attack against that account and try to crack its password. To write an SPN requires you to have theĀ Validated-SPNĀ validated write with WritePropertyExtended, or GenericWrite or GenericAll.
- Execute malicious script: If you can modify theĀ
ScriptPathĀ property of an user, with WriteProperty, GenericWrite or GenericAll, then you can set a malicious file that is going to be execute the next time that the user logs on. You can useĀ an UNC path to point to a share. You may also require to enable theĀ SCRIPTĀ flag of the UserAccountControl property. - Add users to group: If you can modify theĀ membersĀ property of a group, with WriteProperty, GenericWrite or GenericAll, then you can add any member to the group. If you have the right for Self-Membership, you can add your current user to that group.
- Kerberos RBCD attack: If you can modify theĀ
msDS-AllowedToActOnBehalfOfOtherIdentityĀ of a computer account, with WriteProperty, GenericWrite or GenericAll, then you enable Kerberos Resource Based Constrained Delegation for another user to the computer services and finally get access as admin to the computer. - LAPS password: If you can read theĀ ms-Mcs-AdmPwdĀ computer confidential property used by LAPS to store the machine local administrators password, then you could read it an access as local admin to the machine. You can identify the use of LAPS in a machine by checking if theĀ ms-Mcs-AdmPwdExpirationTimeĀ property exists in its computer account.
- DCSync attack: If you have theĀ
DS-Replication-Get-ChangesĀ andĀDS-Replication-Get-Changes-AllĀ extended rights over the domain object, then you can perform a DCSync attack to dump the database contents. - GPO abuse: If you can modify theĀ
GPC-File-Sys-PathĀ of aĀ Group Policy ContainerĀ with WriteProperty, GenericWrite or GenericAll, then you can modify the GPO and perform code execution in the computers affected by the GPO. - Modify ACLs: If you have the WriteDacl right (or GenericAll), then you can create ACE to give any right in the object and perform some of the previous attack. Also, if you have the WriteOwner right, since the owner object has implicit WriteDacl right, you can change the object owner to your user and then modify ACLs.
Besides the possibilities of elevating privileges, ACLs can be also pretty useful and stealthy if you want toĀ create backdoorsĀ to keep your access in the network. In order to create backdoors there are a few tricks about hiding the malicious ACEs described in theĀ An ACE Up the SleeveĀ whitepaper written by the specterops team that you should check.
AdminSDHolder
However, maybe one the most interesting persistence tricks is to modify theĀ AdminSDHolderĀ object. AdminSDHolder is an special object in the database whose DACL is used as template for the security descriptor of privileged principals.
PS C:\> Get-ADObject 'CN=AdminSDHolder,CN=system,DC=etherdrake,DC=local'
DistinguishedName Name ObjectClass ObjectGUID
----------------- ---- ----------- ----------
CN=AdminSDHolder,CN=system,DC=etherdrake,DC=local AdminSDHolder container 7f34e8a5-ffbd-474a-b436-1e02b7b49984
The AdminSDHolder object
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 principals.
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
If you are familiar with the Windows platform, probably you know about the user privileges, that allow the users to perform actions bypassing the ACLs of the objects. For example, the SeDebugPrivilege in a Windows machine allows to read/write in any process memory of the machine even if you don't have rights.
In Active Directory,Ā some privileges can be also abusedĀ (mainly in the Domain Controllers):
SeEnableDelegationPrivilege
SeEnableDelegationPrivilegeĀ must be set in the Domain Controller for an user (is a local privilege) and then it allows to modify theĀ msDS-AllowedToDelegateToĀ property of users and theĀ TRUSTED_FOR_DELEGATIONĀ andĀ TRUSTED_TO_AUTH_FOR_DELEGATIONĀ flags from the UserAccountControl property. In other words, SeEnableDelegationPrivilegeĀ allows to control the Kerberos Unconstrained and Constrained DelegationĀ options of the domain, which could be used by an attacker to escalate privileges. By default is only given to the Administrator account.
SeBackupPrivilege
TheĀ backup privilegeĀ allows to read any file of a domain controller, in order to backup it, which could be used to read the domain database. By default is given toĀ Backup Operators,Ā Server OperatorsĀ andĀ AdministratorsĀ groups. The privilege is only effective when using theĀ NTFS backup API, that can be accessed through theĀ wbadminĀ utility orĀ Powershell WindowsServerBackupĀ (both require theĀ Windows Server BackupĀ feature). You can also useĀ reg saveĀ toĀ access to the SAM and LSA secrets.
SeRestorePrivilege
TheĀ restore privilegeĀ allows to write any file on the domain controller from a backup. This could allow an attacker to modify the database of the domain. By default is given toĀ Backup Operators,Ā Server OperatorsĀ andĀ AdministratorsĀ groups. You can use this privilege toĀ modify registry keys and achieve privileged command execution.
SeTakeOwnershipPrivilege
With theĀ take ownership privilege, you can take theĀ ownership of securable objectsĀ of the machine, like files, processes or registry keys. The owner of the object can always modify the permissions of the object (WriteDacl). For example, you can use theĀ SetNamedSecurityInfoĀ API call to take the ownership of the object. How can I take ownership of Active Directory database objects???
Apart from the privileges used in the domain, is also useful to be aware of theĀ dangerous privilegesĀ that can be useful for elevate privileges in a Windows machine. Commonly the following are used:
SeDebugPrivilege
The user can debug any process in the machine, so it can inject code in any process, which could lead to privilege escalation, or read the memory of the process, that allows to read, for example, the lsass process secrets of users logged on the machine (you can useĀ mimikatz).
SeImpersonatePrivilege
The user can acquireĀ security tokensĀ of other users in the machine. If the impersonation token level is SecurityDelegation, then the user can use that token to impersonate the target user in other machines of the domain (SecurityDelegation tokens are associated with user credentials like Kerberos tickets that can be used in network connections). If the impersonation token level is SecurityImpersonation, then the target user only can be impersonated in the local machine (useful for privilege escalation). The SeImpersonatePrivilege is given to the "NT AUTHORITY\Network Service" that is usually use for running web servers and stuff like that, so if you can compromise a web server, maybe you can useĀ incognitoĀ to impersonate some domain user across the network. But definitely, if you want to elevate privileges with SeImpersonatePrivilege in the local machine, use aĀ potato.
There are other privileges that can be used to get elevation of privileges in Windows machines, if you are interested in them, you should check theĀ token-privĀ repository of FoxGlove that includes a paper describing them and PoCs to exploit them, highly recommended resource.