DACLs Enumeration
There are two essential ACE concepts to comprehend before we start enumerating and attacking DACLs, Access Masks and Access Rights.
Access Masks and Access Rights
In the previous section, we mentioned that all ACE data structures (such as ACCESS_ALLOWED_ACE) contain the Mask member, which is of type ACCESS_MASK. An Access Mask is a 32-bit value that specifies the allowed or denied rights to manipulate an object. The specific format that access masks follow is shown below:
For AD objects, the access mask contains a combination of the below values (represented in big-endian format), noting that X indicates bits that are ignored in AD DACLs:
Access Mask Bits Interpretation
Understanding how the various access mask bits are interpreted is crucial for us, as that will facilitate the exploitation of abusable DACLs when we enumerate them. The following lists contain the various types of access rights we may encounter when enumerating DACLs:
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 |
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. 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. 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 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. |
Now that we understand how some access mask bits are interpreted let us know about specific abusable extended and validated writes access rights.
Extended (Object-specific) Access Rights
We will abuse three out of the 56 extended access rights in this mini-module:
| Display Name | Common Name | Rights-GUID Value | Interpretation |
|---|---|---|---|
| Reset 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, which does require knowing the old password. |
| Replicating Directory 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 | 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
Two out of the five validated writes can be abused:
| Display Name | Common Name | Rights-GUID Value | Interpretation |
|---|---|---|---|
| Add/Remove self as member | Self-Membership |
bf9679c0-0de6-11d0-a285-00aa003049e2 |
Allows editing the member attribute, therefore enabling setting membership of groups. |
| Validated write to service principal name | Validated-SPN |
f3a64788-5306-11d1-a9c5-0000f80367c1 |
Allows editing the Service Principal Name (SPN) attribute. |
Enumerating DACLs
Some automated tools can be used to inspect/enumerate an object's DACL to find out what access rights other principals have over it.
On Windows systems, Get-DomainObjectAcl and Add-DomainObjectAcl from PowerSploit's PowerView can be used, as well as Get-Acl and Set-Acl functions from the built-in PowerShell Cmdlets.
On UNIX-like systems, impacket's dacledit.py can be used for that purpose. At the time of writing, pull request #1291 offering that tool is still being reviewed and in active development. We can get dacledit.py directly from the ShutdownRepo fork while the branch gets merged into impacket's main branch.
Installing dacledit.py
To install dacledit.py, we will clone the ShutdownRepo impacket's branch, create a Python virtual environment (to avoid conflict between the original Impacket installation and this branch) and install the forked impacket repository:
Clone Forked ShutdownRepo Impacket Repository
$ git clone https://github.com/ShutdownRepo/impacket -b dacledit
Create and Activate the Python Virtual Environment
$ cd impacket
$ pwd
$ python3 -m venv .dacledit
$ source .dacledit/bin/activate
Install ShutdownRepo's Impacket Fork
$ python3 -m pip install .
Processing /home/plaintext/htb/modules/dacl/shutdownRepo/impacket
Collecting chardet
Downloading chardet-5.1.0-py3-none-any.whl (199 kB)
|████████████████████████████████| 199 kB 1.7 MB/s
Collecting flask>=1.0
Using cached Flask-2.3.2-py3-none-any.whl (96 kB)
<SNIP>
Executing dacledit.py
$ python3 examples/dacledit.py --help
Impacket v0.9.25.dev1+20221216.150032.204c5b6b - Copyright 2021 SecureAuth Corporation
usage: dacledit.py [-h] [-use-ldaps] [-ts] [-debug] [-hashes LMHASH:NTHASH]
[-no-pass] [-k] [-aesKey hex key] [-dc-ip ip address]
[-principal NAME] [-principal-sid SID] [-principal-dn DN]
[-target NAME] [-target-sid SID] [-target-dn DN]
[-action [{read,write,remove,backup,restore}]]
[-file FILENAME] [-ace-type [{allowed,denied}]]
[-rights [{FullControl,ResetPassword,WriteMembers,DCSync}]]
[-rights-guid RIGHTS_GUID] [-inheritance]
identity
Python editor for a principal's DACL.
positional arguments:
identity domain.local/username[:password]
optional arguments:
-h, --help show this help message and exit
-use-ldaps Use LDAPS instead of LDAP
-ts Adds timestamp to every logging output
-debug Turn DEBUG output ON
authentication & connection:
-hashes LMHASH:NTHASH
NTLM hashes, format is LMHASH:NTHASH
-no-pass don't ask for password (useful for -k)
-k Use Kerberos authentication. Grabs credentials from
ccache file (KRB5CCNAME) based on target parameters.
If valid credentials cannot be found, it will use the
ones specified in the command line
-aesKey hex key AES key to use for Kerberos Authentication (128 or 256
bits)
-dc-ip ip address IP Address of the domain controller or KDC (Key
Distribution Center) for Kerberos. If omitted it will
use the domain part (FQDN) specified in the identity
parameter
principal:
Object, controlled by the attacker, to reference in the ACE to create or
to filter when printing a DACL
-principal NAME sAMAccountName
-principal-sid SID Security IDentifier
-principal-dn DN Distinguished Name
target:
Principal object to read/edit the DACL of
-target NAME sAMAccountName
-target-sid SID Security IDentifier
-target-dn DN Distinguished Name
dacl editor:
-action [{read,write,remove,backup,restore}]
Action to operate on the DACL
-file FILENAME Filename/path (optional for -action backup, required
for -restore))
-ace-type [{allowed,denied}]
The ACE Type (access allowed or denied) that must be
added or removed (default: allowed)
-rights [{FullControl,ResetPassword,WriteMembers,DCSync}]
Rights to write/remove in the target DACL (default:
FullControl)
-rights-guid RIGHTS_GUID
Manual GUID representing the right to write/remove
-inheritance Enable the inheritance in the ACE flag with
CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE. Useful
when target is a Container or an OU, ACE will be
inherited by objects within the container/OU (except
objects with adminCount=1)
dacledit.py has the following command-line arguments:
-actiondefines the operation to conduct. In the below examples, it must be set toread. If the argument is not set, it defaults toread. The other actions arewrite,remove,backup, andrestore.-target,-target-sid, or-target-dn, respectively, define the sAMAccountName, Security IDentifier, or Distinguished Name of the object from which the DACL must be retrieved and parsed.-principal,-principal-sid, or-principal-dn, respectively, define thesAMAccountName,Security Identifier, orDistinguished Nameof the principal to look for and filter in the parsed DACL. This argument is handy to quickly determine what a particular principal can or cannot do on the target object.
In the following example, we can read the DACL for htb-student:
Reading the DACL of a User
$ python3 examples/dacledit.py -target htb-student -dc-ip 10.129.205.81 inlanefreight.local/htb-student:'HTB_@cademy_stdnt!'
Impacket v0.9.25.dev1+20221216.150032.204c5b6b - Copyright 2021 SecureAuth Corporation
[*] Parsing DACL
[*] Printing parsed DACL
[*] ACE[0] info
[*] ACE Type : ACCESS_ALLOWED_OBJECT_ACE
[*] ACE flags : None
[*] Access mask : ReadProperty
[*] Flags : ACE_OBJECT_TYPE_PRESENT
[*] Object type (GUID) : User-Account-Restrictions (4c164200-20c0-11d0-a768-00aa006e0529)
[*] Trustee (SID) : RAS and IAS Servers (S-1-5-21-1267651629-1192007096-1618970724-553)
[*] ACE[1] info
[*] ACE Type : ACCESS_ALLOWED_OBJECT_ACE
[*] ACE flags : None
[*] Access mask : ReadProperty
[*] Flags : ACE_OBJECT_TYPE_PRESENT
[*] Object type (GUID) : User-Logon (5f202010-79a5-11d0-9020-00c04fc2d4cf)
[*] Trustee (SID) : RAS and IAS Servers (S-1-5-21-1267651629-1192007096-1618970724-553)
[*] ACE[2] info
[*] ACE Type : ACCESS_ALLOWED_OBJECT_ACE
[*] ACE flags : None
[*] Access mask : ReadProperty
[*] Flags : ACE_OBJECT_TYPE_PRESENT
[*] Object type (GUID) : Membership (bc0ac240-79a9-11d0-9020-00c04fc2d4cf)
[*] Trustee (SID) : RAS and IAS Servers (S-1-5-21-1267651629-1192007096-1618970724-553)
[*] ACE[3] info
[*] ACE Type : ACCESS_ALLOWED_OBJECT_ACE
[*] ACE flags : None
[*] Access mask : ReadProperty
[*] Flags : ACE_OBJECT_TYPE_PRESENT
[*] Object type (GUID) : RAS-Information (037088f8-0ae1-11d2-b422-00a0c968f939)
[*] Trustee (SID) : RAS and IAS Servers (S-1-5-21-1267651629-1192007096-1618970724-553)
...
Note: Make sure to use the virtual environment when executing dacledit.py.
Auditing DACLs with BloodHound
While manually enumerating an object's DACL can be useful in specific cases, it does not simply allow auditing all access rights in an Active Directory domain due to their enormous number.
BloodHound, one of the most famous tools used for Active Directory auditing, gathers all DACLs and correlates them to allow the analysis of rights in graph models, making finding abusable access rights easy. In the screenshot below, some edges (highlighted in red) show abusable access rights/privileges:
BloodHound makes auditing easier by separating control rights into two categories:
-
Inbound Control Rights: This is similar to inspecting an object'sDACL. -
Outbound Control Rights: An aggregation and correlation of all references to the object'sSIDin allDACLsacross the domain.
Review the module BloodHound for Active Directory to learn more about BloodHound.
DACLs Abuses Mindmap
The following mindmap from DACL abuse - The Hacker Recipes shows what abuses can be carried out depending on a controlled principal's access rights over a specific type of object. The below mindmap details all abuse scenarios that we will cover in this module and the other DACL Attacks mini-modules:
Coming Next
We provided some examples to perform the enumeration or auditing of these access rights from Linux with dacledit.py and Windows with PowerView. However, always remember that understanding how to use BloodHound to identify these access rights/privileges is crucial because the number of access rights to audit manually would be too large.
In the next section, we will learn about targeted Kerberoasting and how to carry out the attack from Linux and Windows.



