Why this post exists
This is the first in a series of write-ups I’m publishing as part of my OSCP preparation. The strategy is to follow the Lain Kusanagi curated list (a fork/evolution of the classic TJNull list), which selects HackTheBox machines with attack vectors and exploitation patterns similar to those found in the exam.
The goal of these posts is not just to document the solution, but to consolidate what I’ve learned: each write-up is structured as a condensed pentest report - recon, enumeration, foothold, privesc and takeaways - in the same format OffSec expects in the exam.
Machine info
| Name | Sea |
| Platform | HackTheBox |
| OS | Linux |
| Difficulty | Easy |
TL;DR
- WonderCMS with “bike” theme vulnerable to Stored XSS to RCE (CVE-2023-41425)
- XSS via contact form injects a malicious module that installs a reverse shell
- Cracked credentials from
database.jsgive SSH access asamay - Port forward on 8080 reveals System Monitor with command injection on the
log_fileparameter to get root
Recon
RustScan + Nmap
| |

Open ports: 22 (SSH) and 80 (HTTP).

- Port 22: OpenSSH 8.2p1 Ubuntu
- Port 80: Apache 2.4.41 (Ubuntu)
Web service fingerprint
| |

Tech stack: Apache 2.4.41, PHP (PHPSESSID), Bootstrap 3.3.7, jQuery 1.12.4. Title: “Sea - Home”.
Enumeration
Web - Browsing the site
The main page shows a cycling competition website with the velik71 theme.

Browsing the site we find a “How can I participate?” page with a link to a contact form.

The contact form at contact.php has fields for Name, Email, Age, Country and Website.

Identifying the CMS
Looking at the page source code, I noticed images were being loaded from /themes/bike/, indicating the use of a theme called “bike”.

A quick Google search for “velik71” reveals this is a WonderCMS theme called “bike”, available at https://github.com/robiso/bike.

With the theme directory identified, I ran a directory brute force with feroxbuster to enumerate files:
| |

Among the results, the /themes/bike/version endpoint returned version 3.2.0.
WonderCMS 3.2.0 - vulnerable to CVE-2023-41425 (Stored XSS to RCE via installModule).
Foothold
CVE-2023-41425 - WonderCMS XSS to RCE
I used the exploit from prodigiousMind/CVE-2023-41425 which works as follows:
- Generates an XSS payload that, when executed by the admin, installs a malicious module (reverse shell)
- The payload is sent via the contact form in the Website field
- When the admin views the message, the XSS fires and installs the module
| |

The exploit generates xss.js, starts an HTTP server on port 8000, and instructs you to send the malicious link to the admin.
Debugging the exploit
I submitted the payload in the Website field of the contact form and opened netcat:

The xss.js was requested by the target - the XSS executed:

But no reverse shell. Time to debug xss.js.

Reading through the exploit code, I identified several issues.
Fix 1: Host main.zip locally
The xss.js payload tries to download main.zip from GitHub and install it as a WonderCMS module. Since the target has no internet access, we need to host main.zip locally and point the exploit to our machine.
| |
Fix 2: Hardcode urlWithoutLogBase
The next issue was the urlWithoutLogBase variable. Using the browser console to simulate:

urlWithoutLogBase resolved to /, making urlRev become //?installModule=... - an invalid URL:

I edited the exploit to hardcode urlWithoutLogBase = 'http://sea.htb/':

I resubmitted the form. This time the target made requests to main.zip, but I got an error - the exploit was using https:// for the installModule URL, but the python server was serving via http://:

Fix 3: HTTPS to HTTP
I changed https:// to http:// in the installModule URL inside the exploit. Resubmitted once more:

The target fetched xss.js, then main.zip, installed the module, and we got a reverse shell!
Shell as www-data

Upgrade to interactive TTY:
| |

Privilege Escalation
Credentials in database.js
Browsing /var/www/sea/data/, I found the WonderCMS database.js file containing a bcrypt hash:

| |
Cracking with John
| |

Cracked password: mychemicalromance
Checking /etc/passwd, there are two users: amay and geo.
Local enumeration with LinPEAS
| |

LinPEAS revealed interesting internal ports:

- 127.0.0.1:8080 - internal web service
- 127.0.0.1:36189 - another service
Port Forwarding via SSH
With the cracked password, I set up SSH port forwarding as amay:
| |

System Monitor - Command Injection
Accessing http://localhost:9999 on Kali, logged in with amay:mychemicalromance:

The application is a System Monitor (Developing) with management features:

The “Analyze” button sends a POST request with the log_file parameter. Intercepting with browser DevTools:

The log_file parameter points to /var/log/apache2/access.log. I tested command injection with ping:
| |
Confirmed via tcpdump - ICMP echo request received:

Root shell
Injected a reverse shell via the same parameter:
| |

Root!
Takeaways (for OSCP)
- Always debug public exploits before giving up. The CVE-2023-41425 exploit had 3 bugs in this machine’s context (urlWithoutLogBase, hardcoded HTTPS, wrong path). Understanding the JavaScript code instead of treating the exploit as a black box was essential.
- Internal ports are gold. LinPEAS +
netstatrevealed the System Monitor on 8080. On the OSCP, always check services on127.0.0.1and set up port forwarding. - Password reuse is standard in labs. The cracked WonderCMS password worked for both SSH (amay) and the System Monitor. Always test for reuse.
- Command injection in internal web apps is a common privesc vector. Applications “in development” listening on localhost tend to have little to no input sanitization.
References
- HackTheBox - Sea
- CVE-2023-41425 - WonderCMS XSS to RCE
- WonderCMS bike theme
- Lain Kusanagi list (OSCP prep)
