Removed support for PRE-ATT&CK from the Group mode
parent
b3705c782e
commit
94e8b5e4b5
|
@ -26,7 +26,7 @@ def generate_data_sources_layer(filename, output_filename, layer_name, platform=
|
|||
if not layer_name:
|
||||
layer_name = 'Data sources ' + name
|
||||
|
||||
layer = get_layer_template_data_sources(layer_name, 'description', 'attack', platform)
|
||||
layer = get_layer_template_data_sources(layer_name, 'description', platform)
|
||||
layer['techniques'] = my_techniques
|
||||
|
||||
json_string = simplejson.dumps(layer).replace('}, ', '},\n')
|
||||
|
|
26
dettect.py
26
dettect.py
|
@ -25,7 +25,7 @@ def _init_menu():
|
|||
'group, generic} --help', metavar='', dest='subparser')
|
||||
|
||||
parser_editor = subparsers.add_parser('editor', aliases=['e'], help='DeTT&CT Editor',
|
||||
description='Start the DeTT&CT Editor for easy editing the YAML administration files.')
|
||||
description='Start the DeTT&CT Editor for easy editing the YAML administration files')
|
||||
parser_editor.add_argument('-p', '--port', help='port where the webserver listens on (default is 8080)', required=False, default=8080)
|
||||
|
||||
# create the data source parser
|
||||
|
@ -69,9 +69,9 @@ def _init_menu():
|
|||
parser_data_sources.add_argument('-ln', '--layer-name', help='set the name of the Navigator layer')
|
||||
parser_data_sources.add_argument('--health', help='check the YAML file(s) for errors', action='store_true')
|
||||
parser_data_sources.add_argument('--local-stix-path', help='path to a local STIX repository to use DeTT&CT offline '
|
||||
'or to use a specific version of STIX objects.')
|
||||
'or to use a specific version of STIX objects')
|
||||
parser_data_sources.add_argument('--update-to-sub-techniques', help='Update the technique administration YAML file '
|
||||
'to ATT&CK with sub-techniques.', action='store_true')
|
||||
'to ATT&CK with sub-techniques', action='store_true')
|
||||
|
||||
# create the visibility parser
|
||||
parser_visibility = subparsers.add_parser('visibility', aliases=['v'],
|
||||
|
@ -107,9 +107,9 @@ def _init_menu():
|
|||
parser_visibility.add_argument('-ln', '--layer-name', help='set the name of the Navigator layer')
|
||||
parser_visibility.add_argument('--health', help='check the YAML file for errors', action='store_true')
|
||||
parser_visibility.add_argument('--local-stix-path', help='path to a local STIX repository to use DeTT&CT offline '
|
||||
'or to use a specific version of STIX objects.')
|
||||
'or to use a specific version of STIX objects')
|
||||
parser_visibility.add_argument('--update-to-sub-techniques', help='Update the technique administration YAML file '
|
||||
'to ATT&CK with sub-techniques.', action='store_true')
|
||||
'to ATT&CK with sub-techniques', action='store_true')
|
||||
|
||||
# create the detection parser
|
||||
parser_detection = subparsers.add_parser('detection', aliases=['d'],
|
||||
|
@ -147,9 +147,9 @@ def _init_menu():
|
|||
parser_detection.add_argument('-ln', '--layer-name', help='set the name of the Navigator layer')
|
||||
parser_detection.add_argument('--health', help='check the YAML file(s) for errors', action='store_true')
|
||||
parser_detection.add_argument('--local-stix-path', help='path to a local STIX repository to use DeTT&CT offline '
|
||||
'or to use a specific version of STIX objects.')
|
||||
'or to use a specific version of STIX objects')
|
||||
parser_detection.add_argument('--update-to-sub-techniques', help='Update the technique administration YAML file '
|
||||
'to ATT&CK with sub-techniques.', action='store_true')
|
||||
'to ATT&CK with sub-techniques', action='store_true')
|
||||
|
||||
# create the group parser
|
||||
parser_group = subparsers.add_parser('group', aliases=['g'],
|
||||
|
@ -159,7 +159,7 @@ def _init_menu():
|
|||
parser_group.add_argument('-g', '--groups', help='specify the ATT&CK Groups to include. Group can be its ID, '
|
||||
'name or alias (default is all groups). Multiple Groups can be '
|
||||
'provided with extra \'-g/--group\' arguments. Another option is '
|
||||
'to provide a YAML file with a custom group(s).',
|
||||
'to provide a YAML file with a custom group(s)',
|
||||
default=None, action='append')
|
||||
parser_group.add_argument('-o', '--overlay', help='specify what to overlay on the group(s) (provided using the '
|
||||
'arguments \-g/--groups\): group(s), visibility or detection. '
|
||||
|
@ -180,8 +180,6 @@ def _init_menu():
|
|||
'can be provided with extra \'-p/--platform\' arguments',
|
||||
choices=['all'] + list(PLATFORMS.values()), default=None, action='append',
|
||||
type=_platform_lookup())
|
||||
parser_group.add_argument('-s', '--stage', help='specify the stage (default = attack)',
|
||||
choices=['attack', 'pre-attack'], default='attack')
|
||||
parser_group.add_argument('-sd', '--search-detection', help='only include detection objects which match the '
|
||||
'provided EQL query')
|
||||
parser_group.add_argument('-sv', '--search-visibility', help='only include visibility objects which match the '
|
||||
|
@ -194,9 +192,9 @@ def _init_menu():
|
|||
parser_group.add_argument('-ln', '--layer-name', help='set the name of the Navigator layer')
|
||||
parser_group.add_argument('--health', help='check the YAML file(s) for errors', action='store_true')
|
||||
parser_group.add_argument('--local-stix-path', help='path to a local STIX repository to use DeTT&CT offline '
|
||||
'or to use a specific version of STIX objects.')
|
||||
'or to use a specific version of STIX objects')
|
||||
parser_group.add_argument('--update-to-sub-techniques', help='Update the technique administration YAML file '
|
||||
'to ATT&CK with sub-techniques.', action='store_true')
|
||||
'to ATT&CK with sub-techniques', action='store_true')
|
||||
|
||||
# create the generic parser
|
||||
parser_generic = subparsers.add_parser('generic', description='Generic functions which will output to stdout.',
|
||||
|
@ -216,7 +214,7 @@ def _init_menu():
|
|||
'date (default = modified)', choices=['modified', 'created'],
|
||||
default='modified')
|
||||
parser_generic.add_argument('--local-stix-path', help='path to a local STIX repository to use DeTT&CT offline '
|
||||
'or to use a specific version of STIX objects.')
|
||||
'or to use a specific version of STIX objects')
|
||||
|
||||
return menu_parser
|
||||
|
||||
|
@ -289,7 +287,7 @@ def _menu(menu_parser):
|
|||
|
||||
# TODO add search capabilities
|
||||
elif args.subparser in ['group', 'g']:
|
||||
generate_group_heat_map(args.groups, args.overlay, args.overlay_type, args.stage, args.platform,
|
||||
generate_group_heat_map(args.groups, args.overlay, args.overlay_type, args.platform,
|
||||
args.software_group, args.search_visibility, args.search_detection, args.health,
|
||||
args.output_filename, args.layer_name, include_all_score_objs=args.all_scores)
|
||||
|
||||
|
|
28
generic.py
28
generic.py
|
@ -206,13 +206,12 @@ def init_yaml():
|
|||
return _yaml
|
||||
|
||||
|
||||
def _get_base_template(name, description, stage, platform, sorting):
|
||||
def _get_base_template(name, description, platform, sorting):
|
||||
"""
|
||||
Prepares a base template for the json layer file that can be loaded into the MITRE ATT&CK Navigator.
|
||||
More information on the layer format can be found here: https://github.com/mitre/attack-navigator/blob/master/layers/
|
||||
:param name: name
|
||||
:param description: description
|
||||
:param stage: stage (act | prepare)
|
||||
:param platform: platform
|
||||
:param sorting: sorting
|
||||
:return: layer template dictionary
|
||||
|
@ -236,19 +235,18 @@ def _get_base_template(name, description, stage, platform, sorting):
|
|||
return layer
|
||||
|
||||
|
||||
def get_layer_template_groups(name, max_count, description, stage, platform, overlay_type):
|
||||
def get_layer_template_groups(name, max_count, description, platform, overlay_type):
|
||||
"""
|
||||
Prepares a base template for the json layer file that can be loaded into the MITRE ATT&CK Navigator.
|
||||
More information on the layer format can be found here: https://github.com/mitre/attack-navigator/blob/master/layers/
|
||||
:param name: name
|
||||
:param max_count: the sum of all count values
|
||||
:param description: description
|
||||
:param stage: stage (act | prepare)
|
||||
:param platform: platform
|
||||
:param overlay_type: group, visibility or detection
|
||||
:return: layer template dictionary
|
||||
"""
|
||||
layer = _get_base_template(name, description, stage, platform, 3)
|
||||
layer = _get_base_template(name, description, platform, 3)
|
||||
layer['gradient'] = {'colors': [COLOR_GRADIENT_MIN, COLOR_GRADIENT_MAX], 'minValue': 0, 'maxValue': max_count}
|
||||
layer['legendItems'] = []
|
||||
layer['legendItems'].append({'label': 'Tech. not often used', 'color': COLOR_GRADIENT_MIN})
|
||||
|
@ -285,17 +283,16 @@ def get_layer_template_groups(name, max_count, description, stage, platform, ove
|
|||
return layer
|
||||
|
||||
|
||||
def get_layer_template_detections(name, description, stage, platform):
|
||||
def get_layer_template_detections(name, description, platform):
|
||||
"""
|
||||
Prepares a base template for the json layer file that can be loaded into the MITRE ATT&CK Navigator.
|
||||
More information on the layer format can be found here: https://github.com/mitre/attack-navigator/blob/master/layers/
|
||||
:param name: name
|
||||
:param description: description
|
||||
:param stage: stage (act | prepare)
|
||||
:param platform: platform
|
||||
:return: layer template dictionary
|
||||
"""
|
||||
layer = _get_base_template(name, description, stage, platform, 0)
|
||||
layer = _get_base_template(name, description, platform, 0)
|
||||
layer['legendItems'] = \
|
||||
[
|
||||
{'label': 'Detection score 0: Forensics/Context', 'color': COLOR_D_0},
|
||||
|
@ -308,17 +305,16 @@ def get_layer_template_detections(name, description, stage, platform):
|
|||
return layer
|
||||
|
||||
|
||||
def get_layer_template_data_sources(name, description, stage, platform):
|
||||
def get_layer_template_data_sources(name, description, platform):
|
||||
"""
|
||||
Prepares a base template for the json layer file that can be loaded into the MITRE ATT&CK Navigator.
|
||||
More information on the layer format can be found here: https://github.com/mitre/attack-navigator/blob/master/layers/
|
||||
:param name: name
|
||||
:param description: description
|
||||
:param stage: stage (act | prepare)
|
||||
:param platform: platform
|
||||
:return: layer template dictionary
|
||||
"""
|
||||
layer = _get_base_template(name, description, stage, platform, 0)
|
||||
layer = _get_base_template(name, description, platform, 0)
|
||||
layer['legendItems'] = \
|
||||
[
|
||||
{'label': '1-25% of data sources available', 'color': COLOR_DS_25p},
|
||||
|
@ -330,17 +326,16 @@ def get_layer_template_data_sources(name, description, stage, platform):
|
|||
return layer
|
||||
|
||||
|
||||
def get_layer_template_visibility(name, description, stage, platform):
|
||||
def get_layer_template_visibility(name, description, platform):
|
||||
"""
|
||||
Prepares a base template for the json layer file that can be loaded into the MITRE ATT&CK Navigator.
|
||||
More information on the layer format can be found here: https://github.com/mitre/attack-navigator/blob/master/layers/
|
||||
:param name: name
|
||||
:param description: description
|
||||
:param stage: stage (act | prepare)
|
||||
:param platform: platform
|
||||
:return: layer template dictionary
|
||||
"""
|
||||
layer = _get_base_template(name, description, stage, platform, 0)
|
||||
layer = _get_base_template(name, description, platform, 0)
|
||||
layer['legendItems'] = \
|
||||
[
|
||||
{'label': 'Visibility score 1: Minimal', 'color': COLOR_V_1},
|
||||
|
@ -351,17 +346,16 @@ def get_layer_template_visibility(name, description, stage, platform):
|
|||
return layer
|
||||
|
||||
|
||||
def get_layer_template_layered(name, description, stage, platform):
|
||||
def get_layer_template_layered(name, description, platform):
|
||||
"""
|
||||
Prepares a base template for the json layer file that can be loaded into the MITRE ATT&CK Navigator.
|
||||
More information on the layer format can be found here: https://github.com/mitre/attack-navigator/blob/master/layers/
|
||||
:param name: name
|
||||
:param description: description
|
||||
:param stage: stage (act | prepare)
|
||||
:param platform: platform
|
||||
:return: layer template dictionary
|
||||
"""
|
||||
layer = _get_base_template(name, description, stage, platform, 0)
|
||||
layer = _get_base_template(name, description, platform, 0)
|
||||
layer['legendItems'] = \
|
||||
[
|
||||
{'label': 'Visibility and detection', 'color': COLOR_OVERLAY_BOTH},
|
||||
|
|
|
@ -44,19 +44,18 @@ def _are_groups_found(groups_found, argument_groups):
|
|||
if not group_id: # the group that has been provided through the command line cannot be found in ATT&CK
|
||||
print('[!] Unknown ATT&CK group: ' + group_arg)
|
||||
group_found = False
|
||||
elif group_id not in groups_found: # group not present in filtered data sate (i.e. platform and stage)
|
||||
elif group_id not in groups_found: # group not present in filtered (platform) data set
|
||||
print('[!] Group not part of the data set: ' + group_arg)
|
||||
group_found = False
|
||||
|
||||
return group_found
|
||||
|
||||
|
||||
def _get_software_techniques(groups, stage, platform):
|
||||
def _get_software_techniques(groups, platform):
|
||||
"""
|
||||
Get all techniques (in a dict) from the provided list of groups in relation to the software these groups use,
|
||||
and hence techniques they support.
|
||||
:param groups: ATT&CK groups
|
||||
:param stage: attack or pre-attack
|
||||
:param platform: one or multiple values from PLATFORMS constant
|
||||
:return: dictionary with info on groups
|
||||
"""
|
||||
|
@ -108,7 +107,7 @@ def _get_software_techniques(groups, stage, platform):
|
|||
# software matches the ATT&CK Matrix and platform
|
||||
# and the group is a group we are interested in
|
||||
if s['x_mitre_platforms']: # there is software that do not have a platform, skip those
|
||||
if s['matrix'] == 'mitre-' + stage and len(set(s['x_mitre_platforms']).intersection(set(platform))) > 0 and \
|
||||
if s['matrix'] == 'mitre-attack' and len(set(s['x_mitre_platforms']).intersection(set(platform))) > 0 and \
|
||||
(groups[0] == 'all' or s['group_id'].lower() in groups or _is_in_group(s['aliases'], groups)):
|
||||
if s['group_id'] not in groups_dict:
|
||||
groups_dict[s['group_id']] = {'group_name': s['name']}
|
||||
|
@ -149,11 +148,10 @@ def _generate_group_id(group_name, campaign):
|
|||
return CG_GROUPS[group_name + campaign]
|
||||
|
||||
|
||||
def _get_group_techniques(groups, stage, platform, file_type):
|
||||
def _get_group_techniques(groups, platform, file_type):
|
||||
"""
|
||||
Get all techniques (in a dict) from the provided list of groups
|
||||
:param groups: group ID, group name/alias or a YAML file with group(s) data
|
||||
:param stage: attack or pre-attack
|
||||
:param platform: one or multiple values from PLATFORMS constant
|
||||
:param file_type: the file type of the YAML file as present in the key 'file_type'
|
||||
:return: returns dictionary with all techniques from the provided list of groups or -1 when group is not found
|
||||
|
@ -196,7 +194,7 @@ def _get_group_techniques(groups, stage, platform, file_type):
|
|||
platforms = ['Windows']
|
||||
|
||||
# group matches the: matrix/stage, platform and the group(s) we are interested in
|
||||
if gr['matrix'] == 'mitre-' + stage and len(set(platforms).intersection(set(platform))) > 0 and \
|
||||
if gr['matrix'] == 'mitre-attack' and len(set(platforms).intersection(set(platform))) > 0 and \
|
||||
(groups[0] == 'all' or gr['group_id'].lower() in groups or _is_in_group(gr['aliases'], groups)):
|
||||
if gr['group_id'] not in groups_dict:
|
||||
groups_found.add(gr['group_id'])
|
||||
|
@ -477,7 +475,7 @@ def _get_group_list(groups, file_type):
|
|||
return groups
|
||||
|
||||
|
||||
def generate_group_heat_map(groups, overlay, overlay_type, stage, platform, software_groups, search_visibility,
|
||||
def generate_group_heat_map(groups, overlay, overlay_type, platform, software_groups, search_visibility,
|
||||
search_detection, health_is_called, output_filename, layer_name, include_all_score_objs=False):
|
||||
"""
|
||||
Calls all functions that are necessary for the generation of the heat map and write a json layer to disk.
|
||||
|
@ -485,7 +483,6 @@ def generate_group_heat_map(groups, overlay, overlay_type, stage, platform, soft
|
|||
:param overlay: group(s), visibility or detections to overlay (group ID, group name/alias, YAML file with
|
||||
group(s), detections or visibility)
|
||||
:param overlay_type: group, visibility or detection
|
||||
:param stage: attack or pre-attack
|
||||
:param platform: one or multiple the values from PLATFORMS constant or None (default = Windows)
|
||||
:param software_groups: specify if techniques from related software should be included
|
||||
:param search_visibility: visibility EQL search query
|
||||
|
@ -567,11 +564,11 @@ def generate_group_heat_map(groups, overlay, overlay_type, stage, platform, soft
|
|||
|
||||
# we are not overlaying visibility or detection, overlay group will therefore contain information on another group
|
||||
elif len(overlay) > 0:
|
||||
overlay_dict = _get_group_techniques(overlay, stage, platform, overlay_file_type)
|
||||
overlay_dict = _get_group_techniques(overlay, platform, overlay_file_type)
|
||||
if overlay_dict == -1:
|
||||
return None # returns None when the provided Group(s) to be overlaid, contains Groups not part of ATT&CK
|
||||
|
||||
groups_dict = _get_group_techniques(groups, stage, platform, groups_file_type)
|
||||
groups_dict = _get_group_techniques(groups, platform, groups_file_type)
|
||||
if groups_dict == -1:
|
||||
return None # returns None when the provided Group contains Groups not part of ATT&CK
|
||||
if len(groups_dict) == 0:
|
||||
|
@ -582,9 +579,9 @@ def generate_group_heat_map(groups, overlay, overlay_type, stage, platform, soft
|
|||
if software_groups and overlay:
|
||||
if overlay_type not in [OVERLAY_TYPE_VISIBILITY, OVERLAY_TYPE_DETECTION]:
|
||||
# if a group overlay is provided, get the software techniques for the overlay
|
||||
groups_software_dict = _get_software_techniques(overlay, stage, platform)
|
||||
groups_software_dict = _get_software_techniques(overlay, platform)
|
||||
elif software_groups:
|
||||
groups_software_dict = _get_software_techniques(groups, stage, platform)
|
||||
groups_software_dict = _get_software_techniques(groups, platform)
|
||||
|
||||
technique_count, max_count = _get_technique_count(groups_dict, overlay_dict, groups_software_dict, overlay_type, all_techniques)
|
||||
technique_layer = _get_technique_layer(technique_count, groups_dict, overlay_dict, groups_software_dict,
|
||||
|
@ -597,26 +594,24 @@ def generate_group_heat_map(groups, overlay, overlay_type, stage, platform, soft
|
|||
groups_list = _get_group_list(groups_dict, groups_file_type)
|
||||
overlay_list = _get_group_list(overlay_dict, overlay_file_type)
|
||||
|
||||
desc = 'stage: ' + stage + ' | platform(s): ' + platform_to_name(platform, separator=', ') + ' | group(s): ' \
|
||||
desc = 'stage: attack | platform(s): ' + platform_to_name(platform, separator=', ') + ' | group(s): ' \
|
||||
+ ', '.join(groups_list) + ' | overlay group(s): ' + ', '.join(overlay_list)
|
||||
|
||||
if not layer_name:
|
||||
layer_name = stage[0].upper() + stage[1:] + ' - ' + platform_to_name(platform, separator=', ')
|
||||
layer_name = 'Attack - ' + platform_to_name(platform, separator=', ')
|
||||
|
||||
layer = get_layer_template_groups(layer_name, max_count, desc, stage, platform, overlay_type)
|
||||
layer = get_layer_template_groups(layer_name, max_count, desc, platform, overlay_type)
|
||||
layer['techniques'] = technique_layer
|
||||
|
||||
json_string = simplejson.dumps(layer).replace('}, ', '},\n')
|
||||
|
||||
if not output_filename:
|
||||
if stage == 'pre-attack':
|
||||
filename = '_'.join(groups_list)
|
||||
elif overlay:
|
||||
if overlay:
|
||||
filename = platform_to_name(platform) + '_' + '_'.join(groups_list) + '-overlay_' + '_'.join(overlay_list)
|
||||
else:
|
||||
filename = platform_to_name(platform) + '_' + '_'.join(groups_list)
|
||||
|
||||
filename = create_output_filename(stage, filename)
|
||||
filename = create_output_filename('attack', filename)
|
||||
write_file(filename, json_string)
|
||||
else:
|
||||
write_file(output_filename, json_string)
|
||||
|
|
|
@ -7,7 +7,6 @@ from eql_yaml import *
|
|||
groups = 'all'
|
||||
software_group = False
|
||||
default_platform = ['Windows']
|
||||
default_stage = 'attack'
|
||||
default_matrix = 'enterprise'
|
||||
groups_overlay = ''
|
||||
overlay_type = 'group'
|
||||
|
@ -460,7 +459,7 @@ def _menu_groups():
|
|||
Prints and handles the Threat actor group mapping functionality.
|
||||
:return:
|
||||
"""
|
||||
global groups, software_group, default_platform, default_stage, groups_overlay, overlay_type, eql_all_scores, \
|
||||
global groups, software_group, default_platform, groups_overlay, overlay_type, eql_all_scores, \
|
||||
eql_query_detection, eql_query_visibility
|
||||
_clear()
|
||||
print('Menu: %s' % MENU_NAME_THREAT_ACTOR_GROUP_MAPPING)
|
||||
|
@ -468,12 +467,11 @@ def _menu_groups():
|
|||
print('Options:')
|
||||
print('1. Software group: %s' % str(software_group))
|
||||
print('2. Platform: %s' % ','.join(default_platform))
|
||||
print('3. Stage: %s' % default_stage)
|
||||
print('4. Groups: %s' % groups)
|
||||
print('5. Overlay: ')
|
||||
print('3. Groups: %s' % groups)
|
||||
print('4. Overlay: ')
|
||||
print(' - %s: %s' % ('File' if os.path.exists(groups_overlay) else 'Groups', groups_overlay))
|
||||
print(' - Type: %s' % overlay_type)
|
||||
print('6. EQL search: ')
|
||||
print('5. EQL search: ')
|
||||
eql_d_str = '' if not eql_query_detection else eql_query_detection
|
||||
eql_v_str = '' if not eql_query_visibility else eql_query_visibility
|
||||
print(' - Only include detection objects which match the EQL query: ' + eql_d_str)
|
||||
|
@ -481,7 +479,7 @@ def _menu_groups():
|
|||
print(' - Include all \'score\' objects from the \'score_logbook\' in the EQL search: ' + str(eql_all_scores))
|
||||
print('')
|
||||
print('Select what you want to do:')
|
||||
print('7. Generate a heat map layer.')
|
||||
print('6. Generate a heat map layer.')
|
||||
print('9. Back to main menu.')
|
||||
choice = _ask_input()
|
||||
if choice == '1':
|
||||
|
@ -491,15 +489,11 @@ def _menu_groups():
|
|||
p = _ask_input().lower()
|
||||
default_platform = [PLATFORMS[p]] if p in PLATFORMS.keys() else ['all']
|
||||
elif choice == '3':
|
||||
print('Specify stage (pre-attack, attack):')
|
||||
s = _ask_input().lower()
|
||||
default_stage = 'pre-attack' if s == 'pre-attack' else 'attack'
|
||||
elif choice == '4':
|
||||
print('Specify the groups to include separated using commas. Group can be their ID, name or alias '
|
||||
'(default is all groups). Other option is to provide a YAML file with a custom group(s)')
|
||||
g = _ask_input()
|
||||
groups = g if g != '' else 'all'
|
||||
elif choice == '5':
|
||||
elif choice == '4':
|
||||
print('')
|
||||
print('1. Overlay with groups.')
|
||||
print('2. Overlay with detections.')
|
||||
|
@ -521,7 +515,7 @@ def _menu_groups():
|
|||
elif choice == '4':
|
||||
overlay_type = ''
|
||||
groups_overlay = ''
|
||||
elif choice == '6':
|
||||
elif choice == '5':
|
||||
print('')
|
||||
print('1. Only include detection objects which match the EQL query: ' + eql_d_str)
|
||||
print('2. Only include visibility objects which match the EQL query: ' + eql_v_str)
|
||||
|
@ -537,8 +531,8 @@ def _menu_groups():
|
|||
elif choice == '3':
|
||||
eql_all_scores = not eql_all_scores
|
||||
|
||||
elif choice == '7':
|
||||
generate_group_heat_map(groups, groups_overlay, overlay_type, default_stage, default_platform,
|
||||
elif choice == '6':
|
||||
generate_group_heat_map(groups, groups_overlay, overlay_type, default_platform,
|
||||
software_group, eql_query_visibility, eql_query_detection, False,
|
||||
None, None, include_all_score_objs=eql_all_scores)
|
||||
_wait()
|
||||
|
|
|
@ -23,14 +23,14 @@ def generate_detection_layer(filename_techniques, filename_data_sources, overlay
|
|||
mapped_techniques_detection = _map_and_colorize_techniques_for_detections(my_techniques)
|
||||
if not layer_name:
|
||||
layer_name = 'Detections ' + name
|
||||
layer_detection = get_layer_template_detections(layer_name, 'description', 'attack', platform)
|
||||
layer_detection = get_layer_template_detections(layer_name, 'description', platform)
|
||||
_write_layer(layer_detection, mapped_techniques_detection, 'detection', name, output_filename)
|
||||
else:
|
||||
my_data_sources = _load_data_sources(filename_data_sources)
|
||||
mapped_techniques_both = _map_and_colorize_techniques_for_overlaid(my_techniques, my_data_sources, platform)
|
||||
if not layer_name:
|
||||
layer_name = 'Visibility and Detection ' + name
|
||||
layer_both = get_layer_template_layered(layer_name, 'description', 'attack', platform)
|
||||
layer_both = get_layer_template_layered(layer_name, 'description', platform)
|
||||
_write_layer(layer_both, mapped_techniques_both, 'visibility_and_detection', name, output_filename)
|
||||
|
||||
|
||||
|
@ -53,13 +53,13 @@ def generate_visibility_layer(filename_techniques, filename_data_sources, overla
|
|||
mapped_techniques_visibility = _map_and_colorize_techniques_for_visibility(my_techniques, my_data_sources, platform)
|
||||
if not layer_name:
|
||||
layer_name = 'Visibility ' + name
|
||||
layer_visibility = get_layer_template_visibility(layer_name, 'description', 'attack', platform)
|
||||
layer_visibility = get_layer_template_visibility(layer_name, 'description', platform)
|
||||
_write_layer(layer_visibility, mapped_techniques_visibility, 'visibility', name, output_filename)
|
||||
else:
|
||||
mapped_techniques_both = _map_and_colorize_techniques_for_overlaid(my_techniques, my_data_sources, platform)
|
||||
if not layer_name:
|
||||
layer_name = 'Visibility and Detection ' + name
|
||||
layer_both = get_layer_template_layered(layer_name, 'description', 'attack', platform)
|
||||
layer_both = get_layer_template_layered(layer_name, 'description', platform)
|
||||
_write_layer(layer_both, mapped_techniques_both, 'visibility_and_detection', name, output_filename)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue