3
3
require 'erb'
4
4
require 'cgi'
5
5
require 'date'
6
+ require 'set'
6
7
require 'rex/exploitation/js'
7
8
require 'msf/core/exploit/jsobfu'
8
9
@@ -23,43 +24,43 @@ module Exploit::Remote::BrowserExploitServer
23
24
# this must be static between runs, otherwise the older cookies will be ignored
24
25
DEFAULT_COOKIE_NAME = '__ua'
25
26
26
- PROXY_REQUEST_HEADER_SET = Set . new (
27
- %w{
28
- CLIENT_IP
29
- FORWARDED
30
- FORWARDED_FOR
31
- FORWARDED_FOR_IP
32
- HTTP_CLIENT_IP
33
- HTTP_FORWARDED
34
- HTTP_FORWARDED_FOR
35
- HTTP_FORWARDED_FOR_IP
36
- HTTP_PROXY_CONNECTION
37
- HTTP_VIA
38
- HTTP_X_FORWARDED
39
- HTTP_X_FORWARDED_FOR
40
- VIA
41
- X_FORWARDED
42
- X_FORWARDED_FOR
43
- } )
27
+ PROXY_REQUEST_HEADER_SET = Set . new ( %w{
28
+ CLIENT_IP
29
+ FORWARDED
30
+ FORWARDED_FOR
31
+ FORWARDED_FOR_IP
32
+ HTTP_CLIENT_IP
33
+ HTTP_FORWARDED
34
+ HTTP_FORWARDED_FOR
35
+ HTTP_FORWARDED_FOR_IP
36
+ HTTP_PROXY_CONNECTION
37
+ HTTP_VIA
38
+ HTTP_X_FORWARDED
39
+ HTTP_X_FORWARDED_FOR
40
+ VIA
41
+ X_FORWARDED
42
+ X_FORWARDED_FOR
43
+ } )
44
44
45
45
# Requirements a browser module can define in either BrowserRequirements or in targets
46
- REQUIREMENT_KEY_SET = {
47
- :source => 'source' , # Either 'script' or 'headers'
48
- :ua_name => 'ua_name' , # Example: MSIE
49
- :ua_ver => 'ua_ver' , # Example: 8.0, 9.0
50
- :os_name => 'os_name' , # Example: Microsoft Windows
51
- :os_flavor => 'os_flavor' , # Example: XP, 7
52
- :language => 'language' , # Example: en-us
53
- :arch => 'arch' , # Example: x86
54
- :proxy => 'proxy' , # 'true' or 'false'
55
- :silverlight => 'silverlight' , # 'true' or 'false'
56
- :office => 'office' , # Example: "2007", "2010"
57
- :java => 'java' , # Example: 1.6, 1.6.0.0
58
- :clsid => 'clsid' , # ActiveX clsid. Also requires the :method key
59
- :method => 'method' , # ActiveX method. Also requires the :clsid key
60
- :mshtml_build => 'mshtml_build' , # mshtml build. Example: "65535"
61
- :flash => 'flash' # Example: "12.0" (chrome/ff) or "12.0.0.77" (IE)
62
- }
46
+ REQUIREMENT_KEY_SET = Set . new ( [
47
+ :source , # Either 'script' or 'headers'
48
+ :ua_name , # Example: MSIE
49
+ :ua_ver , # Example: 8.0, 9.0
50
+ :os_name , # Example: Microsoft Windows
51
+ :os_flavor , # Example: XP, 7
52
+ :language , # Example: en-us
53
+ :arch , # Example: x86
54
+ :proxy , # 'true' or 'false'
55
+ :silverlight , # 'true' or 'false'
56
+ :office , # Example: "2007", "2010"
57
+ :java , # Example: 1.6, 1.6.0.0
58
+ :clsid , # ActiveX clsid. Also requires the :method key
59
+ :method , # ActiveX method. Also requires the :clsid key
60
+ :mshtml_build , # mshtml build. Example: "65535"
61
+ :flash , # Example: "12.0" (chrome/ff) or "12.0.0.77" (IE)
62
+ :vuln_test # Example: "if(window.MyComponentIsInstalled)return true;"
63
+ ] )
63
64
64
65
def initialize ( info = { } )
65
66
super
@@ -129,7 +130,7 @@ def get_target
129
130
# @return [Hash] A hash of requirements
130
131
#
131
132
def extract_requirements ( reqs )
132
- tmp = reqs . select { |k , v | REQUIREMENT_KEY_SET . has_key ?( k . to_sym ) }
133
+ tmp = reqs . select { |k , v | REQUIREMENT_KEY_SET . include ?( k . to_sym ) }
133
134
# Make sure keys are always symbols
134
135
Hash [ tmp . map { |( k , v ) | [ k . to_sym , v ] } ]
135
136
end
@@ -189,9 +190,12 @@ def get_bad_requirements(profile)
189
190
# Special keys to ignore because the script registers this as [:activex] = true or false
190
191
next if k == :clsid or k == :method
191
192
192
- vprint_debug ( "Comparing requirement: #{ k } =#{ v } vs k=#{ profile [ k . to_sym ] } " )
193
+ expected = k != :vuln_test ? v : 'true'
194
+ vprint_debug ( "Comparing requirement: #{ k } =#{ expected } vs #{ k } =#{ profile [ k . to_sym ] } " )
193
195
194
- if v . is_a? Regexp
196
+ if k == :vuln_test
197
+ bad_reqs << k unless profile [ k . to_sym ] . to_s == 'true'
198
+ elsif v . is_a? Regexp
195
199
bad_reqs << k if profile [ k . to_sym ] !~ v
196
200
elsif v . is_a? Proc
197
201
bad_reqs << k unless v . call ( profile [ k . to_sym ] )
@@ -375,19 +379,20 @@ def get_detection_html(user_agent)
375
379
window.onload = function() {
376
380
var osInfo = os_detect.getVersion();
377
381
var d = {
378
- "<%=REQUIREMENT_KEY_SET[:os_name]%>" : osInfo.os_name,
379
- "<%=REQUIREMENT_KEY_SET[:os_flavor]%>" : osInfo.os_flavor,
380
- "<%=REQUIREMENT_KEY_SET[:ua_name]%>" : osInfo.ua_name,
381
- "<%=REQUIREMENT_KEY_SET[:ua_ver]%>" : osInfo.ua_version,
382
- "<%=REQUIREMENT_KEY_SET[:arch]%>" : osInfo.arch,
383
- "<%=REQUIREMENT_KEY_SET[:java]%>" : misc_addons_detect.getJavaVersion(),
384
- "<%=REQUIREMENT_KEY_SET[:silverlight]%>" : misc_addons_detect.hasSilverlight(),
385
- "<%=REQUIREMENT_KEY_SET[:flash]%>" : misc_addons_detect.getFlashVersion()
382
+ "os_name" : osInfo.os_name,
383
+ "os_flavor" : osInfo.os_flavor,
384
+ "ua_name" : osInfo.ua_name,
385
+ "ua_ver" : osInfo.ua_version,
386
+ "arch" : osInfo.arch,
387
+ "java" : misc_addons_detect.getJavaVersion(),
388
+ "silverlight" : misc_addons_detect.hasSilverlight(),
389
+ "flash" : misc_addons_detect.getFlashVersion(),
390
+ "vuln_test" : <%= js_vuln_test %>
386
391
};
387
392
388
393
<% if os == OperatingSystems::WINDOWS and client == HttpClients::IE %>
389
- d['<%=REQUIREMENT_KEY_SET[: office]%> '] = ie_addons_detect.getMsOfficeVersion();
390
- d['<%=REQUIREMENT_KEY_SET[: mshtml_build]%> '] = ScriptEngineBuildVersion().toString();
394
+ d['office'] = ie_addons_detect.getMsOfficeVersion();
395
+ d['mshtml_build'] = ScriptEngineBuildVersion().toString();
391
396
<%
392
397
clsid = @requirements[:clsid]
393
398
method = @requirements[:method]
@@ -497,6 +502,12 @@ def on_request_uri(cli, request)
497
502
method ( :on_request_exploit ) . call ( cli , request , profile )
498
503
else
499
504
print_warning ( "Exploit requirement(s) not met: #{ bad_reqs * ', ' } . For more info: http://r-7.co/PVbcgx" )
505
+ if bad_reqs . include? ( :vuln_test )
506
+ error_string = ( self . module_info [ 'BrowserRequirements' ] || { } ) [ :vuln_test_error ]
507
+ if error_string . present?
508
+ print_warning ( error_string )
509
+ end
510
+ end
500
511
send_not_found ( cli )
501
512
end
502
513
end
@@ -555,5 +566,16 @@ def get_payload(cli, browser_info)
555
566
regenerate_payload ( cli , platform , arch ) . encoded
556
567
end
557
568
569
+ # @return [String] custom Javascript to check if a vulnerability is present
570
+ def js_vuln_test
571
+ all_reqs = self . module_info [ 'BrowserRequirements' ] || { }
572
+ if all_reqs [ :vuln_test ] . present?
573
+ code = all_reqs [ :vuln_test ] + ';return !!this.is_vuln;'
574
+ 'Function((' +JSON . generate ( :code => code ) +').code)()'
575
+ else
576
+ 'true'
577
+ end
578
+ end
579
+
558
580
end
559
581
end
0 commit comments