The Active Directory Permissions Analysis Challenge
Analyzing permissions in Active Directory is a quite difficult task for Active Directory administrators.
First, because the Active Directory delegation capabilities are extremely powerful and could lead to highly complex hierarchy which is then hard to check.
Second, because the built-in tools are limited: The permissions are displayed in the properties of each object, the effective permissions for a user on an object can be calculated but the usage is limited in large environment and provide approximated and sometimes inaccurate results (See Microsoft KB 933071). Other alternatives will also be describe in this post.
Third, because the company may not have a defined delegation model, or may have an old one defined at the forest or domain creation. In a perfect world, every Active Directory "should" have a defined (and documented) delegation model which "should" evolve as the Enterprise evolves (Teams reorganizations, Companies acquisitions, Partnerships...). In the same perfect world, Active Directory administrators should be able to check if the current delegations in Active Directory are in accordance with the defined delegation model, and modify either part accordingly to the desired state.
Last, because this task is a shared responsibility of both the Active Directory service administrators (for the top-level delegations) and Active Directory data administrators (See Microsoft Best Practices for Active Directory Delegation)
Active Directory objects, like all other securable objects, have a Security Descriptor which answer to different questions:
- Who is the owner
- Who can access the object in what way
- What type of access is audited
- How Access Control Information is inherited from object's container (object's parent object)
Each access permission or audit is defined in an Access Control Entry (ACE), all ACEs of the object form a list known as Access Control List (ACL). Permissions and Audit have separate ACL, a Discretionary Access Control List (DACL) identifying users/groups who are allowed or denied access and a System Access Control (SACL) controlling how access is audited.
An ACE can be of two different kinds:
- Generic ACE:
- 3 types: Access-denied and Access-allowed (DACL), System-Audit (SACL)
- applies to en entire object
- inheritance can only distinguish containers and non-containers
- Object-specific ACE (applies only to Active Directory Objects)::
- 3 types:
- Access-denied, object-specific: deny access to a property or property set, limit inheritance to a type of child object
- Access-allowed, object-specific: allow access to a property or property set, limit inheritance to a type of child object
- System-audit, object-specific: log access to a property or property set, limit inheritance to a type of child object
- Applies to entire object, individual property or property set
- Offers greater control on inheritance
- 3 types:
How access is evaluated ?
The ACEs in the DACL are ordered in a specific order, explicit ACEs are placed before inherited ACEs and access-denied ACEs before access-allowed ACEs. The System evaluate the access by comparing Security Identifiers (SID) in the client access token with SIDs in each ACE, one by one from the top down.
The DACL ACEs evaluation stops when the system founds either one of the following matching ACE or:
- Access-denied ACE for a requested access right to one trustee listed in client token
- Access-allowed ACE for all requested access rights to trustees listed in client token
- All ACEs have been checked => access is denied
With this in mind it is easy to figure out that analyzing true effective permissions is more than just extract ACEs.
The first step is to extract these permissions from Active Directory:
Active Directory permissions analysis requires to be able to extract every ACL of every Active Directory object in a format that can be queried. This can be done in the live environment using tools like checkdsacls which can dump the ACEs of every object in an excel file. It is also possible the extract information from the Active Directory database file. As described in Christoffer Andersson’s (Microsoft MVP) blog, and David Gregory’s (Microsoft PFE) blog, the Active Directory ntds.dit is made of tables with the three main ones:
- The Data Table containing all objects and phantom objects of all partitions currently instantiated on the Domain Controller (Writable or Global Catalog naming contexts)
- The Security Descriptor (SD) Table containing Security Descriptors of all Active Directory objects (stored as single-instance meaning all objects in the Data Table with the same security descriptor are all pointing to the same line on the SD Table)
- The Link Table referencing all linked attributes (like members/memberof)
These tables can be dumped in a MongoDB database to be then requested for permissions (and other security settings) analysis in a much more powerful format than excel sheet. Working on a database is also a great benefit in terms of performance when you have to deal with 100000 ACEs or more in Active Directory. Another benefit of dumping Active Directory tables in a database is that you have more than Active Directory permissions, you have all the information stored in the database. With this approach, you can do much more than analyzing Active Directory permissions in terms of security audit. The dumping of the database in MongoDB is the purpose of the BTA Tool (Note: You can even dump the datatable on a live environment in a text file with the dbdump feature of ldp)
Let’s have a look at a simple user account named bj7 and how it looks like in the Data Table:
DNT is the Distinguished Name Tag, the unique primary key of the object.
PDNT (Parent Distinguished Name Tag) points to the parent of the object (which means that if I query the datatable for the object whose DNT is 4070, I will get the object representing the organizational Unit OU7).
NCDNT points to the partition (naming context) containing the object (which means that if I query the datatable for the object whose DNT is 1788, I will get the object representing the head of the domain partition).
nTSecurityDescriptor points to the Security Descriptor of the object (the user bj7) in the SD Table.
Once decoded, you can display the same information in the SD Table than in the Windows Console. Here is an example with my user bj7 with the following permissions entries:
The ACL in the SD Table is the same as the one extracted with ldp.exe in the live environment, example with these two ACEs:
The second step is to analyze the extracted ACEs to get the effective permissions:
In the first option, using Checkdsacls to dump permissions in an Excel File, you need to create your own script based on this particular input format.
With the second option, working with the SD Table, once we have all Security Descriptors in our mongodb table, decoded the valuable information, we can then easily elaborate simple and complex scripts based on this easy-to-use data format. As an example, a script can process the entire ACL on an object and provide the effective permission of each trustee: get all the ACEs for the trustee or a group for which the trustee is a member (can depend on the type and starting location of the client access), and simulate resultant ACEs processing using the Windows Access Control logic described earlier. Valuable reports can then be built from database data extraction, for example:
- Who can create user accounts on which location
- Who can reset which user's password
- Who can modify which Security group members
In the next post, I will describe one of the various possible extractions in the SD Table, the processing to find effective permissions, and the valuable information it gives to the Active Directory administrator.