ACL Abuse

ACL BloodHound Abuse Hierarchy

Some AD object security permissions abusable with PowerView/SharpView:

  • ForceChangePassword abused with Set-DomainUserPassword.

  • AddMembers abused with Add-DomainGroupMember.

  • GenericAll abused with Set-DomainUserPassword or Add-DomainGroupMember.

  • GenericWrite abused with Set-DomainObject.

  • WriteOwner abused with Set-DomainObjectOwner.

  • WriteDACL abused with Add-DomainObjectACL.

  • AllExtendedRights abused with Set-DomainUserPassword or Add-DomainGroupMember.

SDDL (Security Descriptor Definition Language)

At the lowest level, the Security Descriptor Definition Language is used in the nTSecurityDescriptor attribute (and on registry keys and NTFS files) to define the ACL. Fortunately, one does not need to know this level of detail in normal conditions.

But advanced administrators may want to write scripts or code that can correctly construct SDDL strings. Also the security templates (located at %systemroot%\security\templates) use SDDL if you manually edit them with a text editor instead of the MMC interface.manually editing these templates turns out to be the most effective way to manipulate them. It is most likely that you will simply need to be able to read a SDDL string.

Format of nTSecurityDescriptor string

O:owner_sidG:group_sidD:dacl_flags(string_ace1)(string_ace2)…
(string_acen)S:sacl_flags(string_ace1)(string_ace2)…(string_acen)

Each nTSecurityDescriptor SDDL string is composed of 5 primary parts which correspond to the Header, DACL (D:), SACL (S:), primary group (G:)and owner (O:). Each of these parts is designated with the prefix noted in parenthesis. The header contains some record keeping information, along with 2 flags that designate whether the object is blocking inheritance for the SACL and DACL. The contents of both the primary group and owner parts are simply a single SID. The contents of both the SACL and DACL parts are a string with no fixed length. ACEs make up the contents of these strings. ACEs are enclosed within parenthesis, and there are 6 fields in each ACE. These 6 fields are separated by a semicolon delimiter. The fields are ACE type (allow/deny/audit), ACE flags (inheritance and audit settings), Permissions (list of incremental permissions), ObjectType (GUID), Inherited Object Type (GUID), and Trustee (SID).

ACE Type

The ACE type designates whether the trustee is allowed, denied or audited.

Value

Description

β€œA”

ACCESS ALLOWED

β€œD”

ACCESS DENIED

β€œOA”

OBJECT ACCESS ALLOWED: ONLY APPLIES TO A SUBSET OF THE OBJECT(S).

β€œOD”

OBJECT ACCESS DENIED: ONLY APPLIES TO A SUBSET OF THE OBJECT(S).

β€œAU”

SYSTEM AUDIT

β€œAL”

SYSTEM ALARM

β€œOU”

OBJECT SYSTEM AUDIT

β€œOL”

OBJECT SYSTEM ALARM

ACE Flags

The ACE flags denote the inheritance options for the ACE, and if it is a SACL, the audit settings.

Value

Description

β€œCI”

CONTAINER INHERIT: Child objects that are containers, such as directories, inherit the ACE as an explicit ACE.

β€œOI”

OBJECT INHERIT: Child objects that are not containers inherit the ACE as an explicit ACE.

β€œNP”

NO PROPAGATE: ONLY IMMEDIATE CHILDREN INHERIT THIS ACE.

β€œIO”

INHERITANCE ONLY: ACE DOESN’T APPLY TO THIS OBJECT, BUT MAY AFFECT CHILDREN VIA INHERITANCE.

β€œID”

ACE IS INHERITED

β€œSA”

SUCCESSFUL ACCESS AUDIT

β€œFA”

FAILED ACCESS AUDIT

Permissions

The Permissions are a list of the incremental permissions given (or denied/audited) to the trustee-these correspond to the permissions discussed earlier and are simply appended together. However, the incremental permissions are not the only permissions available. The table below lists all the permissions.

Value

Description

Hexadecimal Value

Binary Bits from 0

Generic access rights

β€œGA”

GENERIC ALL

0x10000000

Bit 28

β€œGR”

GENERIC READ

0x80000000

Bit 31

β€œGW”

GENERIC WRITE

0x40000000

Bit 30

β€œGX”

GENERIC EXECUTE

0x20000000

Bit 29

Directory service access rights

β€œRC”

Read Permissions

0x20000

Bit 17

β€œSD”

Delete

0x10000

Bit 16

β€œWD”

Modify Permissions

0x40000

Bit 18

β€œWO”

Modify Owner

0x80000

Bit 19

β€œRP”

Read All Properties

0x00000010

Bit 4

β€œWP”

Write All Properties

0x00000020

Bit 5

β€œCC”

Create All Child Objects

0x00000001

Bit 0

β€œDC”

Delete All Child Objects

0x00000002

Bit 1

β€œLC”

List Contents

0x00000004

Bit 2

β€œSW”

All Validated Writes

0x00000008

Bit 3

β€œLO”

List Object

0x00000080

Bit 7

β€œDT”

Delete Subtree

0x00000040

Bit 6

β€œCR”

All Extended Rights

0x00000100

Bit 8

File access rights

β€œFA”

FILE ALL ACCESS

β€œFR”

FILE GENERIC READ

β€œFW”

FILE GENERIC WRITE

β€œFX”

FILE GENERIC EXECUTE

Registry key access rights

β€œKA”

KEY ALL ACCESS

0xF003F

β€œKR”

KEY READ

0x20019

β€œKW”

KEY WRITE

0x20006

β€œKX”

KEY EXECUTE

0x20019

KEY CREATE SUB KEYS

0x0004

KEY ENUMERATE SUB KEYS

0x0008

KEY NOTIFY

0x0010

KEY QUERY VALUE

0x0001

KEY SET VALUE

0x0002

Object Type and Inherited Object Type

The ObjectType is a GUID representing an object class, attribute, attribute set, or extended right. If present it limits the ACE to the object the GUID represents. The Inherited Object Type is a GUID representing an object class. If present it limits inheritance of the ACE to the child entries of only that object class.

Trustee

The Trustee is the SID of the user or group being given access (or denied or audited). Instead of a SID, there are several commonly used acronyms for well-known SIDs. The most common are listed in the table below, but you can review more at https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings:

Value

Description

β€œAO”

Account operators

β€œRU”

Alias to allow previous Windows 2000

β€œAN”

Anonymous logon

β€œAU”

Authenticated users

β€œBA”

Built-in administrators

β€œBG”

Built-in guests

β€œBO”

Backup operators

β€œBU”

Built-in users

β€œCA”

Certificate server administrators

β€œCG”

Creator group

β€œCO”

Creator owner

β€œDA”

Domain administrators

β€œDC”

Domain computers

β€œDD”

Domain controllers

β€œDG”

Domain guests

β€œDU”

Domain users

β€œEA”

Enterprise administrators

β€œED”

Enterprise domain controllers

β€œWD”

Everyone

β€œPA”

Group Policy administrators

β€œIU”

Interactively logged-on user

β€œLA”

Local administrator

β€œLG”

Local guest

β€œLS”

Local service account

β€œSY”

Local system

β€œNU”

Network logon user

β€œNO”

Network configuration operators

β€œNS”

Network service account

β€œPO”

Printer operators

β€œPS”

Personal self

β€œPU”

Power users

β€œRS”

RAS servers group

β€œRD”

Terminal server users

β€œRE”

Replicator

β€œRC”

Restricted code

β€œSA”

Schema administrators

β€œSO”

Server operators

β€œSU”

Service logon user

Let's say that the ACE on object A applies to object B. This grants or denies object B access to object A with the specified access rights.

ACE example in SDDL format:

A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-1-0)
​
AceType:
A = ACCESS_ALLOWED_ACE_TYPE
​
Access rights:
RP = ADS_RIGHT_DS_READ_PROP
WP = ADS_RIGHT_DS_WRITE_PROP
CC = ADS_RIGHT_DS_CREATE_CHILD
DC = ADS_RIGHT_DS_DELETE_CHILD
LC = ADS_RIGHT_ACTRL_DS_LIST
SW = ADS_RIGHT_DS_SELF
RC = READ_CONTROL
WD = WRITE_DAC
WO = WRITE_OWNER
GA = GENERIC_ALL
​
Ace Sid:
S-1-1-0

Hunt for ACLs

ActiveDirectory

Enumerate ACLs which snovvcrash user possesses against j.doe user:

(Get-ACL "AD:$((Get-ADUser j.doe).distinguishedName)").access | ? {$_.IdentityReference -eq "MEGACORP\snovvcrash"}

Enumerate which users possess GenericAll or AllExtendedRights permission against j.doe user:

PS > (Get-ACL "AD:$((Get-ADUser j.doe).distinguishedName)").access | ? {$_.ActiveDirectoryRights -match "GenericAll" -or $_.ActiveDirectoryRights -match "AllExtendedRights"} | select IdentityReference,ActiveDirectoryRights -Unique | ft -W

PowerView analog:

PowerView3 > Get-DomainObjectAcl -Identity j.doe -Domain megacorp.local -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "GenericAll" -or $_.ActiveDirectoryRights -match "AllExtendedRights"} | select SecurityIdentifier | sort -Property SecurityIdentifier -Unique
PowerView3 > ConvertFrom-SID <SECURITY_IDENTIFIER>

Find all users who can DCSync and convert their SIDs to names:

PowerView3 > $dcsync = Get-ObjectACL "DC=megacorp,DC=local" -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "GenericAll" -or $_.ObjectAceType -match "Replication-Get"} | select -ExpandProperty SecurityIdentifier | select -ExpandProperty value
PowerView3 > Convert-SidToName $dcsync

PowerView2

Search for interesting ACLs:

PowerView2 > Invoke-ACLScanner -ResolveGUIDs

Check if the attacker "MEGACORP\sbauer" has GenericWrite permissions on the "jorden" user object:

PowerView2 > Get-ObjectAcl -samAccountName jorden -ResolveGUIDs | ? {$_.ActiveDirectoryRights -like "*GenericWrite*" -and $_.IdentityReference -eq "MEGACORP\sbauer"}
​
InheritedObjectType   : All
ObjectDN              : CN=Jorden Mclean,OU=Athens,OU=Employees,DC=MEGACORP,DC=LOCAL  <== Victim (jorden)
ObjectType            : All
IdentityReference     : MEGACORP\sbauer  <== Attacker (sbauer)
IsInherited           : False
ActiveDirectoryRights : GenericWrite
PropagationFlags      : None
ObjectFlags           : None
InheritanceFlags      : ContainerInherit
InheritanceType       : All
AccessControlType     : Allow
ObjectSID             : S-1-5-21-3167813660-1240564177-918740779-3110

PowerView3

Search for interesting ACLs:

PowerView3 > Find-InterestingDomainAcl -ResolveGUIDs | ? {$_.IdentityReferenceClass -match "user"}

Check if the attacker "MEGACORP\sbauer" (S-1-5-21-3167813660-1240564177-918740779-3102) has GenericWrite permissions on the "jorden" user object:

PowerView3 > Get-DomainObjectAcl -Identity jorden -ResolveGUIDs | ? {$_.ActiveDirectoryRights -like "*GenericWrite*" -and $_.SecurityIdentifier -eq "S-1-5-21-3167813660-1240564177-918740779-3102"}
​
AceType               : AccessAllowed
ObjectDN              : CN=Jorden Mclean,OU=Athens,OU=Employees,DC=MEGACORP,DC=LOCAL
ActiveDirectoryRights : GenericWrite
OpaqueLength          : 0
ObjectSID             : S-1-5-21-3167813660-1240564177-918740779-3110  <== Victim (jorden)
InheritanceFlags      : ContainerInherit
BinaryLength          : 36
IsInherited           : False
IsCallback            : False
PropagationFlags      : None
SecurityIdentifier    : S-1-5-21-3167813660-1240564177-918740779-3102  <== Attacker (sbauer)
AccessMask            : 131112
AuditFlags            : None
AceFlags              : ContainerInherit
AceQualifier          : AccessAllowed

The -ResolveGUIDs switch shows ObjectType and InheritedObjectType properties in a human readable form (not in GUIDs).

PowerView 3.0 does not return IdentityReference property, which makes it less handy for this task (however, you may filter the output by the attacker's SID). To automatically convert SIDs to names we can use the following loop:

PowerView3 > Get-DomainObjectAcl -Identity snovvcrash -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_}

Last updated