Color shading for overlay files.

master
Ruben Bouman 2020-06-18 17:01:16 +02:00
parent f17cf9d0d0
commit 4c7ff2f095
5 changed files with 71 additions and 21 deletions

View File

@ -44,7 +44,7 @@ COLOR_DS_99p_HAPPY = '#689F38'
COLOR_DS_100p_HAPPY = '#33691E' COLOR_DS_100p_HAPPY = '#33691E'
# Detection colors (green range) # Detection colors (green range)
COLOR_D_0 = '#64B5F6' # Blue: Forensics/Context COLOR_D_0 = '#9C27B0' # Purple: Forensics/Context
COLOR_D_1 = '#DCEDC8' COLOR_D_1 = '#DCEDC8'
COLOR_D_2 = '#AED581' COLOR_D_2 = '#AED581'
COLOR_D_3 = '#8BC34A' COLOR_D_3 = '#8BC34A'
@ -57,6 +57,14 @@ COLOR_V_2 = '#64B5F6'
COLOR_V_3 = '#1976D2' COLOR_V_3 = '#1976D2'
COLOR_V_4 = '#0D47A1' COLOR_V_4 = '#0D47A1'
# Orange overlay colors
COLOR_O_0 = '#FEEED3'
COLOR_O_1 = '#FDE5BE'
COLOR_O_2 = '#FDDCA8'
COLOR_O_3 = '#FBCB7C'
COLOR_O_4 = '#FAB951'
COLOR_O_5 = '#F9A825'
COLOR_WHITE = '#FFFFFF' COLOR_WHITE = '#FFFFFF'
# Detection and visibility overlay color: # Detection and visibility overlay color:

View File

@ -246,10 +246,9 @@ def _menu(menu_parser):
# todo add search capabilities # todo add search capabilities
elif args.subparser in ['group', 'g']: elif args.subparser in ['group', 'g']:
if not 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.stage, args.platform,
args.software_group, args.search_visibility, args.search_detection, args.health, args.software_group, args.search_visibility, args.search_detection, args.health,
args.output_filename, args.layer_name, include_all_score_objs=args.all_scores): args.output_filename, args.layer_name, include_all_score_objs=args.all_scores)
quit() # something went wrong in executing the search or 0 results where returned
elif args.subparser in ['detection', 'd']: elif args.subparser in ['detection', 'd']:
if args.overlay: if args.overlay:

View File

@ -243,11 +243,27 @@ def get_layer_template_groups(name, max_count, description, stage, platform, ove
layer['legendItems'].append({'label': 'Src. of tech. is only software', 'color': COLOR_SOFTWARE}) layer['legendItems'].append({'label': 'Src. of tech. is only software', 'color': COLOR_SOFTWARE})
layer['legendItems'].append({'label': 'Src. of tech. is group(s)/overlay + software', 'color': COLOR_GROUP_AND_SOFTWARE}) layer['legendItems'].append({'label': 'Src. of tech. is group(s)/overlay + software', 'color': COLOR_GROUP_AND_SOFTWARE})
elif overlay_type == OVERLAY_TYPE_DETECTION: elif overlay_type == OVERLAY_TYPE_DETECTION:
layer['legendItems'].append({'label': 'Tech. in group + detection', 'color': COLOR_GROUP_OVERLAY_MATCH}) layer['legendItems'].append({'label': 'Tech. in group + detection score 0: Forensics/Context', 'color': COLOR_O_0})
layer['legendItems'].append({'label': 'Tech. in detection', 'color': COLOR_GROUP_OVERLAY_ONLY_DETECTION}) layer['legendItems'].append({'label': 'Tech. in group + detection score 1: Basic', 'color': COLOR_O_1})
layer['legendItems'].append({'label': 'Tech. in group + detection score 2: Fair', 'color': COLOR_O_2})
layer['legendItems'].append({'label': 'Tech. in group + detection score 3: Good', 'color': COLOR_O_3})
layer['legendItems'].append({'label': 'Tech. in group + detection score 4: Very good', 'color': COLOR_O_4})
layer['legendItems'].append({'label': 'Tech. in group + detection score 5: Excellent', 'color': COLOR_O_5})
layer['legendItems'].append({'label': 'Tech. in detection, score 0: Forensics/Context', 'color': COLOR_D_0})
layer['legendItems'].append({'label': 'Tech. in detection, score 1: Basic', 'color': COLOR_D_1})
layer['legendItems'].append({'label': 'Tech. in detection, score 2: Fair', 'color': COLOR_D_2})
layer['legendItems'].append({'label': 'Tech. in detection, score 3: Good', 'color': COLOR_D_3})
layer['legendItems'].append({'label': 'Tech. in detection, score 4: Very good', 'color': COLOR_D_4})
layer['legendItems'].append({'label': 'Tech. in detection, score 5: Excellent', 'color': COLOR_D_5})
elif overlay_type == OVERLAY_TYPE_VISIBILITY: elif overlay_type == OVERLAY_TYPE_VISIBILITY:
layer['legendItems'].append({'label': 'Tech. in group + visibility', 'color': COLOR_GROUP_OVERLAY_MATCH}) layer['legendItems'].append({'label': 'Tech. in group + visibility score 1: Minimal', 'color': COLOR_O_1})
layer['legendItems'].append({'label': 'Tech. in visibility', 'color': COLOR_GROUP_OVERLAY_ONLY_VISIBILITY}) layer['legendItems'].append({'label': 'Tech. in group + visibility score 2: Medium', 'color': COLOR_O_2})
layer['legendItems'].append({'label': 'Tech. in group + visibility score 3: Good', 'color': COLOR_O_3})
layer['legendItems'].append({'label': 'Tech. in group + visibility score 4: Excellent', 'color': COLOR_O_4})
layer['legendItems'].append({'label': 'Tech. in visibility, score 1: Minimal', 'color': COLOR_V_1})
layer['legendItems'].append({'label': 'Tech. in visibility, score 2: Medium', 'color': COLOR_V_2})
layer['legendItems'].append({'label': 'Tech. in visibility, score 3: Good', 'color': COLOR_V_3})
layer['legendItems'].append({'label': 'Tech. in visibility, score 4: Excellent', 'color': COLOR_V_4})
return layer return layer
@ -335,9 +351,16 @@ def get_layer_template_layered(name, description, stage, platform):
layer = _get_base_template(name, description, stage, platform, 0) layer = _get_base_template(name, description, stage, platform, 0)
layer['legendItems'] = \ layer['legendItems'] = \
[ [
{'label': 'Visibility', 'color': COLOR_OVERLAY_VISIBILITY}, {'label': 'Visibility and detection', 'color': COLOR_OVERLAY_BOTH},
{'label': 'Detection', 'color': COLOR_OVERLAY_DETECTION}, {'label': 'Visibility score 1: Minimal', 'color': COLOR_V_1},
{'label': 'Visibility and detection', 'color': COLOR_OVERLAY_BOTH} {'label': 'Visibility score 2: Medium', 'color': COLOR_V_2},
{'label': 'Visibility score 3: Good', 'color': COLOR_V_3},
{'label': 'Visibility score 4: Excellent', 'color': COLOR_V_4},
{'label': 'Detection score 1: Basic', 'color': COLOR_D_1},
{'label': 'Detection score 2: Fair', 'color': COLOR_D_2},
{'label': 'Detection score 3: Good', 'color': COLOR_D_3},
{'label': 'Detection score 4: Very good', 'color': COLOR_D_4},
{'label': 'Detection score 5: Excellent', 'color': COLOR_D_5}
] ]
return layer return layer
@ -710,7 +733,7 @@ def calculate_score(list_detections, zero_value=0):
number = 0 number = 0
for v in list_detections: for v in list_detections:
score = get_latest_score(v) score = get_latest_score(v)
if score and score >= 0: if score is not None and score >= 0:
avg_score += score avg_score += score
number += 1 number += 1

View File

@ -235,8 +235,8 @@ def _get_detection_techniques(filename):
groups_dict[group_id]['techniques'] = set() groups_dict[group_id]['techniques'] = set()
groups_dict[group_id]['weight'] = dict() groups_dict[group_id]['weight'] = dict()
for t, v in detection_techniques.items(): for t, v in detection_techniques.items():
s = calculate_score(v['detection']) s = calculate_score(v['detection'], zero_value=-1)
if s > 0: if s >= 0:
groups_dict[group_id]['techniques'].add(t) groups_dict[group_id]['techniques'].add(t)
groups_dict[group_id]['weight'][t] = 1 groups_dict[group_id]['weight'][t] = 1
@ -302,7 +302,10 @@ def _get_technique_count(groups, groups_overlay, groups_software, overlay_type,
dict_tech_score = {} dict_tech_score = {}
list_tech = groups_overlay[overlay_type.upper()]['techniques'] list_tech = groups_overlay[overlay_type.upper()]['techniques']
for tech in list_tech: for tech in list_tech:
dict_tech_score[tech] = calculate_score(all_techniques[tech][overlay_type]) + max_count if overlay_type == OVERLAY_TYPE_VISIBILITY:
dict_tech_score[tech] = calculate_score(all_techniques[tech]['visibility']) + max_count
elif overlay_type == OVERLAY_TYPE_DETECTION:
dict_tech_score[tech] = calculate_score(all_techniques[tech]['detection'], zero_value=-1) + max_count
for group, v in groups_overlay.items(): for group, v in groups_overlay.items():
for tech in v['techniques']: for tech in v['techniques']:
@ -388,15 +391,30 @@ def _get_technique_layer(techniques_count, groups, overlay, groups_software, ove
# Determine color: # Determine color:
if len(v['groups'].intersection(set(groups.keys()))) > 0: if len(v['groups'].intersection(set(groups.keys()))) > 0:
# if the technique is both present in the group (-g/--groups) and the groups overlay (-o/--overlay) # if the technique is both present in the group (-g/--groups) and the groups overlay (-o/--overlay)
t['color'] = COLOR_GROUP_OVERLAY_MATCH
metadata_dict['Group'].add(values['group_name']) metadata_dict['Group'].add(values['group_name'])
# determine the color of the overlay:
# - using groups, it's normal orange
# - using detections, it's 6 variations or orange (score 0 to 5)
# - using visibility, it's 4 variations of orange (score 1 to 4)
if overlay_file_type == FILE_TYPE_TECHNIQUE_ADMINISTRATION:
if overlay_type == OVERLAY_TYPE_VISIBILITY:
s = calculate_score(all_techniques[tech]['visibility'])
t['color'] = COLOR_O_1 if s == 1 else COLOR_O_2 if s == 2 else COLOR_O_3 if s == 3 else COLOR_O_4 if s == 4 else ''
elif overlay_type == OVERLAY_TYPE_DETECTION:
s = calculate_score(all_techniques[tech]['detection'], zero_value=-1)
t['color'] = COLOR_O_0 if s == 0 else COLOR_O_1 if s == 1 else COLOR_O_2 if s == 2 else COLOR_O_3 if s == 3 else COLOR_O_4 if s == 4 else COLOR_O_5 if s == 5 else ''
else:
t['color'] = COLOR_GROUP_OVERLAY_MATCH
else: else:
# the technique is only present in the overlay and not in the provided groups (-g/--groups) # the technique is only present in the overlay and not in the provided groups (-g/--groups)
if overlay_file_type == FILE_TYPE_TECHNIQUE_ADMINISTRATION: if overlay_file_type == FILE_TYPE_TECHNIQUE_ADMINISTRATION:
if overlay_type == OVERLAY_TYPE_VISIBILITY: if overlay_type == OVERLAY_TYPE_VISIBILITY:
t['color'] = COLOR_GROUP_OVERLAY_ONLY_VISIBILITY s = calculate_score(all_techniques[tech]['visibility'])
t['color'] = COLOR_V_1 if s == 1 else COLOR_V_2 if s == 2 else COLOR_V_3 if s == 3 else COLOR_V_4 if s == 4 else ''
elif overlay_type == OVERLAY_TYPE_DETECTION: elif overlay_type == OVERLAY_TYPE_DETECTION:
t['color'] = COLOR_GROUP_OVERLAY_ONLY_DETECTION s = calculate_score(all_techniques[tech]['detection'], zero_value=-1)
t['color'] = COLOR_D_0 if s == 0 else COLOR_D_1 if s == 1 else COLOR_D_2 if s == 2 else COLOR_D_3 if s == 3 else COLOR_D_4 if s == 4 else COLOR_D_5 if s == 5 else ''
else: else:
t['color'] = COLOR_GROUP_OVERLAY_NO_MATCH t['color'] = COLOR_GROUP_OVERLAY_NO_MATCH
if 'Groups' not in metadata_dict: if 'Groups' not in metadata_dict:

View File

@ -300,9 +300,11 @@ def _map_and_colorize_techniques_for_overlaid(my_techniques, my_data_sources, pl
if detection and visibility: if detection and visibility:
color = COLOR_OVERLAY_BOTH color = COLOR_OVERLAY_BOTH
elif detection and not visibility: elif detection and not visibility:
color = COLOR_OVERLAY_DETECTION s = detection_score
color = COLOR_D_0 if s == 0 else COLOR_D_1 if s == 1 else COLOR_D_2 if s == 2 else COLOR_D_3 if s == 3 else COLOR_D_4 if s == 4 else COLOR_D_5 if s == 5 else ''
elif not detection and visibility: elif not detection and visibility:
color = COLOR_OVERLAY_VISIBILITY s = visibility_score
color = COLOR_V_1 if s == 1 else COLOR_V_2 if s == 2 else COLOR_V_3 if s == 3 else COLOR_V_4 if s == 4 else ''
else: else:
color = COLOR_WHITE color = COLOR_WHITE