Kerberos delegation attack principle S4U2 utilization details

To better prevent the abuse of constraint delegates, see the “S4U” section of the “From Kekeo to Rubeus” article.

A few weeks ago, my colleague Lee Christensen (who helped me with this article and related materials) and I spent some time digging into active Directory’s S4U2Self and S4U2Proxy protocol extensions. Just recently, Benjamin Delpy and Ben Campbell had an interesting public conversation on Twitter about the same subject. As a result of the conversation, Benjamin released a modified Kekeo that made it easier to abuse the S4U misconfiguration. Ben has also posted an excellent article on this topic as I write this, which everyone should read before moving on. Seriously, readers should read Ben’s post first.

 

Lee and I wanted to write about our understanding of the technology and how any misconfiguration could be abused in combat. Some of this will overlap with Ben’s article, but we’ve incorporated a few different aspects that we think can at least add some value. Ben also talked about vulnerability exploitation in Linux, which we won’t cover in this article.

At the heart of the problem is privileged delegation, which allows one user to impersonate another user in the active directory. This delegation (currently) comes in two forms: unconstrained and constrained delegation. If you don’t care about the technical details, skip right to the S4U abuse section.

Unconstrained delegate

Suppose you have a server (or service account) that for some reason needs to impersonate as another user. A common scenario is when a user authenticates to a Web server using Kerberos or other protocols, and the server wants good integration with the SQL back end. The active directory provides two general methods for doing this: constrained and unconstrained delegates.

In Windows 2000, unconstrained delegation was the only option available, and it has since been retained (possibly for reasons of backward compatibility). We’ll cover this type of delegation briefly, because Sean Metcalf has a great article that covers it in depth. In that article Sean said,” When the Kerberos unconstrained delegate is enabled on the server that hosts the service specified in the service principal name referenced in TGS-REq (Step 3), the DC domain controller puts a copy of the user TGT into the service ticket. When a user’s service ticket (TGS) is provided to the server for service access, the server opens the TGS and puts the user’s TGT into LSASS for subsequent use. At this point, the application server can impersonate the user indefinitely!” .

Here’s an official graphical overview of the protocol from Microsoft:

 

 

Tl; Dr: TGT will be stuffed into memory, and an attacker can extract and reuse the TGT in the following situations:

  1. You can attack servers with unconstrained delegate Settings.
  2. You can trick domain users who have not enabled the “accounts are sensitive and cannot delegate” setting (see the “Safeguards” section below) to connect to any service on your computer. Including clicking \SERVER\Share.

This allows an attacker to impersonate that user to any service or computer on the domain! This is obviously a bad situation. By contrast, if unconstrained delegation is not enabled, a plain service ticket without a TGT is submitted, so that an attacker does not gain the additional advantage of scale-out.

How do I determine which machines have unconstrained delegate Settings? This is actually quite simple: search for any machine that has the userAccountControl property, which contains ADS_UF_TRUSTED_FOR_DELEGATION. You can use LDAP filters’ (userAccountControl: 1.2.840.113556.1.4.803: = 524288), This is what PowerView’s get-domaincomputer function does when it passes the -unconstrained flag:

 

Constraints to delegate

Clearly, unconstrained delegation can be quite dangerous in the hands of careless administrators. Microsoft realized this for a long time and released The Constraint Delegate in Windows 2003. This includes a set of Kerberos protocol extensions called S4U2Self and S4U2Proxy. These extensions also support so-called protocol transformations, which we’ll cover in more detail later.

Essentially, a constraint delegate is a way to precisely limit access to certain services for a particular machine or account while impersonating other users. Here’s what a service account with constraint delegate configured looks like in the active directory GUI:

 

The specified “service” is the name of the service principal that accounts are allowed to access when impersonating other users. In the example above is the HOST/PRIMARY testlab. Local. Before we discuss how it works in detail, here’s how the target object looks in PowerView:

 

The field of interest is MSDS – AllowedToDelegateto, but the userAccountControl property of the account has also been modified. In fact, if the userAccountControl value of a computer or user object contains TRUSTED_TO_AUTH_FOR_DELEGATION, Any user with access to this account can emulate the SPN set in MSDS-AllowedtoDelegateto. Ben mentioned is necessary to modify these parameters SeEnableDelegationPrivilege, later I will discuss it more deeply.

But first, let’s take a look at how active directory implements the whole process. If you’re not interested, you can skip to the S4U abuse section of this article.

S4U2Self . S4U2Proxy And protocol conversion

Suppose you have a Web service account that needs to impersonate the user as a specific back-end service account, but you don’t want to turn on unconstrained delegation. Microsoft’s solution is implemented through User Services (S4U) with Kerberos extended Settings. There is extensive documentation on this topic; Lee and I prefer Microsoft’s “Kerberos Protocol Extension: Services for Users and Constrained Delegate Protocols “([MS-SFU]). Here’s what we understand so far. If we get anything wrong, please let us know!

The first extension to implement constraint delegation is the S4U2self extension, which allows a service to request a special forwarding service ticket from itself on behalf of a particular user. This is for use when a user authenticates a service without Using Kerberos, such as in the Web services case we mentioned earlier. When KRB_TGS_REQ is first sent to KDC, it sets the forwardable flag, which requires that the tag returned by TGS be forwardable for use with the S4U2proxy extension. In the unconstrained delegate, TGT is used to identify the USER, but in this case, the S4U extension uses the PA-for-user structure as a new type in the “Padata” pre-authentication data field.

Note that the S4U2self process can be executed by any user and does not require the password of the target user. In addition, the S4U2self process is allowed only if the requesting user has set the TRUSTED_TO_AUTH_FOR_DELEGATION field in their userAccountControl.

Now, the first thing Lee and I thought was that this might be a way to perform Kerberoast attacks on any user we wanted, but unfortunately for us attackers, that’s not the case. Pacs are signed for the source user (not the target user), in this case the request service account, so the generic Kerberoast attack method is out of the question. But we now have a special service ticket that in this case can be forwarded to the target service configured to constrain the delegate.

The second extension is S4U2proxy, which allows the caller (in our case, the service account) to use this forward ticket to request the service ticket from any SPN specified in MSDS-AllowedtoDelegateto, impersonating the user specified in the S4U2self step. KDC checks whether the requested service is in the MSDS-AllowedToDelegateto field of the requested service and issues a ticket when this check passes. In this way, you delegate “constraints” to specific target services.

S4U2self and S4U2proxy:

 

 

This extended setup is what Microsoft calls protocol transformation, which starts with the first Kerberos exchange during the S4u2Self component. This means that services can authenticate users over non-Kerberos protocols and “convert” the authentication to Kerberos, making it easy to interoperate with existing environments.

The abuse of S4U

Reading from the beginning here, if you ask yourself “so what” or skip the previous sections and go straight to this chapter, we can come up with some ways to make the S4U extension work in penetration testing.

The first approach is to enumerate all computers and users using a non-empty MSDS-AllowedToDelegateTO field setting. This can be easily done using PowerView’s get-DomainUser/GET-Domaincomputer function with the -TrustedToAuth flag:

 

Now, remember that a machine or user account with SPN set to MSDS-AllowedToDelegateTo can impersonate any target service SPN they wish to be. Therefore, if you can get access to one of the accounts, you can cheat privileged access to the target SPN. For HOST SPN, a full remote takeover can be implemented. For MSSQLSvc SPN, DBA privileges are available. The CIFS SPN provides complete remote file access. For HTTP SPN it is possible to take over remote network services, while for LDAP it is possible to perform DCSync;) For HTTP or SQL service accounts, even if they do not raise administrator privileges on the target server, it is possible to further abuse by raising privileges to the SYSTEM using Rotten Potato (although I have not tested this myself).

Fortunately, Benjamin recently released a modified Version of Kekeo that makes it easy to execute this type of lateral propagation attack if we know the plaintext password of a particular account. Lee and I envisioned four different scenarios, including S4U, which you might want to abuse. We have tested two of these scenarios reliably in the lab, but failed to test the other two (note below). @gentilkiwi **** contact and tell Lee and me that askTGt.exe accepts a /key: NTLM parameter and a password. This allows us to use an account hash instead of plain text passwords to perform scenarios 3 and 4 below!

Scenario ****1: The user account is configured to restrict delegation and the plaintext password is known

This is the scene Benjamin showed in his tweet. If you can crack the plaintext password of a user account with constraint delegate enabled, you can request the TGT using Kekeo, perform the S4U TGS request, and then access the target service.

 

Enumerate users with MSDS – AllowedtoDelegateto

 

Request a TGT for a user account with constraint delegate enabled

Use s4U. Exe to execute S4U2Proxy

 

Inject S4U ticket to gain access

Also, if you want to execute this attack from a Linux system, please read Ben’s article.

Scene * * * * 2: The agent on the machine is configured as a constraint delegate

If you can get access to a computer account configured to constrain the delegate (rather than the user account), the attack approach is a little different. Since any process running as SYSTEM has the same permissions as a local computer account, we can skip the Kekeo asktgt.exe step. You can use another method to execute the S4U2Proxy process, with help from Microsoft. Lee and I translated this process from C# into PowerShell code as follows:

# translated from the C# example at https://msdn.microsoft.com/en-us/library/ff649317.aspx # load the necessary assembly  $Null = [Reflection.Assembly]::LoadWithPartialName('System.IdentityModel') # execute S4U2Self w/ WindowsIdentity to request a forwardable TGS for the specified user $Ident = New-Object System.Security.Principal.WindowsIdentity @('[email protected]') # actually impersonate the next context $Context = $Ident.Impersonate() # implicitly invoke S4U2Proxy with the specified action ls \PRIMARY.TESTLAB.LOCAL\C$ # undo the impersonation context $Context.Undo()Copy the code

As Microsoft officially details, when using Windows Entity, “identity-level” markup is returned by default in most cases. This allows you to see which groups are associated with user tags, but does not allow reuse access. In order to impersonate the context to access other network resources, an emulated level token is required, which is returned only if the requesting account has “Act as Part of the Operating system” user privilege (SeTcbPrivilege). This permission is only granted to the SYSTEM account by default, but since we already have SYSTEM permission to use our computer account on the network, we don’t need to worry about this.

Also, as I mentioned earlier, due to some of the features of PowerShell. Exe, if you are using PowerShell Version 2, you need to start PowerShell. Exe in single-threaded Apartment mode (with the “-sta” flag), For token impersonation to work properly:

 

SYSTEM permissions for the computer on which MSDS – AllowedtoDelegateto is set

 

S4U2Proxy for computer accounts

Scenario 3: * * * * The user account is configured to constrain delegates and is known NTLM The hash

Our next goal was to perform this transformation attack from a Windows system given only the target user’s NTLM hash, but unfortunately we could not use the same approach as scenario 2. Our gut feeling was that we had overlooked some silly details, but we wanted to spell out what we were trying to do and what went wrong, in case anyone gave a suggestion that would work. Ben points out that/Key :NTLM also works with AskTGt.exe, which is covered below.

Instead of using Kekro’s askTGt.exe, we tried to use Mimikatz’s PTH command to inject the user’s hash into memory (assuming you are a local administrator on the board). One problem here (as shown in Scenario 2) is SeTcbPrivilege, but even though we explicitly granted this privilege to our important users, we still ran into problems. It looks like the S4U2Self step is working fine:

 

Although we have the necessary privileges or permissions, it seems that the S4U2Proxy process has fallen back to NTLM instead of Kerberos and replaced the correct process with some authentication information with a value of NULL:

 

You can use asktgt.exe/s4U. Exe to execute this scenario, which is almost exactly the same as scenario 1. Simply replace/assword:PLAINTEXT with /key: NTLM, as shown below:

 

Scene 4: * * * * The computer account configuration is the constraint delegate configuration and is known NTLM The hash

If you somehow get a hash of a computer account and want to execute an attack from a computer in another domain, we assume that you will execute an attack flow that is almost identical to scenario 3. Unfortunately, we ran into the same problem. Again, if anyone can tell us what we’re doing wrong, please let us know and we’d be grateful 🙂 This can be done with /user:MACHINE$and /key:NTLM, as in scenario 3:

 

Protection measures

Microsoft has built good safeguards into the active directory that can help reduce delegate abuse. If an Account is enabled with “(Sensitive accounts can’t be delegated) Account is sensitive and can not be delegated,” then “even if the service Account is set to a Trusted Account delegated by Kerberos, the user’s security context is not delegated to the service.” You can easily check that the account has this attribute set by checking the userAccountControl attribute again and checking NOT_DELEGATED value. Powerview allows you to easily search for accounts with or without this value set (get-DomainUser-allowdelegation / -disallowdelegation), And you can use the convertfrom-uacValue function to check the value of this attribute in a particular account, as shown in the previous example.

 

【 Network Security Learning Materials 】