REGISTRY_DACL

Use REGISTRY_DACL to verify the discretionary access control list (DACL) permissions on a registry key. The check compares the key's access control entries (ACEs) against the entries you define inline, without requiring a separate <registry_acl> block. This makes it a self-contained replacement for the older REGISTRY_PERMISSIONS check type.

Note: This check requires remote registry access on the target Windows system.

Usage

<custom_item>

type: REGISTRY_DACL

description: ["description"]

reg_key: ["registry key path"]

dacl: ["principal"] || ["right"] || ["scope"]

dacl: ["principal"] || ["right"] || ["scope"]

(optional) dacl: ["principal"] || ["right"] || ["scope"] || ["inheritance"]

(optional) check_type: [CHECK_EQUAL|CHECK_SUBSET|CHECK_SUBSET_USER|CHECK_SUPERSET]

(optional) acl_option: [CAN_BE_NULL]

</custom_item>

The reg_key field uses the standard hive abbreviations:

HKLM\... - HKEY_LOCAL_MACHINE

HKCU\... - HKEY_CURRENT_USER

HKU\... - HKEY_USERS

HKCR\... - HKEY_CLASSES_ROOT

Each dacl line defines one access control entry (ACE). The fields are separated by the || operator, in the order:

"principal" || "right" || "scope" [|| "inheritance"]

The following describes each segment of a dacl line:

  • principal — The user or group name, or a raw SID string (for example Administrators, SYSTEM, Authenticated Users, Users, CREATOR OWNER, ALL APPLICATION PACKAGES). Principal names are compared case-insensitively.
    • To assign multiple granular rights to one principal, use multiple dacl lines for that principal. The rights are OR'd together.
  • right — A single registry permission. Supported values: full control, read, query value, set value, create subkey, enumerate subkeys, notify, create link, delete, write dac, write owner, read control.
  • scope — Which keys the ACE applies to. Supported values: this key only, this key and subkeys, subkeys only.
  • inheritance — Optional fourth segment that controls how the ACE is matched against the system's inheritance flags. Supported values: not inherited (default), inherited, not used.

Additional field notes:

  • Use reg_key to specify the full registry key path with the standard hive abbreviation (for example, HKLM\Software).
  • check_type — Determines how the policy ACL is compared against the system ACL. Defaults to CHECK_EQUAL when omitted.
  • CHECK_EQUAL — Requires an exact match.
  • CHECK_SUBSET — Requires the policy ACEs to be a subset of the system ACEs.
  • CHECK_SUBSET_USER — Same as CHECK_SUBSET, but ignores principals present on the system that are not listed in the policy.
  • CHECK_SUPERSET - Requires the system rights to be greater than or equal to the policy rights.
  • acl_option — Set to CAN_BE_NULL to pass the check if the registry key does not exist.

Examples

Verify a subset of permissions on HKLM\Security:

<custom_item>

type: REGISTRY_DACL

description: "HKLM\Security - default permissions"

reg_key: "HKLM\Security"

dacl: "Administrators" || "read control" || "this key and subkeys"

dacl: "Administrators" || "write dac" || "this key and subkeys"

dacl: "SYSTEM" || "full control" || "this key and subkeys"

check_type: CHECK_SUBSET

</custom_item>

Specify multiple granular rights for a single principal:

<custom_item>

type: REGISTRY_DACL

description: "HKLM\Software - Users have read-only access"

reg_key: "HKLM\Software"

dacl: "Users" || "enumerate subkeys" || "this key and subkeys"

dacl: "Users" || "notify" || "this key and subkeys"

dacl: "Users" || "query value" || "this key and subkeys"

dacl: "Users" || "read control" || "this key and subkeys"

dacl: "Administrators" || "full control" || "this key and subkeys"

dacl: "SYSTEM" || "full control" || "this key and subkeys"

dacl: "CREATOR OWNER" || "full control" || "this key and subkeys"

check_type: CHECK_SUBSET_USER

</custom_item>

Match only non-inherited ACEs using the optional inheritance segment:

<custom_item>

type: REGISTRY_DACL

description: "Verify non-inherited permissions on HKLM\System"

reg_key: "HKLM\System"

dacl: "Administrators" || "full control" || "this key and subkeys" || "not inherited"

dacl: "SYSTEM" || "full control" || "this key and subkeys" || "not inherited"

check_type: CHECK_SUBSET

</custom_item>

Pass when an optional key may not be present:

<custom_item>

type: REGISTRY_DACL

description: "SNMP Parameters - check if exists"

reg_key: "HKLM\System\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers"

dacl: "Administrators" || "full control" || "this key and subkeys"

dacl: "SYSTEM" || "full control" || "this key and subkeys"

acl_option: CAN_BE_NULL

check_type: CHECK_SUBSET

</custom_item>

Comparison with the legacy REGISTRY_PERMISSIONS style

The older REGISTRY_PERMISSIONS check requires a separate <registry_acl> block referenced by value_data:

<registry_acl:"HKLM_SECURITY">

  <user:"Administrators">

    acl_inheritance : "not inherited"

    acl_apply       : "this key and subkeys"

    acl_allow       : 'read control' | 'write dac'

  </user>

  <user:"SYSTEM">

    acl_inheritance : "not inherited"

    acl_apply       : "this key and subkeys"

    acl_allow       : 'full control'

  </user>

</registry_acl>

 

<custom_item>

type: REGISTRY_PERMISSIONS

description: "HKEY_LOCAL_MACHINE\Security"

value_type: REG_ACL

value_data: "HKLM_SECURITY"

reg_key: "HKLM\Security"

check_type: CHECK_SUBSET

</custom_item>

The equivalent self-contained REGISTRY_DACL check:

<custom_item>

type: REGISTRY_DACL

description: "HKEY_LOCAL_MACHINE\Security"

reg_key: "HKLM\Security"

dacl: "Administrators" || "read control" || "this key and subkeys"

dacl: "Administrators" || "write dac" || "this key and subkeys"

dacl: "SYSTEM" || "full control" || "this key and subkeys"

check_type: CHECK_SUBSET

</custom_item>