CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/gather/enum_av_excluded.rb
Views: 11655
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 and
28
# perhaps https://github.com/rapid7/metasploit-framework/issues/6316
29
# are fixed
30
'SessionTypes' => [ 'meterpreter' ]
31
)
32
)
33
34
register_options(
35
[
36
OptBool.new('DEFENDER', [true, 'Enumerate exclusions for Microsoft Defender', true]),
37
OptBool.new('ESSENTIALS', [true, 'Enumerate exclusions for Microsoft Security Essentials/Antimalware', true]),
38
OptBool.new('SEP', [true, 'Enumerate exclusions for Symantec Endpoint Protection (SEP)', true])
39
]
40
)
41
end
42
43
DEFENDER = 'Windows Defender'
44
DEFENDER_BASE_KEY = 'HKLM\\SOFTWARE\\Microsoft\\Windows Defender'
45
ESSENTIALS = 'Microsoft Security Essentials / Antimalware'
46
ESSENTIALS_BASE_KEY = 'HKLM\\SOFTWARE\\Microsoft\\Microsoft Antimalware'
47
SEP = 'Symantec Endpoint Protection (SEP)'
48
SEP_BASE_KEY = 'HKLM\\SOFTWARE\\Symantec\\Symantec Endpoint Protection'
49
50
def av_installed?(base_key, product)
51
if registry_key_exist?(base_key)
52
print_good("Found #{product}")
53
true
54
else
55
false
56
end
57
end
58
59
def excluded_sep
60
base_exclusion_key = "#{SEP_BASE_KEY}\\Exclusions\\ScanningEngines\\Directory"
61
admin_exclusion_key = "#{base_exclusion_key}\\Admin"
62
client_exclusion_key = "#{base_exclusion_key}\\Client"
63
64
admin_paths = []
65
if (admin_exclusion_keys = registry_enumkeys(admin_exclusion_key, @registry_view))
66
admin_exclusion_keys.map do |key|
67
admin_paths << registry_getvaldata("#{admin_exclusion_key}\\#{key}", 'DirectoryName', @registry_view)
68
end
69
print_exclusions_table(SEP, 'admin path', admin_paths)
70
end
71
client_paths = []
72
if (client_exclusion_keys = registry_enumkeys(client_exclusion_key, @registry_view))
73
client_exclusion_keys.map do |key|
74
client_paths << registry_getvaldata("#{client_exclusion_key}\\#{key}", 'DirectoryName', @registry_view)
75
end
76
end
77
print_exclusions_table(SEP, 'client path', client_paths)
78
end
79
80
def excluded_defender
81
print_exclusions_table(DEFENDER, 'extension', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Extensions", @registry_view))
82
print_exclusions_table(DEFENDER, 'path', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Paths", @registry_view))
83
print_exclusions_table(DEFENDER, 'process', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Processes", @registry_view))
84
end
85
86
def excluded_mssec
87
print_exclusions_table(ESSENTIALS, 'extension', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Extensions", @registry_view))
88
print_exclusions_table(ESSENTIALS, 'path', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Paths", @registry_view))
89
print_exclusions_table(ESSENTIALS, 'process', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Processes", @registry_view))
90
end
91
92
def print_exclusions_table(product, exclusion_type, exclusions)
93
exclusions ||= []
94
exclusions = exclusions.compact.reject(&:blank?)
95
if exclusions.empty?
96
print_status("No #{exclusion_type} exclusions for #{product}")
97
return
98
end
99
table = Rex::Text::Table.new(
100
'Header' => "#{product} excluded #{exclusion_type.pluralize}",
101
'Indent' => 1,
102
'Columns' => [ exclusion_type.capitalize ]
103
)
104
exclusions.map { |exclusion| table << [exclusion] }
105
print_line(table.to_s)
106
end
107
108
def setup
109
unless datastore['DEFENDER'] || datastore['ESSENTIALS'] || datastore['SEP']
110
fail_with(Failure::BadConfig, 'Must set one or more of DEFENDER, ESSENTIALS or SEP to true')
111
end
112
113
# all of these target applications seemingly store their registry
114
# keys/values at the same architecture of the host, so if we happen to be
115
# in a 32-bit process on a 64-bit machine, ensure that we read from the
116
# 64-bit keys/values, and otherwise use the native keys/values
117
if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86
118
@registry_view = REGISTRY_VIEW_64_BIT
119
else
120
@registry_view = REGISTRY_VIEW_NATIVE
121
end
122
end
123
124
def run
125
print_status("Enumerating Excluded Paths for AV on #{sysinfo['Computer']}")
126
127
found = false
128
if datastore['DEFENDER'] && av_installed?(DEFENDER_BASE_KEY, DEFENDER)
129
found = true
130
excluded_defender
131
end
132
if datastore['ESSENTIALS'] && av_installed?(ESSENTIALS_BASE_KEY, ESSENTIALS)
133
found = true
134
excluded_mssec
135
end
136
if datastore['SEP'] && av_installed?(SEP_BASE_KEY, SEP)
137
found = true
138
excluded_sep
139
end
140
141
print_error 'No supported AV identified' unless found
142
end
143
end
144
145