# DACL Overview

Within the Windows security ecosystem, `tokens` identify the security context of a process or a thread and `security descriptors` contain the security information associated with an object. To achieve `Confidentiality`, many operating systems and directory services utilize `access control lists` (`ACLs`): a mechanism that implements access control for a system resource by enumerating the system entities that are permitted to access the resource and stating, either implicitly or explicitly, the access modes granted to each entity.

Access control policies dictate what types of access are permitted, under what circumstances, and by whom. The four general categories of access control policies are:

* DAC - Discretionary access control: controls access based on the requestor's identity and access rules stating what requestors are allowed to do. It is discretionary because an entity might have access rights that permit it, by its own volition, to enable another entity to access some resource
* MAC - Mandatory access control: the entity having access to a resource may not, just by its own volition, enable another entity to access that resource
* RBAC - Role-based access control
* ABAC - Attribute-based access control

*Windows is an example of a `DAC` operating system, which utilizes Discretionary access control lists or DACLs. witch are part of the bigger picture of security descriptors.*

#### Security Descriptors

In Windows, every object (also known as [securable objects](https://learn.microsoft.com/en-us/windows/win32/secauthz/securable-objects)) has a security descriptor data structure that specifies who can perform what actions on the object.

```cpp
typedef struct _SECURITY_DESCRIPTOR {
  BYTE                        Revision;
  BYTE                        Sbz1;
  SECURITY_DESCRIPTOR_CONTROL Control;
  PSID                        Owner;
  PSID                        Group;
  PACL                        Sacl;
  PACL                        Dacl;
} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
```

Only four of the seven members of the `SECURITY_DESCRIPTOR` struct matter to us for the exploitation of DACLs.

The `security descriptor` is a binary data structure that can contain six main fields:

* Revision Number: the SRM (Security Reference Monitor) version of the security model used to create the descriptor
* Control Flags: optional modifiers that define the behavior/characteristics of the security descriptor
* Owner SID: the object's owner SID
* Group SID: the object's primary group SID - only the [Windows POSIX](https://en.wikipedia.org/wiki/Microsoft_POSIX_subsystem) subsystem utilized this member (before being [discontinued](https://social.technet.microsoft.com/wiki/contents/articles/10224.posix-and-unix-support-in-windows.aspx)), and most AD environments now ignore it
* Discretionary access control list: specifies who has what access to the object - throughout the `DACL Attacks` mini-modules, our primary focus will be abusing and attacking these
* System access control list or SACL: specifies which operations by which users should be logged in the security audit log and the explicit integrity level of an object

We are interested in the Control, Owner, Sacl and Dacl fields.

A `security descriptor` can be one of two forms:

* [absolute or self-relative](https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors)
* absolute security descriptors: contain pointers to the information, as in the `SECURITY_DESCRIPTOR` struct above, and these are the ones that we will encounter when interacting with Windows objects, whether AD ones or not

Self-relative security descriptors are not very different: instead of storing pointers, they store the actual data of a security descriptor in a contiguous memory block -these are meant to store a security descriptor on a disk or transmit it over the wire

#### Control Field

The Control member is of type [SECURITY\_DESCRIPTOR\_CONTROL](https://learn.microsoft.com/en-gb/windows/win32/secauthz/security-descriptor-control), a 16-bit set of bit flags that qualify the meaning of a security descriptor or its components. The value of Control, when retrieved with the function [GetSecurityDescriptorControl](https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-getsecuritydescriptorcontrol), can include a combination of 13 bits flags:

| Flag                                                                                                                                                               | Hexadecimal Representation |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------: |
| [SE\_DACL\_AUTO\_INHERIT\_REQ](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_DACL_AUTO_INHERIT_REQ) |          `0x0100`          |
| [SE\_DACL\_AUTO\_INHERITED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_DACL_AUTO_INHERITED)      |          `0x0400`          |
| [SE\_DACL\_DEFAULTED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_DACL_DEFAULTED)                 |          `0x0008`          |
| [SE\_DACL\_PRESENT](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_DACL_PRESENT)                     |          `0x0004`          |
| [SE\_DACL\_PROTECTED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_DACL_PROTECTED)                 |          `0x1000`          |
| [SE\_GROUP\_DEFAULTED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_GROUP_DEFAULTED)               |          `0x0002`          |
| [SE\_OWNER\_DEFAULTED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_OWNER_DEFAULTED)               |          `0x0001`          |
| [SE\_SACL\_AUTO\_INHERIT\_REQ](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_SACL_AUTO_INHERIT_REQ) |          `0x0200`          |
| [SE\_SACL\_AUTO\_INHERITED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_SACL_AUTO_INHERITED)      |          `0x0800`          |
| [SE\_SACL\_DEFAULTED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_SACL_DEFAULTED)                 |          `0x0008`          |
| [SE\_SACL\_PRESENT](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_SACL_PRESENT)                     |          `0x0010`          |
| [SE\_SACL\_PROTECTED](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_SACL_PROTECTED)                 |          `0x2000`          |
| [SE\_SELF\_RELATIVE](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/secrcw32prov/win32-securitydescriptor#SE_SELF_RELATIVE)                   |          `0x8000`          |

These binary flags can be added to represent any combinations - for example, if the value of `Control` is `0x8014`, it signifies the presence of the `SE_DACL_PRESENT`, `SE_SACL_PRESENT`, and `SE_SELF_RELATIVE` flags.

#### Owner Field

The Owner and Group members contain a pointer to the Security Identifier of the object's owner and primary group, respectively. Object owners are always granted full control of the security descriptor, as they are granted the access rights `RIGHT_WRITE_DAC` (WriteDacl) and `RIGHT_READ_CONTROL` (ReadControl) implicitly.

#### SACL and DACL Fields

In Windows, `SACL` (`System access control list`) and `DACL` (`Discretionary access control lists`) are the two types of `access control lists` (`ACLs`), each consisting of a `header` and zero or more `access control entries` (`ACEs`). (Throughout security literature, when the term `ACL` is used, it usually refers to `DACL`, especially for Windows systems.)

A [SACL](https://learn.microsoft.com/en-gb/windows/win32/ad/retrieving-an-objectampaposs-sacl) contains `ACEs` that dictate the types of access attempts that generate audit records in the `security event log` of a domain controller; therefore, a `SACL` allows administrators to log access attempts to `securable objects`. There are two types of `ACEs` within a `SACL`, `system audit` `ACEs` and `system audit-object` `ACEs`.

While a `DACL` holds `ACEs` that dictate what principals have control rights over a specific object. Internally within Windows, a `DACL` consists of an [ACL](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-acl) followed by an ordered list of zero or more `ACEs` (the same applies to `SACLs`). Below is the struct definition of an `ACL` (recognizing these struct definitions will help us later on when viewing a `security descriptor` from the kernel's point of view):

```cpp
typedef struct _ACL {
  BYTE AclRevision;
  BYTE Sbz1;
  WORD AclSize;
  WORD AceCount;
  WORD Sbz2;
} ACL;
```

#### Generic and Object-specific ACEs

An ACE contains a set of user rights and a SID that identifies a principal for whom the rights are allowed, denied, or audited

```cpp
typedef struct _ACE_HEADER {
  BYTE AceType;
  BYTE AceFlags;
  WORD AceSize;
} ACE_HEADER;
```

![](https://i.imgur.com/zG8oMxv.png)

In a DACL, there can be nine types of ACEs, each having the struct `ACE_HEADER` as a member, in addition to the [Mask](https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask) member (which is of type [ACCESS\_MASK](https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask) and defines the standard, specific, and generic rights) and `SidStart` (which holds the first 32 bits of the trustee's `SID`):

* [Access Allowed](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace)
* [Access Denied](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_ace)
* [Access Allowed Object](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_object_ace)
* [Access Denied Object](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_object_ace)
* [Access Allowed Callback](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_callback_ace)
* [Access Denied Callback](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_callback_ace)
* [Access Allowed Object Callback](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_callback_object_ace)
* [Conditional Claims](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-addconditionalace)

but the most important are the following

| ACE                                                                                                                          | Implication                                                                                                                                                                                                                                                                                                                               |
| ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [ACCESS\_ALLOWED\_ACE](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace)                | `Allows` a particular security principal (user or group) to access an `Active Directory object`, such as a user account or group. An `Access Allowed ACE` specifies which permissions the security principal can perform on the object, such as read, write, or modify.                                                                   |
| [ACCESS\_ALLOWED\_OBJECT\_ACE](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_object_ace) | A specific type of `Access Allowed ACE` that is applied to an object and `grants access` to the object itself and any child objects it contains. An `Access Allowed Object ACE` can grant a security principal the necessary permissions to access an object and its child objects without applying separate `ACEs` to each child object. |
| [ACCESS\_DENIED\_ACE](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_ace)                  | `Denies` a particular security principal access to an `Active Directory object`, such as a user account or group. An `Access Denied ACE` specifies which permissions the security principal is not allowed to perform on the object, such as read, write, or modify.                                                                      |
| [ACCESS\_DENIED\_OBJECT\_ACE](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_object_ace)   | A specific type of `Access Denied ACE` that is applied to an object and `restricts` access to the object itself and any child objects it contains. An `Access Denied Object ACE` prevents a security principal from accessing an object and its child objects without having to apply separate `ACEs` to each child object.               |

Some ACEs include the keyword `Object`, these are [object-specific ACEs](https://learn.microsoft.com/en-us/windows/win32/secauthz/object-specific-aces) used only within Active Directory. In addition to the members of generic ACEs structure, object-specific ACEs contain the members:

* `ObjectType`: A `GUID` containing a type of child object, a property set or property, an extended right, or a validated write
* `InheritedObjectType`: Specifies the type of child object that can inherit the ACE
* `Flags`: Indicates whether the members `ObjectType` and `InheritedObjectType` are present via a set of bit flags

#### Interpret Access Masks

We mentioned that all ACE data structures (such as [ACCESS\_ALLOWED\_ACE](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace)) contain the `Mask` member, which is of type `ACCESS_MASK`: a 32-bit value that specifies the allowed or denied rights to manipulate an object

![](https://i.imgur.com/gj1uH4i.png)

How do we interpret access masks and their bits?

* Generic access rights bits

| Display Name     | Common Name                  | Hexadecimal Value | Interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------- | ---------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GenericAll`     | `GA`/`RIGHT_GENERIC_ALL`     | `0x10000000`      | Allows creating or deleting child objects, deleting a subtree, reading and writing properties, examining child objects and the object itself, adding and removing the object from the directory, and reading or writing with an `extended right`. This is equivalent to the `object-specific` access rights bits (`DE` \| `RC` \| `WD` \| `WO` \| `CC` \| `DC` \| `DT` \| `RP` \| `WP` \| `LC` \| `LO` \| `CR` \| `VW`) for AD objects.                                         |
| `GenericExecute` | `GX`/`RIGHT_GENERIC_EXECUTE` | `0x20000000`      | Allows reading permissions on and listing the contents of a container object. This is equivalent to the `object-specific` access rights bits (`RC` \| `LC`) for AD objects.                                                                                                                                                                                                                                                                                                     |
| `GenericWrite`   | `GW`/`RIGHT_GENERIC_WRITE`   | `0x40000000`      | Allows reading permissions on this object, writing all the properties on this object, and performing all validated writes to this object. This is equivalent to the `object-specific` access rights bits (`RC` \| `WP` \| `VW`) for AD objects.                                                                                                                                                                                                                                 |
| `GenericRead`    | `GR`/`RIGHT_GENERIC_READ`    | `0x80000000`      | Allows reading permissions on this object, reading all the properties on this object, listing this object name when the parent container is listed, and listing the object's contents if it is a [container](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/b645c125-a7da-4097-84a1-2fa7cea07714#gt_c3143e71-2ada-417e-83f4-3ef10eff2c56). This is equivalent to the `object-specific` access rights bits (`RC` \| `LC` \| `RP` \| `LO`) for AD objects. |

* Standard Access Rights Bits

| Display Name  | Common Name               | Hexadecimal Value | Interpretation                                                                                                                                                        |
| ------------- | ------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WriteDacl`   | `WD`/`RIGHT_WRITE_DAC`    | `0x00040000`      | Allows modifying the object's `security descriptor`'s `discretionary access-control list` (`DACL`).                                                                   |
| `WriteOwner`  | `WO`/`RIGHT_WRITE_OWNER`  | `0x00080000`      | Allows modifying the object's `security descriptor`'s `owner`. A user can only take ownership of an object but cannot transfer ownership of an object to other users. |
| `ReadControl` | `RC`/`RIGHT_READ_CONTROL` | `0x00020000`      | Allows reading the data from the object's `security descriptor`, however, this does not include the data of the `SACL`.                                               |
| `Delete`      | `DE`/`RIGHT_DELETE`       | `0x00010000`      | Allows deleting the object.                                                                                                                                           |

* Object-specific Access Rights Bits

| Common Name                             | Hexadecimal Value | Interpretation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| --------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `CR`/`RIGHT_DS_CONTROL_ACCESS`          | `0x0000100`       | Allows performing an operation controlled by a [control access right](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/b645c125-a7da-4097-84a1-2fa7cea07714#gt_42f6c9e0-a2b3-4bc3-9b87-fdb902e5505e). The `ObjectType` member of an `ACE` can contain a `GUID` that identifies the `control access right`. If `ObjectType` does not contain a `GUID`, the `ACE` controls the right to perform all `control access right` controlled operations associated with the object. Also referred to as `AllExtendedRights`, especially when `ObjectType` does not contain a `GUID`. |
| `WP`/`RIGHT_DS_WRITE_PROPERTY`          | `0x00000020`      | Allows writing properties of the object. The `ObjectType` member of an `ACE` can contain a `GUID` that identifies a property set or an attribute. If `ObjectType` does not contain a `GUID`, the `ACE` controls the right to write `all` object's attributes.                                                                                                                                                                                                                                                                                                                                    |
| `VW`/`RIGHT_DS_WRITE_PROPERTY_EXTENDED` | `0x00000008`      | Allows performing an operation controlled by a [validated write](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/20504d60-43ec-458f-bc7a-754eb64446df) `access right`. The `ObjectType` member of an `ACE` can contain a `GUID` that identifies the `validated write`. If `ObjectType` does not contain a `GUID`, the `ACE` controls the rights to perform all `validated write` operations associated with the object. Also referred to as `Self`.                                                                                                                        |

* Extended (Object-specific) Access Rights

| Display Name                                                                                                                   | Common Name                      | Rights-GUID Value                      | Interpretation                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Reset Password](https://learn.microsoft.com/en-gb/windows/win32/adschema/r-user-force-change-password)                        | `User-Force-Change-Password`     | `00299570-246d-11d0-a768-00aa006e0529` | Allows a user's account password to be reset without knowing the old one. This is in contrast to [User-Change-Password](https://learn.microsoft.com/en-gb/windows/win32/adschema/r-user-change-password), which does require knowing the old password. |
| [Replicating Directory Changes](https://learn.microsoft.com/en-gb/windows/win32/adschema/r-ds-replication-get-changes)         | `DS-Replication-Get-Changes`     | `1131f6aa-9c07-11d1-f79f-00c04fc2dcd2` | Required to replicate changes from a given `NC` (`Naming Context`). To perform a `DCSync` attack, this extended right and `DS-Replication-Get-Changes-All` are required.                                                                               |
| [Replicating Directory Changes All](https://learn.microsoft.com/en-gb/windows/win32/adschema/r-ds-replication-get-changes-all) | `DS-Replication-Get-Changes-All` | `1131f6ad-9c07-11d1-f79f-00c04fc2dcd2` | Allows the replication of secret domain data. To perform a `DCSync` attack, this extended right and `DS-Replication-Get-Changes` are required.                                                                                                         |

* Validated Writes

| Display Name                                                                                                          | Common Name       | Rights-GUID Value                      | Interpretation                                                                          |
| --------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------------------------------- | --------------------------------------------------------------------------------------- |
| [Add/Remove self as member](https://learn.microsoft.com/en-gb/windows/win32/adschema/r-self-membership)               | `Self-Membership` | `bf9679c0-0de6-11d0-a285-00aa003049e2` | Allows editing the `member` attribute, therefore enabling setting membership of groups. |
| [Validated write to service principal name](https://learn.microsoft.com/en-gb/windows/win32/adschema/r-validated-spn) | `Validated-SPN`   | `f3a64788-5306-11d1-a9c5-0000f80367c1` | Allows editing the `Service Principal Name` (`SPN`) attribute.                          |
