metasploit-framework/lib/msf/core/exploit/remote/http/jboss/base.rb

142 lines
3.8 KiB
Ruby

# -*- coding: binary -*-
module Msf::Exploit::Remote::HTTP::JBoss::Base
# Deploys a WAR through HTTP uri invoke
#
# @param opts [Hash] Hash containing {Exploit::Remote::HttpClient#send_request_cgi} options
# @param num_attempts [Integer] The number of attempts
# @return [Rex::Proto::Http::Response, nil] The {Rex::Proto::Http::Response} response if exists, nil otherwise
def deploy(opts = {}, num_attempts = 5)
uri = opts['uri']
if uri.blank?
return nil
end
# JBoss might need some time for the deployment. Try 5 times at most and
# wait 5 seconds inbetween tries
num_attempts.times do |attempt|
res = send_request_cgi(opts, 5)
msg = nil
if res.nil?
msg = "Execution failed on #{uri} [No Response]"
elsif res.code == 200
vprint_status("Successfully called '#{uri}'")
return res
else
msg = "http request failed to #{uri} [#{res.code}]"
end
if attempt < num_attempts - 1
msg << ", retrying in 5 seconds..."
vprint_status(msg)
Rex.sleep(5)
else
print_error(msg)
return res
end
end
end
# Provides the HTTP verb used
#
# @return [String] The HTTP verb in use
def http_verb
datastore['VERB']
end
# Try to auto detect the target architecture and platform
#
# @param [Array] available_targets The available targets
# @return [Msf::Module::Target, nil] The detected target or nil
def auto_target(available_targets)
if http_verb == 'HEAD'
print_status("Sorry, automatic target detection doesn't work with HEAD requests")
else
print_status("Attempting to automatically select a target...")
res = query_serverinfo
plat = detect_platform(res)
unless plat
print_warning('Unable to detect platform!')
return nil
end
arch = detect_architecture(res)
unless arch
print_warning('Unable to detect architecture!')
return nil
end
# see if we have a match
available_targets.each { |t| return t if t['Platform'] == plat && t['Arch'] == arch }
end
# no matching target found, use Java as fallback
java_targets = available_targets.select {|t| t.name =~ /^Java/ }
java_targets[0]
end
# Query the server information from HtmlAdaptor
#
# @return [Rex::Proto::Http::Response, nil] The {Rex::Proto::Http::Response} response or nil
def query_serverinfo
path = normalize_uri(target_uri.path.to_s, 'HtmlAdaptor')
res = send_request_cgi(
{
'uri' => path,
'method' => http_verb,
'vars_get' =>
{
'action' => 'inspectMBean',
'name' => 'jboss.system:type=ServerInfo'
}
})
unless res && res.code == 200
print_error("Failed: Error requesting #{path}")
return nil
end
res
end
# Try to autodetect the target platform
#
# @param res [Rex::Proto::Http::Response] the http response where fingerprint platform from
# @return [String, nil] The target platform or nil
def detect_platform(res)
if res && res.body =~ /<td.*?OSName.*?(Linux|FreeBSD|Windows).*?<\/td>/m
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 target architecture
#
# @param res [Rex::Proto::Http::Response] the http response where fingerprint architecture from
# @return [String, nil] The target architecture or nil
def detect_architecture(res)
if res && res.body =~ /<td.*?OSArch.*?(x86_64|amd64|x86|i386|i686).*?<\/td>/m
arch = $1
if arch =~ /^(x86_64|amd64)$/i
return ARCH_X64
elsif arch =~ /^(x86|i386|i686)$/i
return ARCH_X86
end
end
nil
end
end