Land #6197, @jakxx's post module for enumerating AV exclusions
commit
3937c75d5f
|
@ -0,0 +1,141 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
include Msf::Post::Windows::Registry
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Windows Antivirus Exclusions Enumeration',
|
||||
'Description' => %q(
|
||||
This module will enumerate the file, directory, process and
|
||||
extension-based exclusions from supported AV products, which
|
||||
currently includes Microsoft Defender, Microsoft Security
|
||||
Essentials/Antimalware, and Symantec Endpoint Protection.
|
||||
),
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Andrew Smith', # original metasploit module
|
||||
'Jon Hart <jon_hart[at]rapid7.com>' # improved metasploit module
|
||||
],
|
||||
'Platform' => [ 'win' ],
|
||||
# XXX: this will work with 'shell' when the sysinfo parts are removed
|
||||
# and https://github.com/rapid7/metasploit-framework/issues/6328 and
|
||||
# perhaps https://github.com/rapid7/metasploit-framework/issues/6316
|
||||
# are fixed
|
||||
'SessionTypes' => [ 'meterpreter' ]
|
||||
)
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptBool.new('DEFENDER', [true, 'Enumerate exclusions for Microsoft Defender', true]),
|
||||
OptBool.new('ESSENTIALS', [true, 'Enumerate exclusions for Microsoft Security Essentials/Antimalware', true]),
|
||||
OptBool.new('SEP', [true, 'Enumerate exclusions for Symantec Endpoint Protection (SEP)', true])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
DEFENDER = 'Windows Defender'
|
||||
DEFENDER_BASE_KEY = 'HKLM\\SOFTWARE\\Microsoft\\Windows Defender'
|
||||
ESSENTIALS = 'Microsoft Security Essentials / Antimalware'
|
||||
ESSENTIALS_BASE_KEY = 'HKLM\\SOFTWARE\\Microsoft\\Microsoft Antimalware'
|
||||
SEP = 'Symantec Endpoint Protection (SEP)'
|
||||
SEP_BASE_KEY = 'HKLM\\SOFTWARE\\Symantec\\Symantec Endpoint Protection'
|
||||
|
||||
def av_installed?(base_key, product)
|
||||
if registry_key_exist?(base_key)
|
||||
print_good("Found #{product}")
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def excluded_sep
|
||||
base_exclusion_key = "#{SEP_BASE_KEY}\\Exclusions\\ScanningEngines\\Directory"
|
||||
admin_exclusion_key = "#{base_exclusion_key}\\Admin"
|
||||
client_exclusion_key = "#{base_exclusion_key}\\Client"
|
||||
|
||||
admin_paths = []
|
||||
if (admin_exclusion_keys = registry_enumkeys(admin_exclusion_key, @registry_view))
|
||||
admin_exclusion_keys.map do |key|
|
||||
admin_paths << registry_getvaldata("#{admin_exclusion_key}\\#{key}", 'DirectoryName', @registry_view)
|
||||
end
|
||||
print_exclusions_table(SEP, 'admin path', admin_paths)
|
||||
end
|
||||
client_paths = []
|
||||
if (client_exclusion_keys = registry_enumkeys(client_exclusion_key, @registry_view))
|
||||
client_exclusion_keys.map do |key|
|
||||
client_paths << registry_getvaldata("#{client_exclusion_key}\\#{key}", 'DirectoryName', @registry_view)
|
||||
end
|
||||
end
|
||||
print_exclusions_table(SEP, 'client path', client_paths)
|
||||
end
|
||||
|
||||
def excluded_defender
|
||||
print_exclusions_table(DEFENDER, 'extension', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Extensions", @registry_view))
|
||||
print_exclusions_table(DEFENDER, 'path', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Paths", @registry_view))
|
||||
print_exclusions_table(DEFENDER, 'process', registry_enumvals("#{DEFENDER_BASE_KEY}\\Exclusions\\Processes", @registry_view))
|
||||
end
|
||||
|
||||
def excluded_mssec
|
||||
print_exclusions_table(ESSENTIALS, 'extension', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Extensions", @registry_view))
|
||||
print_exclusions_table(ESSENTIALS, 'path', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Paths", @registry_view))
|
||||
print_exclusions_table(ESSENTIALS, 'process', registry_enumvals("#{ESSENTIALS_BASE_KEY}\\Exclusions\\Processes", @registry_view))
|
||||
end
|
||||
|
||||
def print_exclusions_table(product, exclusion_type, exclusions)
|
||||
exclusions ||= []
|
||||
exclusions = exclusions.compact.reject(&:blank?)
|
||||
if exclusions.empty?
|
||||
print_status("No #{exclusion_type} exclusions for #{product}")
|
||||
return
|
||||
end
|
||||
table = Rex::Ui::Text::Table.new(
|
||||
'Header' => "#{product} excluded #{exclusion_type.pluralize}",
|
||||
'Indent' => 1,
|
||||
'Columns' => [ exclusion_type.capitalize ]
|
||||
)
|
||||
exclusions.map { |exclusion| table << [exclusion] }
|
||||
print_line(table.to_s)
|
||||
end
|
||||
|
||||
def setup
|
||||
# all of these target applications seemingly store their registry
|
||||
# keys/values at the same architecture of the host, so if we happen to be
|
||||
# in a 32-bit process on a 64-bit machine, ensure that we read from the
|
||||
# 64-bit keys/values, and otherwise use the native keys/values
|
||||
@registry_view = sysinfo['Architecture'] =~ /WOW64/ ? REGISTRY_VIEW_64_BIT : REGISTRY_VIEW_NATIVE
|
||||
unless datastore['DEFENDER'] || datastore['ESSENTIALS'] || datastore['SEP']
|
||||
fail_with(Failure::BadConfig, 'Must set one or more of DEFENDER, ESSENTIALS or SEP to true')
|
||||
end
|
||||
end
|
||||
|
||||
def run
|
||||
print_status("Enumerating Excluded Paths for AV on #{sysinfo['Computer']}")
|
||||
|
||||
found = false
|
||||
if datastore['DEFENDER'] && av_installed?(DEFENDER_BASE_KEY, DEFENDER)
|
||||
found = true
|
||||
excluded_defender
|
||||
end
|
||||
if datastore['ESSENTIALS'] && av_installed?(ESSENTIALS_BASE_KEY, ESSENTIALS)
|
||||
found = true
|
||||
excluded_mssec
|
||||
end
|
||||
if datastore['SEP'] && av_installed?(SEP_BASE_KEY, SEP)
|
||||
found = true
|
||||
excluded_sep
|
||||
end
|
||||
|
||||
print_error "No supported AV identified" unless found
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue