Skip to content
Good news! Alsid joins Tenable -> More info |

Alsid SAS
106 Boulevard Haussmann
75008 Paris, France

Stay in touch.

Subscribe to Alsid’s newsletter and receive meaningful intels about latest Active Directory attacks or learn more about Alsid’s latest product features.

Contact us

Kerberos delegation: a new control path


This article is part of a series that explore new ways to compromise an Active Directory. The series follows an outstanding paper published by Elad Shamir: “Wagging the Dog – Abusing Resource-Based Constrained Delegation to Attack Active Directory”

The first article will focus on an AD objects ownership and permissions, the next one will address the backdoor aspect of the new-found persistence technique.


Shamir’s paper briefly explains Kerberos delegations (and you should definitely go read about it), but we would like to add more details on this, regarding other usages of Kerberos extensions he uses: S4U2Self and S4U2Proxy.


This extension enables any server to ask for a TGS on itself for an arbitrary identity. This is done with a TGS_REQ operation where the pre-authentication data contains the desired client identity for the KDC to generate the right ticket. In a traditional TGS_REQ operation, the client identity should be the requestor, so the computer account used by the host itself.

An important note to understand what’s to come, when the TGS service on the domain controller handles the TGS_REQ, it will look at the requestor’s “userAccountControl” attribute and look for the “TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION” bit. The returned ticket will be forwardable only if this bit is set.

Another property of the TGS_REQ is that any authenticated user can request a TGS for any user having a SPN. The retrieved ticket’s flags though won’t be the same depending on the conditions the S4U2Self is performed. This is used in the Kerberoasting attack, already covered quite a lot, e.g. .

— Citation bloc —

Note that S4U2Self is the mechanism used when you run the effective access 
of a specific user 
– note that you do not need to enter the credentials of the said user:


This extension still uses the TGS_REQ phase of the Kerberos authentication, but the request contains an additional ticket inside (stored in the eponym section of the TGS_REQ). This nested ticket usually can be obtained in two ways.

If the client has been authenticated through Kerberos, the nested ticket used by the server is the service ticket TS. This TS has to be forwardable for it to usually be reusable (although Shamir found one case where it does not seem to matter) and the KDC set it only if the client account can be delegated.

If the client did not authenticate on the server, the server can use aforementioned S4U2Self operation to impersonate the client. Once again, the ticket can be included in the TGS_REQ only if the forwardable bit is set – which is the case when the server has the “TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION” in its “userAccountControl” attribute. The latter scenario is used when the server is configured with the protocol transition (“Use any authentication protocol”).

However, for S4U2Proxy, the server cannot ask a ticket for anybody. The ticket asked needs to be for a SPN listed in the “msDS-AllowedToDelegateTo” attribute (which completes the classic constraint delegation) or the server has to be authorized in the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute.

Objects ownership and permissions

Being owner

To begin on the ownership subject, we have to state a potential well-known truth: the owner of an object has the implicit right to modify the DACL of this object. That means even if there is an explicit deny for the owner not to be able to touch the object, the owner will still have the rights to change permissions.

 --- Citation bloc --- 
This is generally true, but an exception exists: positioning a Deny for the 
OWNER RIGHTS SID (S-1-3-4) in an object’s ACE removes the owner’s 
implicit control of this object’s DACL.

This rule is one of the bases of Microsoft security model, it applies as well as on Active Directory objects as on the NTFS objects.

Figure 1 Owner user without the right to write to the DACL
Figure 2 Add an ACE in the nTSecurityDescriptor just because RedTeddy is owner
Figure 3 ACE effectively added to the nTSecurityDescriptor

It is important to understand this point, because applying this on a computer object is special. If you can modify the DACL, you can add the reset password right for yourself and perform the reset password operation on the computer object. As the previous and current passwords for a host machine are valid, resetting the password does not disable the host’s access to the AD and enables you to have the host’s password. Once you have the host’s password, it’s over: you can get a TGT for the host, mount C$ and have fun.

Only the write property right

Now, when you are not owner of the object nor have you any other classic control right except writing to the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute, can you still own the host?

Well that’s one of the points of Shamir’s paper. If you have access to an account with an SPN and have the right to write into the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute of a computer object, you basically can own the object’s host. Having access to an account with an SPN might not be the most difficult part as accounts can create new computers (see the “ms-DS-MachineAccountQuota” attribute on the domain’s root). The computers will have SPNs or, as you will be owner of the computer object, you will have the right to add the right to write into the “servicePrincipalName” attribute, then add SPNs.

For the attack, Shamir first sets the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute on the computer object (here desktop-u2v0mfq) to have the value of the account the attacker controls (e.g. DESKTOP-LOL42XPS$).

Under the hood, in the object’s “nTSecurityDescriptor” attribute, the right to write this attribute is represented as an ACE of the following form :

Figure 4 A right in a middle of an SDDL

In the ACE, the “OA” means it is an “Allow” entry on a subset of the object, “WP” means “Write Property”, the “3f78c3e5-f79a-46bd-a0b8-9d18116ddc79” GUID is the “SchemaIDGUID” attribute of the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute – retrievable in the schema partition – and the “S-1-5-21-2985693341-697491136-3488640750-1105” SID is the user – the security principal – on which the ACE applies, called the trustee. So basically, this entry allows the domain user which RID is 1105 to write the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute, which is exactly what we need.

Now to effectively use the right and change the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute’s value, the “Set-ADComputer” cmdlet from the ActiveDirectory PowerShell module can be used:

Figure 5 Add DESKTOP-LOL42XPS$ into desktop-u2v0mfq’s msDS-AllowedToActOnBehalfOfOtherIdentity

Performing this attribute change enables the DESKTOP-LOL42XPS$ account to first request a non-forwardable TGS for any user for itself using S4U2Self, and then use the retrieved TGS with the S4U2Proxy component with the same user on the targeted host.

Figure 6 Rubeus attack with pass-the-ticket

Let’s dissect this command line:

--- Command line ---
./Rubeus.exe s4u /user:DESKTOP-LOL42XPS$
/msdsspn:cifs/desktop-u2v0mfq.panda.lab /impersonateuser:administrator /ptt

At the time of writing, the Rubeus version used is the one from Shamir’s repository:

The “s4u” is the subcommand, or attack here, performed. It needs a controlled account, e.g. DESKTOP-LOL42XPS$. This account is the one with the SPN, the same one in the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute of the computer’s object.

The AES parameter is the Kerberos key associated to the account. It is used to build the TGS requests for both the S4U2Self and S4U2Proxy phases.

--- Citation bloc ---
You can easily retrieve the key using the “sekurlsa::ekeys” command of Mimikatz 
on the compromised computer and look for the entry corresponding 
to the LocalSystem account 
(with the 999 authentication ID or the S-1-5-18 SID).
Figure 7 Computer account entry

Or you can use the “DCSync” feature and use the retrieved AES key.

The domain and impersonated user parameters are simply used to create a ticket for the said user for each TGS request.

And finally, the “ptt” parameter tells Rubeus to insert the retrieved ticket in the current session’s tickets cache, allowing the current user to use the ticket.

Figure 8 Using the ticket is as simple as mount C$

Now let’s examine the output of Rubeus. The first thing to have is a TGT so that the TGS request can be performed. This step basically proves to the KDC that you’re authenticated with the DESKTOP-LOL42XPS$ account? This also enables you to create a TGS request, in which you need the session key shared between you and the KDC, SC,K in the literature, and retrieved in the TGT request’s response.

The second operation is to ask for a TGS for the Administrator user on the current, controlled computer, here DESKTOP-LOL42XPS$. This is a S4U2Self operation and is at least used by Windows to check the effective rights on the filesystem. The TGS service thus dutifully answers and give us the requested, non-forwardable ticket.

The last Kerberos operation is to ask for a TGS for the same Administrator user, but on the targeted service and account, respectively CIFS and desktop-u2v0mfq here. This is a S4U2Proxy operation which performs a TGS request just like S4U2Self did, but with the previously obtained ticket added in the request (in the “additional-tickets” field). This additional ticket tells the TGS service on the Domain Controller not to use the requestor’s name in the to-be-created ticket’s client name, but instead use the additional ticket’s one.

Now here’s the interesting part: this should not be possible. At least, in the classical Kerberos delegation idea, using the “msDS-AllowedToDelegateTo” attribute, the TGS service will refuse to give an impersonated TGS when the included additional ticket is not marked as forwardable. And the ticket we gave is not marked as forwardable, because we get it from a S4U2Self operation.

However, as per the Microsoft specifications, this flag is not checked when the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute is used. Quoting Shamir, it is a feature, not a bug. And so it works! We retrieve a TGS for the user Administrator on the requested service.

The last part to finish the attack is simply to use the retrieved ticket to authenticate on the targeted service, cifs/desktop-u2v0mfq.panda.lab.

Efficiently detect the attack in your environment

Detecting S4U2Self backdoors when you are not using Alsid’s solution

Not everybody has access to Alsid for AD, but everything is not lost.

First of all, a small PowerShell script can be run on an ad hoc basis to retrieve all the ACEs specifically concerning the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute:

--- Command line ---
Import-Module ActiveDirectory
First get the GUID (spoiler, it will be 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79)
$rootDSE = Get-ADRootDSE
$scopedAttribute = "msDS-AllowedToActOnBehalfOfOtherIdentity"
$scopedSchemaIDGUID = 
(Get-ADObject -SearchBase $($rootDSE.schemaNamingContext) 
-LDAPFilter "(lDAPDisplayName=$scopedAttribute)" 
-Properties schemaIDGUID).schemaIDGUID
Then for each AD object, look for an incriminating ACE
Get-ADObject -Filter * -Properties nTSecurityDescriptor | ForEach-Object {
$adObject = $_
$acls = $adObject.nTSecurityDescriptor.Access |
Where-Object ObjectType -eq $scopedSchemaIDGUID |
Where-Object {
$_.AccessControlType -eq 'Allow' -and
$_.ActiveDirectoryRights -eq 'WriteProperty' -and
$_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value -ne 'S-1-5-10'
if ($acls) { [PSCustomObject]@{ DistinguishedName = $adObject.DistinguishedName Access = $acls } }

Its output is each object that has at least one ACE in its DACL that explicitly authorize the Write Property right on the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute for other users than “Self”.

A second script can be used to list every object having a non-empty “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute:

--- Command line ---
Get-ADObject -LDAPFilter "(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" 
-Properties msDS-AllowedToActOnBehalfOfOtherIdentity 
| ForEach-Object {
DistinguishedName = $_.DistinguishedName
= $_.'msDS-AllowedToActOnBehalfOfOtherIdentity'

This script outputs the object’s DistinguishedName and the content of the attribute. Both scripts can be run with a user without any privilege, it just needs to be able to read the “nTSecurityDescriptor” and the “msDS-AllowedToActOnBehalfOfOtherIdentity” attributes.

Those commands do not monitor the AD in live, so you might be able to run them occasionally, but it might already be too late. What you need is to be alerted as soon as something like this appears on your AD. Without Alsid for AD, you can leverage the SACL mechanism on your AD to produce an event when a certain condition is met.

--- Command line ---
Import-Module ActiveDirectory
$rootDSE = Get-ADRootDSE
Create a lDAPDisplayName -> schemaIDGUID mapping
$ldapDisplayNameToSchemaIdGuid = @{}
Get-ADObject -SearchBase $($rootDSE.schemaNamingContext) -LDAPFilter "(schemaIDGUID=*)"
-Properties lDAPDisplayName, schemaIDGUID | ForEach-Object {
$ldapDisplayNameToSchemaIdGuid[$_.lDAPDisplayName] = [GUID]$_.schemaIDGUID
Object class, attribute and scope to configure auditing for
$scopedObject = "user"
$schemaIDGUIDScopedObject = $ldapDisplayNameToSchemaIdGuid[$scopedObject]
$scopedAttribute = "msDS-AllowedToActOnBehalfOfOtherIdentity"
$schemaIDGUIDScopedAttribute = $ldapDisplayNameToSchemaIdGuid[$scopedAttribute]
$inheritanceScope = "Descendents"
Security principal to audit for actions: every user
$securityPrincipalObject = [Security.Principal.NTAccount]'Everyone'
Define the entry
$rightsCollection = [System.DirectoryServices.ActiveDirectoryRights]::WriteProperty
$auditType = [System.Security.AccessControl.AuditFlags]::"Success", "Failure"
$auditDefinition = 
$securityPrincipalObject, $rightsCollection, 
$auditType, $schemaIDGUIDScopedAttribute, 
$inheritanceScope, $schemaIDGUIDScopedObject
$auditRule = 
New-Object System.DirectoryServices.ActiveDirectoryAuditRule
Get, add, update the ACL
$drivePath = "AD:\$($rootDSE.defaultNamingContext)"
$acl = Get-Acl $drivePath -Audit
$acl | Set-Acl $drivePath

This last script hopefully has to be launched from a privileged user, otherwise random users could update the rights of all of the AD objects.
The eventId 4742 is generated when the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute is modified. This is a generic event and this attribute isn’t listed, so you will not see the newly-set value nor will you be sure that this is the changed attribute, e.g. if you have other SACL generating this eventId:

Even though you will not be able to know for sure this is the attribute that has been changed, you can see the targeted computer in the “TargetUserName”/“TargetSid” and the writer of the attribute in the “SubjectUserName”/“SubjectUserSid”.

Alsid customers, you are already protected

Throughout this attack, there are a few ways to alert a SOC.

The first thing Alsid for AD detects is an ACE allowing a security principal other than “Self” to write in the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute when it has already been present for a time, but also as soon as it is set, e.g. for persistence purposes. This is done by combining the review of the entire objects’ ACLs with an understanding of the replication process, enabling live monitoring of changes happening on the Directory.

In the same idea, having new users being added to the “msDS-AllowedToActOnBehalfOfOtherIdentity” attribute is not something done on a daily basis. Alsid for AD sees all the changes made in the AD, but it cannot know which principal made the change (yet?), so it can send the attribute change to a SOC, which will be able to correlate this with other data to decide to raise an alert or not.

The security analysis is therefore entirely managed by Alsid, Customers do not have to configure anything specific and test the impact on their AD infrastructure, you merely need to review the results from the web interface and clear the attribute if not legit.

Figure 9 Clear the msDS-AllowedToActOnBehalfOfOtherIdentity attribute


There already exist a lot of control possibilities between objects, all having their specificities, but Shamir found yet another way to control an object from another one. If an attacker can control an account with an SPN and can control the “msDS-AllowedToActOnBehalfOfOtherIdentity” on another one, then he can own the latter’s host server.

At Alsid, we track those control relationships between objects to provide you a top-notch AD security level. This kind of new control relationship has already been added to our Indicators-of-Exposure database, so sleep well tonight, dear Customers, because we have your back.

Comments are closed.

Download pdf