index-logo

Windows ACLs

Introduction to Windows ACLs


Introduction


Today, we’ll explore the fundamentals of ACLs in Windows and later demonstrate common attacks that exploit ACL misconfigurations in an Active Directory environment.


Introduction to ACLs in Windows


Access Control Lists (ACLs) are a fundamental part of Windows security, defining who can access or modify system resources such as files, folders, registry keys, and even Active Directory objects. An ACL is a list of access control entries (ACEs), where each entry specifies a user or group and their corresponding permissions.


Windows uses two types of ACLs: Discretionary ACLs (DACLs), which control access to an object, and System ACLs (SACLs), which define auditing rules. Understanding how ACLs work is crucial for managing permissions and securing systems, especially in enterprise environments where Active Directory plays a central role in access management.


Key Components


  • DACL (Discretionary Access Control List): Contains ACEs that grant or deny access permissions to users and groups for an object. It is the primary ACL that determines access rights.


  • SACL (System Access Control List): Used for auditing access to objects, where ACEs specify which types of access should be logged in the Security Event Log. This is invaluable for detecting unauthorized access attempts and troubleshooting access issues.


System Interaction with ACLs and the Session Access Token


When a user logs into a Windows system, the Local Security Authority Subsystem Service (LSASS) generates a session access token. This token contains:


  • The user’s SID (Security Identifier)
  • The SIDs of all groups the user belongs to
  • Any privileges assigned to the user
  • The user's integrity level

Every time the user attempts to access an object (such as a file or registry key), Windows performs an Access Check by comparing the user’s access token against the DACL of the target object.


Understanding Access Control Entries (ACEs)


Before entering the Access Check process, let's quickly delve into Access Control Entries (ACEs). So far, we know that ACEs are the rules that constitute the Discretionary Access Control List (DACL) and System Access Control List (SACL) of each object. Each ACE in the DACL defines the rights and privileges of a user or group over an object, while ACEs in the SACL dictate what access attempts should be logged.


Each Access Control Entry (ACE) consists of four essential elements that define how permissions are applied to an object:


  1. Security Identifier (SID) – Identifies the user, group, or computer the ACE applies to. Essentially, who receives the privileges. Windows resolves SIDs to recognizable names like Administrator or Domain Users.


  2. ACE Type Flag – Specifies whether the ACE grants, denies, or audits access. The main types are:


    • Access Denied ACE → This type of ACE explicitly denies access rights to a specific user or group.


    • Access Allowed ACE → An Access Allowed ACE grants specific permissions to a user or group.


    • System Audit ACE → Unlike the other ACEs, System Audit ACEs do not grant or deny access. Instead, they define which actions should be logged in the Security Event Log. These ACEs reside in the SACL, and Windows generates an event whenever a matching access attempt occurs. System Audit ACEs are critical for compliance, forensic analysis, and intrusion detection.


  3. Inheritance Flags – Define whether and how the ACE applies to child objects (e.g., files in a folder). Some ACEs inherit permissions, while others apply only to the parent.


  4. Access Mask (Permissions) – A 32-bit value specifying the exact rights (read, write, execute, delete, etc.) granted or denied. These masks allow fine-grained control over object access.


Together, these components form the structure of an ACE, determining how Windows enforces security rules on system objects.


How These Components Work Together


When a user attempts to access an object, Windows performs the Access Check process:


  1. Reads the requested object’s DACL to retrieve all relevant ACEs.
  2. It scans the ACEs in the DACL to find entries matching the requesting user's SID or group SIDs.
  3. If an explicit deny ACE is found, access is immediately blocked.
  4. If there are allow ACEs granting the required permissions, access is granted.
  5. If no ACE explicitly allows access, the request is denied by default (implicit deny).

Additionally, if a SACL is defined, Windows logs access attempts based on the auditing rules specified.


This mechanism ensures that access control in Windows is dynamic, granular, and secure, integrating with authentication and privilege management at the kernel level.


The process described above is almost the actual process Windows performs. However, some concepts are missing, so let's introduce the order of ACEs.


Order of ACEs


The order in which Access Control Entries (ACEs) appear in a Discretionary Access Control List (DACL) is crucial, as Windows processes them sequentially during an Access Check. The general order follows these rules in canonical order:


  1. Explicit Deny ACEs – These ACEs immediately block access and take precedence over all others. If a user or group has an explicit deny entry, Windows stops processing and denies access.
  2. Explicit Allow ACEs – If no deny ACE was found, Windows scans for an explicit allow ACE that grants the requested permissions.
  3. Inherited Deny ACEs – If no explicit ACEs apply, Windows processes inherited deny ACEs from parent objects.
  4. Inherited Allow ACEs – Lastly, inherited allow ACEs are evaluated.

Why This Order Matters?


  • Explicit Deny has priority → This ensures that access is blocked before any allow rules are processed.
  • Explicit ACEs take precedence over inherited ones → Permissions explicitly set on an object override those inherited from a parent.

This order provides predictability and security, preventing unauthorized access while allowing administrators to fine-tune access control efficiently.


So, let's recap the Access Check process. Imagine a user wants to write a file to a folder. The process follows these steps:


  1. Read the DACL:
    Windows retrieves the folder's Discretionary Access Control List (DACL), which contains all the ACEs (Access Control Entries) for that folder.


  2. Scan for Matching ACEs:
    The system scans through the ACEs in the DACL to find entries that match the SID of the requesting user, as well as any group SIDs included in the user's access token.


  3. Evaluate Explicit Deny ACEs:
    Since the DACL is processed in a specific order, explicit deny ACEs are evaluated first. If an ACE is found that both matches the user's SID and explicitly denies the WRITE permission (as indicated by its Access Mask), the write request is immediately blocked. This prevents the user from writing to the folder, regardless of any subsequent allow entries.


  4. Evaluate Explicit Allow ACEs:
    If no deny ACE is found that restricts the write operation, Windows then checks the explicit allow ACEs. If an allow ACE granting the WRITE permission is found, the system permits the file write.


  5. Evaluate Inherited ACEs:
    If no explicit ACE grants the necessary permissions, Windows will then evaluate the inherited ACEs, which could have been inherited from a parent object or group the user belongs to. The order of evaluation for inherited ACEs is the same as for explicit ones: first, inherited deny ACEs are checked, and if a deny ACE matches the user's SID and blocks the WRITE permission, the action is immediately denied. If no inherited deny ACE is found, Windows moves on to evaluate inherited allow ACEs. If one is found granting the WRITE permission, the write operation is allowed.


  6. Implicit Deny:
    If no ACE—explicit or inherited—explicitly grants the required WRITE permission, the request is implicitly denied by default. This default behavior ensures that only explicitly permitted actions are allowed.


Additionally, if a SACL (System Access Control List) is defined for the folder, Windows logs the access attempt according to the auditing rules specified, aiding in monitoring and security analysis.


Summary of this process


1. What Are ACLs and ACEs?


Access to resources is managed using Access Control Lists (ACLs), which are composed of individual rules called Access Control Entries (ACEs). Each ACE specifies which users or groups can or cannot perform certain actions on a resource.


2. Denying Access to a Specific Group


Imagine you have a folder named Projects. If you want to prevent a group called Contractors from accessing it, you can set up an ACE that explicitly denies them access. This deny rule is placed before any general allow rules, ensuring that any access attempt by a member of Contractors is blocked.


3. Allowing Access to a Specific Member Within a Restricted Group


Now, suppose Alice, a member of Contractors, needs access because she is the project lead. To override the group restriction, an explicit allow ACE is created specifically for Alice. Since the deny rule for Contractors is inherited by its members, placing Alice’s explicit allow ACE before the inherited deny ACE ensures she gets access, even though her group is generally restricted.



Generic ACEs vs. Object-Specific ACEs


ACEs are the individual rules within an Access Control List (ACL) that define who can or cannot access a resource. Each ACE specifies a user or group (identified by a Security Identifier or SID), details the permissions that are allowed or denied (through an access mask), and establishes how these permissions are passed on to sub-items via inheritance.


There are two main types of ACEs:


  • Generic ACEs: These apply broad, common permissions like Read, Write, Execute, or Full Control to different objects. They make it easy to assign general access without worrying about the specific details of each object. For example, granting "Read" permission on a folder lets a user see its contents without having to define separate rules for each file inside


  • Object-Specific ACEs: These provide more detailed control by allowing permissions on specific parts of an object. For instance, in a shared contact list, an object-specific ACE could allow users to update their own phone number but prevent them from changing their email address. These ACEs include extra settings, like which parts of the object they apply to and how they are inherited, giving administrators more precise control over access.


In summary, while generic ACEs are ideal for straightforward scenarios with uniform rules, object-specific ACEs are designed for complex environments—such as Active Directory—where tailored access control is necessary. Together, ACLs and ACEs ensure that only the appropriate individuals or groups can access sensitive resources, with the flexibility to define permissions down to a very detailed level.


When talking about Generic/Object-Specific ACEs, we refer to the AccessMask value, which defines the permissions that the ACE either grants or denies. The table below outlines the possible AccessMask values and their corresponding bit ranges.


(original table on hacktricks)



Conclusion


Access Control Lists (ACLs) play a crucial role in managing permissions within systems by defining who can access what and how. Each ACL consists of multiple Access Control Entries (ACEs), which specify whether a user or group is granted or denied certain rights.


There are two main types of ACEs: Generic ACEs, which apply broad permissions to objects, and Object-Specific ACEs, which offer finer control over specific attributes. The AccessMask value within an ACE determines the exact permissions, ranging from basic actions like reading and writing to more advanced security modifications.


By structuring ACLs carefully, administrators can enforce granular security policies, ensuring the right level of access while maintaining system integrity. Understanding how ACEs, AccessMask values, and inheritance work is essential for securing resources effectively, whether in file systems, Active Directory, or other access-controlled environments.


In upcoming articles, we will discuss attack techniques to leverage ACL misconfigurations in an Active Directory environment.


References


https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/acls-dacls-sacls-aces.html
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/20233ed8-a6c6-4097-aafa-dd545ed24428
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/d06e5a81-176e-46c6-9cf7-9137aad4455e