def load_yamls(path): yamls = [join(path, f) for f in listdir(path) if isfile( join(path, f)) if f.endswith('.yaml') or f.endswith('.yml')] result = [] for yaml in yamls: try: result.append(ATCutils.read_yaml_file(yaml)) except ScannerError: raise ScannerError('yaml is bad! %s' % yaml) return result, yamls
def parse_into_fields(self): """Description""" # self.fields contains parsed fields obtained from yaml file self.cu_fields = ATCutils.read_yaml_file(self.yaml_file) """Fill the fields with values. Put None if key not found""" self.title = self.cu_fields.get('title') self.customer_name = self.cu_fields.get('customer_name') self.description = self.cu_fields.get('description') self.data_needed = self.cu_fields.get('dataneeded') self.logging_policies = self.cu_fields.get('loggingpolicy') self.detection_rules = self.cu_fields.get('detectionrule')
def checkRA(self, stage): if self.rp_rule.get(stage): for rule in self.rp_rule.get(stage): try: rtask = ATCutils.read_yaml_file(self.inputRA + rule + ".yml") except OSError: print("Response Action %s not existing\n" % rule) continue self.task_prefix = int(self.task_prefix) self.task_prefix += 1 task = THC.TheHiveTask(order=self.task_order) self.task_order += 1 task.title = str(self.task_prefix) + " | " + \ str(rtask.get('title')) task.group = rtask.get('stage', 'Unknown stage') task.description = str(rtask.get('workflow')) self.case.tasks.append(task.return_dictionary()) if rtask.get('linked_ra'): self.task_prefix = float(self.task_prefix) for linked_ra in rtask.get('linked_ra'): try: rtask = ATCutils.read_yaml_file(self.inputRA + linked_ra + ".yml") except OSError: print("Response Action %s not existing\n" % rule) continue task = THC.TheHiveTask(order=self.task_order) self.task_order += 1 self.task_prefix += 0.1 task.title = str(round(self.task_prefix, 1)) + \ " | " + str(rtask.get('title')) task.title = str(round(self.task_prefix, 1)) + " | "\ + str(rtask.get("title")) task.group = rtask.get('stage', 'Unknown stage') task.description = str(rtask.get('workflow')) self.case.tasks.append(task.return_dictionary())
def parse_into_fields(self, yaml_file): """Description""" # self.dn_fields contains parsed fields obtained from yaml file self.dn_fields = ATCutils.read_yaml_file(yaml_file) """Fill the fields with values. Put None if key not found""" self.title = self.dn_fields.get("title") self.description = self.dn_fields.get("description") self.loggingpolicy = self.dn_fields.get("loggingpolicy") self.platform = self.dn_fields.get("platform") self.type = self.dn_fields.get("type") self.channel = self.dn_fields.get("channel") self.provider = self.dn_fields.get("provider") self.fields = self.dn_fields.get("fields") self.sample = self.dn_fields.get("sample")
def convertRPToTemplate(self, file_input, output_file): self.rp_rule = ATCutils.read_yaml_file(file_input) self.case = THC.TheHiveCase() self.case.name = self.rp_rule.get('title') self.case.description = "Description:\n" + \ str(self.rp_rule.get('description')) + \ '\n\nWorkflow:\n' + str(self.rp_rule.get('workflow')) try: self.case.tags += self.rp_rule.get('tags') except TypeError: pass self.case.tlp = self.checkTLP(self.rp_rule.get('tlp')) self.case.pap = self.checkPAP(self.rp_rule.get('pap')) if self.args.prefix: self.case.prefix = self.args.prefix self.task_prefix = 0.0 self.task_order = 0 stages = [ 'preparation', 'identification', 'containment', 'eradication', 'recovery', 'lessons_learned' ] for stage in stages: if stage in self.rp_rule.keys(): self.checkRA(stage) try: with open(output_file, 'w') as f: f.write(self.case.json()) except OSError: print("ERROR: No such directory %s" % os.path.dirname(os.path.abspath(output_file)))
def parse_into_fields(self, yaml_file): """Description""" self.ra_parsed_file = ATCutils.read_yaml_file(yaml_file)
def parse_into_fields(self): """Description""" # self.fields contains parsed fields obtained from yaml file self.fields = ATCutils.read_yaml_file(self.yaml_file)
if not args.vis_input: for file in os.listdir(dashboard_path): if not file.endswith((".yml", ".yaml")): continue YamlHandler(dashboard_path + file, output_path + file[:-4] + ".json", args.vis_force, args.vis_export_type) print("File path: %s" % (output_path + "_" + file[:-4] + ".json")) else: YamlHandler(args.vis_input, output_path2 + ".json", args.vis_force, args.vis_export_type) print("File path: %s" % (output_path2 + ".json")) elif args.thehive: ATCconfig = ATCutils.read_yaml_file("config.yml") ATCconfig2 = ATCutils.read_yaml_file("config.default.yml") print("HINT: Make sure proper directories are " + "configured in the config.yml") if ATCconfig.get( 'response_playbooks_dir', ATCconfig2.get('response_playbooks_dir')) and \ ATCconfig.get( 'response_actions_dir', ATCconfig2.get('response_actions_dir')) and \ ATCconfig.get( 'thehive_templates_dir', ATCconfig2.get('thehive_templates_dir')): RPTheHive( inputRP=ATCconfig.get( 'response_playbooks_dir',
def render_template(self, template_type): """Description template_type: - "markdown" - "confluence" """ if template_type not in ["markdown", "confluence"]: raise Exception("Bad template_type. Available values:" + " [\"markdown\", \"confluence\"]") # Point to the templates directory env = Environment(loader=FileSystemLoader('templates')) # Get proper template if template_type == "markdown": template = env.get_template( 'markdown_responseplaybook_template.md.j2') tactic = [] tactic_re = re.compile(r'attack\.\w\D+$') technique = [] technique_re = re.compile(r'attack\.t\d{1,5}$') other_tags = [] for tag in self.rp_parsed_file.get('tags'): if tactic_re.match(tag): tactic.append(ta_mapping.get(tag)) elif technique_re.match(tag): te = tag.upper()[7:] technique.append((te_mapping.get(te), te)) else: other_tags.append(tag) self.rp_parsed_file.update({'tactics': tactic}) self.rp_parsed_file.update({'techniques': technique}) self.rp_parsed_file.update({'other_tags': other_tags}) identification = [] containment = [] eradication = [] recovery = [] lessons_learned = [] stages = [('identification', identification), ('containment', containment), ('eradication', eradication), ('recovery', recovery), ('lessons_learned', lessons_learned)] # grab workflow per action in each IR stages # error handling for playbooks with empty stages for stage_name, stage_list in stages: try: for task in self.rp_parsed_file.get(stage_name): action = ATCutils.read_yaml_file( '../response_actions/' + task + '.yml') stage_list.append((action.get('description'), action.get('workflow'))) except TypeError: pass # change stages name to more pretty format stages = [(stage_name.replace('_', ' ').capitalize(), stage_list) for stage_name, stage_list in stages] self.rp_parsed_file.update({'stages': stages}) self.rp_parsed_file.update({ 'description': self.rp_parsed_file.get('description').strip() }) elif template_type == "confluence": template = env.get_template( 'confluence_responseplaybook_template.html.j2') self.rp_parsed_file.update({ 'confluence_viewpage_url': ATCconfig.get('confluence_viewpage_url') }) tactic = [] tactic_re = re.compile(r'attack\.\w\D+$') technique = [] technique_re = re.compile(r'attack\.t\d{1,5}$') other_tags = [] for tag in self.rp_parsed_file.get('tags'): if tactic_re.match(tag): tactic.append(ta_mapping.get(tag)) elif technique_re.match(tag): te = tag.upper()[7:] technique.append((te_mapping.get(te), te)) else: other_tags.append(tag) self.rp_parsed_file.update({'tactics': tactic}) self.rp_parsed_file.update({'techniques': technique}) self.rp_parsed_file.update({'other_tags': other_tags}) # get links to response action identification = [] containment = [] eradication = [] recovery = [] lessons_learned = [] stages = [('identification', identification), ('containment', containment), ('eradication', eradication), ('recovery', recovery), ('lessons_learned', lessons_learned)] for stage_name, stage_list in stages: try: for task in self.rp_parsed_file.get(stage_name): action = ATCutils.read_yaml_file( '../response_actions/' + task + '.yml') action_title = action.get('title') if self.apipath and self.auth and self.space: stage_list.append( (action_title, str( ATCutils.confluence_get_page_id( self.apipath, self.auth, self.space, action_title)))) else: stage_list.append((action_title, "")) except TypeError: pass # change stages name to more pretty format stages = [(stage_name.replace('_', ' ').capitalize(), stage_list) for stage_name, stage_list in stages] self.rp_parsed_file.update({'stages_with_id': stages}) # get descriptions for response actions identification = [] containment = [] eradication = [] recovery = [] lessons_learned = [] stages = [('identification', identification), ('containment', containment), ('eradication', eradication), ('recovery', recovery), ('lessons_learned', lessons_learned)] # grab workflow per action in each IR stages # error handling for playbooks with empty stages for stage_name, stage_list in stages: try: for task in self.rp_parsed_file.get(stage_name): action = ATCutils.read_yaml_file( '../response_actions/' + task + '.yml') stage_list.append((action.get('description'), action.get('workflow'))) except TypeError: pass # change stages name to more pretty format stages = [(stage_name.replace('_', ' ').capitalize(), stage_list) for stage_name, stage_list in stages] self.rp_parsed_file.update({'stages': stages}) self.rp_parsed_file.update( {'workflow': self.rp_parsed_file.get('workflow')}) self.rp_parsed_file.update({ 'description': self.rp_parsed_file.get('description').strip() }) # Render self.content = template.render(self.rp_parsed_file)
from enrichment import Enrichment from responseaction import ResponseAction from responseplaybook import ResponsePlaybook from pdb import set_trace as bp from attack_mapping import te_mapping, ta_mapping # Import ATC Utils from atcutils import ATCutils # Others import glob import sys import traceback import os ATCconfig = ATCutils.read_yaml_file("config.yml") class PopulateConfluence: """Desc""" def __init__(self, auth, lp=False, dn=False, dr=False, en=False, tg=False, ra=False, rp=False, auto=False, art_dir=False,
def parse_into_fields(self): """Description""" self.mp_parsed_file = ATCutils.read_yaml_file(self.yaml_file)
def main(c_auth=None): try: ATCconfig = ATCutils.read_yaml_file("config.yml") confluence_space_name = ATCconfig.get('confluence_space_name') confluence_space_home_page_name = ATCconfig.get( 'confluence_space_home_page_name') confluence_rest_api_url = ATCconfig.get('confluence_rest_api_url') confluence_name_of_root_directory = ATCconfig.get( 'confluence_name_of_root_directory') except Exception as e: raise e pass if not c_auth: mail = input("Login: "******"" print("Creating ATC page..") # print(str(ATCutils.confluence_get_page_id(url, # auth, confluence_space_name, confluence_space_home_page_name))) data = { "title": confluence_name_of_root_directory, "spacekey": confluence_space_name, "parentid": str( ATCutils.confluence_get_page_id(url, auth, confluence_space_name, confluence_space_home_page_name)), "confluencecontent": content, } # print(push_to_confluence(data, url, auth)) if not ATCutils.push_to_confluence(data, url, auth): raise Exception("Could not create or update the page. " + "Is the parent name correct?") spaces = [ "Detection Rules", "Logging Policies", "Data Needed", "Triggers", "Response Actions", "Response Playbooks", "Enrichments" ] for space in spaces: print("Creating %s.." % space) data = { "title": space, "spacekey": confluence_space_name, "parentid": str( ATCutils.confluence_get_page_id( url, auth, confluence_space_name, confluence_name_of_root_directory)), "confluencecontent": content, } # print(push_to_confluence(data, url, auth)) if not ATCutils.push_to_confluence(data, url, auth): raise Exception("Could not create or update the page. " + "Is the parent name correct?") print("Done!")
def render_template(self, template_type): """Description template_type: - "markdown" - "confluence" """ if template_type not in ["confluence"]: raise Exception("Bad template_type. Available values:" + " \"confluence\"]") # Point to the templates directory env = Environment(loader=FileSystemLoader('templates')) template = env.get_template( 'confluence_responseplaybook_template.html.j2') new_title = self.rp_parsed_file.get('id')\ + ": "\ + ATCutils.normalize_react_title(self.rp_parsed_file.get('title')) self.rp_parsed_file.update({'title': new_title}) self.rp_parsed_file.update({ 'confluence_viewpage_url': ATCconfig.get('confluence_viewpage_url') }) # MITRE ATT&CK Tactics and Techniques tactic = [] tactic_re = re.compile(r'attack\.\w\D+$') technique = [] technique_re = re.compile(r'attack\.t\d{1,5}$') # AM!TT Tactics and Techniques amitt_tactic = [] amitt_tactic_re = re.compile(r'amitt\.\w\D+$') amitt_technique = [] amitt_technique_re = re.compile(r'amitt\.t\d{1,5}$') other_tags = [] for tag in self.rp_parsed_file.get('tags'): if tactic_re.match(tag): tactic.append(ta_mapping.get(tag)) elif technique_re.match(tag): te = tag.upper()[7:] technique.append((te_mapping.get(te), te)) elif amitt_tactic_re.match(tag): amitt_tactic.append(amitt_tactic_mapping.get(tag)) elif amitt_technique_re.match(tag): te = tag.upper()[6:] amitt_technique.append((amitt_technique_mapping.get(te), te)) else: other_tags.append(tag) # Add MITRE ATT&CK Tactics and Techniques to J2 self.rp_parsed_file.update({'tactics': tactic}) self.rp_parsed_file.update({'techniques': technique}) # Add AM!TT Tactics and Techniques to J2 self.rp_parsed_file.update({'amitt_tactics': amitt_tactic}) self.rp_parsed_file.update({'amitt_techniques': amitt_technique}) self.rp_parsed_file.update({'other_tags': other_tags}) # get links to response action preparation = [] identification = [] containment = [] eradication = [] recovery = [] lessons_learned = [] detect = [] deny = [] disrupt = [] degrade = [] deceive = [] destroy = [] deter = [] stages = [('preparation', preparation), ('identification', identification), ('containment', containment), ('eradication', eradication), ('recovery', recovery), ('lessons_learned', lessons_learned), ('detect', detect), ('deny', deny), ('disrupt', disrupt), ('degrade', degrade), ('deceive', deceive), ('destroy', destroy), ('deter', deter)] for stage_name, stage_list in stages: try: for task in self.rp_parsed_file.get(stage_name): action = ATCutils.read_yaml_file( ATCconfig.get('response_actions_dir') + '/' + task + '.yml') action_title = action.get('id')\ + ": "\ + ATCutils.normalize_react_title(action.get('title')) if self.apipath and self.auth and self.space: stage_list.append((action_title, str( ATCutils.confluence_get_page_id( self.apipath, self.auth, self.space, action_title)))) else: stage_list.append((action_title, "")) except TypeError: pass # change stages name to more pretty format stages = [(stage_name.replace('_', ' ').capitalize(), stage_list) for stage_name, stage_list in stages] self.rp_parsed_file.update({'stages_with_id': stages}) # get descriptions for response actions preparation = [] identification = [] containment = [] eradication = [] recovery = [] lessons_learned = [] detect = [] deny = [] disrupt = [] degrade = [] deceive = [] destroy = [] deter = [] stages = [('preparation', preparation), ('identification', identification), ('containment', containment), ('eradication', eradication), ('recovery', recovery), ('lessons_learned', lessons_learned), ('detect', detect), ('deny', deny), ('disrupt', disrupt), ('degrade', degrade), ('deceive', deceive), ('destroy', destroy), ('deter', deter)] # grab workflow per action in each IR stages # error handling for playbooks with empty stages for stage_name, stage_list in stages: try: for task in self.rp_parsed_file.get(stage_name): action = ATCutils.read_yaml_file( ATCconfig.get('response_actions_dir') + '/' + task + '.yml') stage_list.append( (action.get('description'), action.get('workflow'))) except TypeError: pass # change stages name to more pretty format stages = [(stage_name.replace('_', ' ').capitalize(), stage_list) for stage_name, stage_list in stages] self.rp_parsed_file.update({'stages': stages}) self.rp_parsed_file.update( {'workflow': self.rp_parsed_file.get('workflow')}) self.rp_parsed_file.update( {'description': self.rp_parsed_file.get('description').strip()}) # Render self.content = template.render(self.rp_parsed_file)