Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/gather/enum_av_excluded.rb
19535 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::Windows::Registry
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Windows Antivirus Exclusions Enumeration',
14
'Description' => %q{
15
This module will enumerate the file, directory, process and
16
extension-based exclusions from supported AV products, which
17
currently includes Microsoft Defender, Microsoft Security
18
Essentials/Antimalware, and Symantec Endpoint Protection.
19
},
20
'License' => MSF_LICENSE,
21
'Author' => [
22
'Andrew Smith', # original metasploit module
23
'Jon Hart <jon_hart[at]rapid7.com>' # improved metasploit module
24
],
25
'Platform' => [ 'win' ],
26
# XXX: this will work with 'shell' when the sysinfo parts are removed
27
# and https://github.com/rapid7/metasploit-framework/issues/6328
28
# is fixed
29
'SessionTypes' => [ 'meterpreter' ],
30
'Notes' => {
31
'Stability' => [CRASH_SAFE],
32
'SideEffects' => [],
33
'Reliability' => []
34
}
35
)
36
)
37
38
register_options(
39
[
40
OptBool.new('DEFENDER', [true, 'Enumerate exclusions for Microsoft Defender', true]),
41
OptBool.new('ESSENTIALS', [true, 'Enumerate exclusions for Microsoft Security Essentials/Antimalware', true]),
42
OptBool.new('SEP', [true, 'Enumerate exclusions for Symantec Endpoint Protection (SEP)', true])
43
]
44
)
45
end
46
47
DEFENDER = 'Windows Defender'
48
DEFENDER_BASE_KEY = 'HKLM\\SOFTWARE\\Microsoft\\Windows Defender'
49
ESSENTIALS = 'Microsoft Security Essentials / Antimalware'
50
ESSENTIALS_BASE_KEY = 'HKLM\\SOFTWARE\\Microsoft\\Microsoft Antimalware'
51
SEP = 'Symantec Endpoint Protection (SEP)'
52
SEP_BASE_KEY = 'HKLM\\SOFTWARE\\Symantec\\Symantec Endpoint Protection'
53
54
def av_installed?(base_key, product)
55
if registry_key_exist?(base_key)
56
print_good("Found #{product}")
57
true
58
else
59
false
60
end
61
end
62
63
def excluded_sep
64
base_exclusion_key = "#{SEP_BASE_KEY}\\Exclusions\\ScanningEngines\\Directory"
65
admin_exclusion_key = "#{base_exclusion_key}\\Admin"
66
client_exclusion_key = "#{base_exclusion_key}\\Client"
67
68
admin_paths = []
69
if (admin_exclusion_keys = registry_enumkeys(admin_exclusion_key, @registry_view))
70
admin_exclusion_keys.map do |key|
71
admin_paths << registry_getvaldata("#{admin_exclusion_key}\\#{key}", 'DirectoryName', @registry_view)
72
end
73
print_exclusions_table(SEP, 'admin path', admin_paths)
74
end
75
client_paths = []
76
if (client_exclusion_keys = registry_enumkeys(client_exclusion_key, @registry_view))
77
client_exclusion_keys.map do |key|
78
client_paths << registry_getvaldata("#{client_exclusion_key}\\#{key}", 'DirectoryName', @registry_view)
79
end
80
end
81
print_exclusions_table(SEP, 'client path', client_paths)
82
end
83
84
def excluded_defender
85
print_exclusions_table(DEFENDER, 'extension', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Extensions", @registry_view))
86
print_exclusions_table(DEFENDER, 'path', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Paths", @registry_view))
87
print_exclusions_table(DEFENDER, 'process', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Processes", @registry_view))
88
end
89
90
def excluded_mssec
91
print_exclusions_table(ESSENTIALS, 'extension', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Extensions", @registry_view))
92
print_exclusions_table(ESSENTIALS, 'path', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Paths", @registry_view))
93
print_exclusions_table(ESSENTIALS, 'process', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Processes", @registry_view))
94
end
95
96
def print_exclusions_table(product, exclusion_type, exclusions)
97
exclusions ||= []
98
exclusions = exclusions.compact.reject(&:blank?)
99
if exclusions.empty?
100
print_status("No #{exclusion_type} exclusions for #{product}")
101
return
102
end
103
table = Rex::Text::Table.new(
104
'Header' => "#{product} excluded #{exclusion_type.pluralize}",
105
'Indent' => 1,
106
'Columns' => [ exclusion_type.capitalize ]
107
)
108
exclusions.map { |exclusion| table << [exclusion] }
109
print_line(table.to_s)
110
end
111
112
def setup
113
unless datastore['DEFENDER'] || datastore['ESSENTIALS'] || datastore['SEP']
114
fail_with(Failure::BadConfig, 'Must set one or more of DEFENDER, ESSENTIALS or SEP to true')
115
end
116
117
# all of these target applications seemingly store their registry
118
# keys/values at the same architecture of the host, so if we happen to be
119
# in a 32-bit process on a 64-bit machine, ensure that we read from the
120
# 64-bit keys/values, and otherwise use the native keys/values
121
if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86
122
@registry_view = REGISTRY_VIEW_64_BIT
123
else
124
@registry_view = REGISTRY_VIEW_NATIVE
125
end
126
end
127
128
def run
129
print_status("Enumerating Excluded Paths for AV on #{sysinfo['Computer']}")
130
131
found = false
132
if datastore['DEFENDER'] && av_installed?(DEFENDER_BASE_KEY, DEFENDER)
133
found = true
134
excluded_defender
135
end
136
if datastore['ESSENTIALS'] && av_installed?(ESSENTIALS_BASE_KEY, ESSENTIALS)
137
found = true
138
excluded_mssec
139
end
140
if datastore['SEP'] && av_installed?(SEP_BASE_KEY, SEP)
141
found = true
142
excluded_sep
143
end
144
145
print_error 'No supported AV identified' unless found
146
end
147
end
148
149