adding new checks for file format limitations in capa explorer plugin

This commit is contained in:
Michael Hunhoff
2020-06-24 16:29:30 -06:00
parent 9842ae6c8f
commit 83dbf81d2b
2 changed files with 83 additions and 65 deletions

View File

@@ -32,8 +32,11 @@ from capa.ida.explorer.model import CapaExplorerDataModel
from capa.ida.explorer.proxy import CapaExplorerSortFilterProxyModel
PLUGIN_NAME = 'capaex'
PLUGIN_NAME = 'capa explorer'
SUPPORTED_FILE_TYPES = [
'Portable executable for 80386 (PE)',
]
logger = logging.getLogger(PLUGIN_NAME)
@@ -326,12 +329,15 @@ class CapaExplorerForm(idaapi.PluginForm):
rules_path = os.path.join(os.path.dirname(self._file_loc), '../..', 'rules')
rules = capa.main.get_rules(rules_path)
rules = capa.rules.RuleSet(rules)
results = capa.main.find_capabilities(rules, capa.features.extractors.ida.IdaFeatureExtractor(), True)
capabilities = capa.main.find_capabilities(rules, capa.features.extractors.ida.IdaFeatureExtractor(), True)
if capa.main.is_file_limitation(rules, capabilities):
idaapi.info('capa encountered warnings during analysis. Please refer to the IDA Output window for more information.')
logger.info('analysis completed.')
self._model_data.render_capa_results(rules, results)
self._render_capa_summary(rules, results)
self._model_data.render_capa_results(rules, capabilities)
self._render_capa_summary(rules, capabilities)
logger.info('render views completed.')
@@ -441,6 +447,15 @@ def main():
''' TODO: move to idaapi.plugin_t class '''
logging.basicConfig(level=logging.INFO)
if idaapi.get_file_type_name() not in SUPPORTED_FILE_TYPES:
logger.error('-' * 80)
logger.error(' Input file does not appear to be a PE file.')
logger.error(' ')
logger.error(' capa explorer currently only supports analyzing PE files.')
logger.error('-' * 80)
idaapi.info('capa does not support the format of this file. Please refer to the IDA output window for more information.')
return -1
global CAPA_EXPLORER_FORM
try:

View File

@@ -404,6 +404,65 @@ def appears_rule_cat(rules, capabilities, rule_cat):
return False
def is_file_limitation(rules, capabilities):
if appears_rule_cat(rules, capabilities, 'other-features/installer/'):
logger.warning('-' * 80)
logger.warning(' This sample appears to be an installer.')
logger.warning(' ')
logger.warning(' capa cannot handle installers well. This means the results may be misleading or incomplete.')
logger.warning(' You should try to understand the install mechanism and analyze created files with capa.')
logger.warning(' ')
logger.warning(' Use -v or -vv if you really want to see the capabilities identified by capa.')
logger.warning('-' * 80)
# capa will likely detect installer specific functionality.
# this is probably not what the user wants.
return True
if appears_rule_cat(rules, capabilities, 'other-features/compiled-to-dot-net'):
logger.warning('-' * 80)
logger.warning(' This sample appears to be a .NET module.')
logger.warning(' ')
logger.warning(' .NET is a cross-platform framework for running managed applications.')
logger.warning(
' capa cannot handle non-native files. This means that the results may be misleading or incomplete.')
logger.warning(' You may have to analyze the file manually, using a tool like the .NET decompiler dnSpy.')
logger.warning(' ')
logger.warning(' Use -v or -vv if you really want to see the capabilities identified by capa.')
logger.warning('-' * 80)
# capa won't detect much in .NET samples.
# it might match some file-level things.
# for consistency, bail on things that we don't support.
return True
if appears_rule_cat(rules, capabilities, 'other-features/compiled-with-autoit'):
logger.warning('-' * 80)
logger.warning(' This sample appears to be compiled with AutoIt.')
logger.warning(' ')
logger.warning(' AutoIt is a freeware BASIC-like scripting language designed for automating the Windows GUI.')
logger.warning(
' capa cannot handle AutoIt scripts. This means that the results will be misleading or incomplete.')
logger.warning(' You may have to analyze the file manually, using a tool like the AutoIt decompiler MyAut2Exe.')
logger.warning(' ')
logger.warning(' Use -v or -vv if you really want to see the capabilities identified by capa.')
logger.warning('-' * 80)
# capa will detect dozens of capabilities for AutoIt samples,
# but these are due to the AutoIt runtime, not the payload script.
# so, don't confuse the user with FP matches - bail instead
return True
if appears_rule_cat(rules, capabilities, 'anti-analysis/packing/'):
logger.warning('-' * 80)
logger.warning(' This sample appears packed.')
logger.warning(' ')
logger.warning(' Packed samples have often been obfuscated to hide their logic.')
logger.warning(' capa cannot handle obfuscation well. This means the results may be misleading or incomplete.')
logger.warning(' If possible, you should try to unpack this input file before analyzing it with capa.')
logger.warning('-' * 80)
return True
return False
def is_supported_file_type(sample):
'''
Return if this is a supported file based on magic header values
@@ -657,70 +716,12 @@ def main(argv=None):
capabilities = find_capabilities(rules, extractor)
if appears_rule_cat(rules, capabilities, 'other-features/installer/'):
logger.warning('-' * 80)
logger.warning(' This sample appears to be an installer.')
logger.warning(' ')
logger.warning(' capa cannot handle installers well. This means the results may be misleading or incomplete.')
logger.warning(' You should try to understand the install mechanism and analyze created files with capa.')
logger.warning(' ')
logger.warning(' Use -v or -vv if you really want to see the capabilities identified by capa.')
logger.warning('-' * 80)
# capa will likely detect installer specific functionality.
# this is probably not what the user wants.
#
if is_file_limitation(rules, capabilities):
# bail if capa encountered file limitation e.g. a packed binary
# do show the output in verbose mode, though.
if not (args.verbose or args.vverbose):
return -1
if appears_rule_cat(rules, capabilities, 'other-features/compiled-to-dot-net'):
logger.warning('-' * 80)
logger.warning(' This sample appears to be a .NET module.')
logger.warning(' ')
logger.warning(' .NET is a cross-platform framework for running managed applications.')
logger.warning(
' capa cannot handle non-native files. This means that the results may be misleading or incomplete.')
logger.warning(' You may have to analyze the file manually, using a tool like the .NET decompiler dnSpy.')
logger.warning(' ')
logger.warning(' Use -v or -vv if you really want to see the capabilities identified by capa.')
logger.warning('-' * 80)
# capa won't detect much in .NET samples.
# it might match some file-level things.
# for consistency, bail on things that we don't support.
#
# do show the output in verbose mode, though.
if not (args.verbose or args.vverbose):
return -1
if appears_rule_cat(rules, capabilities, 'other-features/compiled-with-autoit'):
logger.warning('-' * 80)
logger.warning(' This sample appears to be compiled with AutoIt.')
logger.warning(' ')
logger.warning(' AutoIt is a freeware BASIC-like scripting language designed for automating the Windows GUI.')
logger.warning(
' capa cannot handle AutoIt scripts. This means that the results will be misleading or incomplete.')
logger.warning(' You may have to analyze the file manually, using a tool like the AutoIt decompiler MyAut2Exe.')
logger.warning(' ')
logger.warning(' Use -v or -vv if you really want to see the capabilities identified by capa.')
logger.warning('-' * 80)
# capa will detect dozens of capabilities for AutoIt samples,
# but these are due to the AutoIt runtime, not the payload script.
# so, don't confuse the user with FP matches - bail instead
#
# do show the output in verbose mode, though.
if not (args.verbose or args.vverbose):
return -1
if appears_rule_cat(rules, capabilities, 'anti-analysis/packing/'):
logger.warning('-' * 80)
logger.warning(' This sample appears packed.')
logger.warning(' ')
logger.warning(' Packed samples have often been obfuscated to hide their logic.')
logger.warning(' capa cannot handle obfuscation well. This means the results may be misleading or incomplete.')
logger.warning(' If possible, you should try to unpack this input file before analyzing it with capa.')
logger.warning('-' * 80)
if args.vverbose:
render_capabilities_vverbose(capabilities)
elif args.verbose:
@@ -759,7 +760,9 @@ def ida_main():
import capa.features.extractors.ida
capabilities = find_capabilities(rules, capa.features.extractors.ida.IdaFeatureExtractor())
render_capabilities_default(rules, capabilities)
if not is_file_limitation(rules, capabilities):
render_capabilities_default(rules, capabilities)
def is_runtime_ida():