Delegate My Ticket
Since web01 is configured with constrained delegation to the file01 machine,
this means that we can use the web01 machine account NTLM hash
to request a TGS
as any user
for the CIFS service on file01.
If we request a TGS as a user that is a member of the Domain Admins group,
we will have the permissions required to obtain code execution on file01.
The best tool for constrained delegation abuse is Rubeus.
Before compiling Rubeus, the .NET version must be changed to target 4.6
since that is what is installed on Windows Server 2019.
We can do this by navigating to Project
Rubeus Properties,
and changing the Target framework to .NET Framework 4.6.
If we compile and transfer the Rubeus binary to web01 and try to directly
invoke it from the command prompt
it is very likely that the antivirus will flag it.
This is because the default version of Rubeus is well known to antivirus engines
even when we perform the compilation ourselves.
At this point, we can either try to modify the Rubeus source code to evade detection
or execute it directly from memory
after disabling AMSI.
Due to the rather large Rubeus code base, we will run it from memory.
After Rubeus is compiled, we’ll copy it to the web root of our Kali machine,
and turn to our SYSTEM Meterpreter shell.
We’ll open a command prompt and in turn, open PowerShell.
Here, we’ll initially bypass AMSI through a download cradle,
after which we’ll download Rubeus into memory,
and load it as an assembly.
Now Rubeus is loaded into memory through the Load method,
of the System.Reflection.Assembly namespace.
To interact with it, we’ll take advantage of the fact that the Main method is public
and we can invoke all of its functionality
by specifying the function name.
As a simple example, let’s invoke the purge function,
to clear all Kerberos tickets from memory
directly through the Main method.
Now we can invoke Rubeus to request the TGS for the CIFS service on file01
as administrator, which is a domain admin.
To do this in a single command, we’ll call the s4u function
and supply a series of arguments.
First, we’ll specify the username,
and the NTLM hash,
of the web01 machine account,
which is called “web01$”.
Next, we’ll provide the user to impersonate,
which in our case is “administrator”.
These options will allow Rubeus to obtain a TGT for web01$
followed by a S4U2self request
to get a forwardable TGS for administrator
to web01.
As the final arguments, we’ll supply the SPN we want to target,
which is the CIFS service on file01,
and finally, we’ll signal the generated TGS to be loaded into memory.
The output indicates that a TGS as the administrator user for the CIFS service
on file01
has been generated,
and injected into memory.
We can verify this with the klist command.
We have successfully obtained a service ticket for the CIFS service on file01
as the administrator domain admin user.
Note that when working through a reverse shell,
the generated TGS is occasionally lost
and must be requested again.
To prove that the ticket works, we can simply list
the directory of the c$ share on file01.
In this section, we exploited constrained delegation
through the dumped NTLM hash of web01$
and obtained a TGS for the CIFS service on file01.
In the next section, we’ll use this TGS to perform lateral movement.