Unconstrained Delegation
In this section, we’ll discuss unconstrained delegation,
its specific security ramifications,
and demonstrate how to exploit it.
First, we must define unconstrained delegation and explain how it works.
We’ll begin with an overview of Kerberos authentication.
When a user successfully logs in to a computer,
a Ticket Granting Ticket is returned.
Once the user requests access to a service that uses Kerberos authentication,
a Ticket Granting Service ticket is generated,
by the Key Distribution Center,
based on the TGT and returned to the user.
This TGS is then sent to the service, which validates the access.
Note that this TGS only allows that specific user
to access that specific service.
Since the service cannot reuse the TGS to authenticate to a backend service,
any Kerberos authentication stops here.
Unconstrained delegation solves this with a forwardable TGT.
When the user requests access for a service ticket
against a service that uses unconstrained delegation,
the request also includes a forwardable TGT.
The KDC returns a TGT with the forward flag set
along with a session key for that TGT and a regular TGS.
The user’s client embeds the TGT and the session key
into the TGS and sends it to the service,
which can now impersonate the user to the backend service.
In the previous example, this means we request a TGS
for a web server service along with a forwardable TGT.
We then embed the TGT into the TGS and send it to the web server service.
The web server is now able to perform authentication to the backend database
as our user and extract the required information.
This solves the double-hop issue and provides a working solution,
but as we will soon discuss, this introduces a number of problems as well.
Since the frontend service receives a forwardable TGT,
it can perform authentication on behalf of the user
to any service (because of unconstrained delegation),
not just the intended backend service.
In our scenario, this means that
if we succeed in compromising the web server service
and a user authenticates to it,
we can steal the user’s TGT and authenticate to any service.
This is especially interesting if the authenticating user
is a high-privileged domain account.
Now that we have covered the theory, let’s perform this attack in the labs.
As with most attack techniques, we’ll begin with enumeration.
Fortunately, the Domain Controller stores the information
about computers configured with unconstrained delegation
and makes this information available for all authenticated users.
The information is stored in the userAccountControl property,
as TRUSTED_FOR_DELEGATION,
which is represented with a numerical value.
From the Windows 10 client as the Offsec domain user,
we’ll use Powerview to enumerate unconstrained delegation
through the Get-DomainComputer method,
by supplying the -Unconstrained flag,
which parses the userAccountControl property for each computer.
The appsrv01 machine is configured with unconstrained delegation
and will be our target in this section.
To abuse unconstrained delegation,
we must first compromise the computer or service account in question.
We’ll begin by resolving the IP address of appsrv01 with nslookup.
At this stage, we must either perform lateral movement onto appsrv01
or compromise a vulnerable application on that machine.
For purposes of demonstration,
we’ll simply log in to appsrv01 as the Offsec user instead,
which is local administrator on the target system.
When unconstrained delegation is operating normally,
the service account hosting the application
can freely make use of the forwarded tickets it recieves from users.
This means if we compromise the service account as a part of an attack,
we can exploit unconstrained delegation
without needing local administrative privileges,
because we already have access to all affected tickets.
In our example, we logged in to appsrv01 as the Offsec user
as part of our attack simulation.
Because of this, we must use administrative privileges
to extract the TGTs supplied by users to IIS.
First, we’ll launch Mimikatz from an administrative command prompt,
and list all tickets present with sekurlsa::tickets.
We find TGTs and TGSs related to the Offsec user
along with the computer account, but no other domain users.
Typically, a machine would only be configured with unconstrained delegation
because it hosts an application that requires it.
An Nmap scan against this machine would reveal a single running application:
an IIS-hosted web site running on port 80.
Since this is a legitimate site, we can either wait for a user to connect
or leverage an internal phishing attack to solicit visits.
In our example, we’ll simulate this by logging in to the Windows 10 client
as the admin domain user.
Then we’ll browse to appsrv01
Since the web application is configured with Windows authentication,
the Kerberos protocol is used.
Now that the browser has loaded the web page,
which is just a default IIS splash screen,
we’ll switch back to appsrv01,
and execute the sekurlsa::tickets command again.
This time, we find a TGT for the admin user
and it is flagged as forwardable.
We can use the /export flag with sekurlsa::tickets to dump it to disk.
Then we inject the TGT contents from the output file
into our process with the kerberos::ptt command.
With the TGT for the admin user injected into memory,
we can exit Mimikatz,
and test our access on the domain controller with PsExec.
We have achieved code execution on the domain controller
since the admin user is a member of the Domain Admins group.
Nice!
This illustrates that if a user connects to a service that is configured with
unconstrained Kerberos delegation, that user can be compromised.
In the next section, we’ll improve our abuse of unconstrained delegation
so that we do not have to rely on social engineering an administrative user.