def render_template(self, template_type): """Description template_type: - "markdown" """ if template_type not in ["markdown"]: raise Exception("Bad template_type. Available values:" + " [\"markdown\"]") template = env.get_template('markdown_responseaction_template.md.j2') self.ra_parsed_file.update( {'description': self.ra_parsed_file.get('description').strip()}) self.ra_parsed_file.update({ 'title': ATCutils.normalize_react_title(self.ra_parsed_file.get('title')) }) stage_list = [] stage = self.ra_parsed_file.get('stage') for rs_id, rs_name in rs_mapping.items(): if ATCutils.normalize_rs_name(stage) == rs_name: stage_list.append((rs_id, rs_name)) self.ra_parsed_file.update({'stage': stage_list}) self.ra_parsed_file.update({ 'category': ATCutils.get_ra_category(self.ra_parsed_file.get('id')) }) self.content = template.render(self.ra_parsed_file)
def render_template(self, template_type): """Description template_type: - "markdown" """ if template_type not in ["markdown"]: raise Exception("Bad template_type. Available values:" + " [\"markdown\"]") # Point to the templates directory env = Environment(loader=FileSystemLoader('scripts/templates')) template = env.get_template('markdown_responsestage_template.md.j2') self.ra_parsed_file.update( {'description': self.ra_parsed_file.get('description').strip()}) ras, ra_paths = ATCutils.load_yamls_with_paths( ATCconfig.get('response_actions_dir')) ra_filenames = [ ra_path.split('/')[-1].replace('.yml', '') for ra_path in ra_paths ] rs_id = self.ra_parsed_file.get('id') stage_list = [] for i in range(len(ras)): if rs_mapping[rs_id] == ATCutils.normalize_rs_name( ras[i].get('stage')): ra_id = ras[i].get('id') ra_filename = ra_filenames[i] ra_title = ATCutils.normalize_react_title(ras[i].get('title')) ra_description = ras[i].get('description').strip() stage_list.append( (ra_id, ra_filename, ra_title, ra_description)) self.ra_parsed_file.update({'stage_list': sorted(stage_list)}) self.content = template.render(self.ra_parsed_file)
def render_template(self, template_type): """Description template_type: - "markdown" """ if template_type not in ["markdown"]: raise Exception("Bad template_type. Available values:" + " [\"markdown\"]") # Point to the templates directory env = Environment(loader=FileSystemLoader('scripts/templates')) # Get proper template template = env.get_template('markdown_responseplaybook_template.md.j2') self.rp_parsed_file.update({ 'title': ATCutils.normalize_react_title(self.rp_parsed_file.get('title')) }) # 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}) 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') action_title = action.get('id')\ + ": "\ + ATCutils.normalize_react_title(action.get('title')) stage_list.append( (action_title, task, 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()}) # Render self.content = template.render(self.rp_parsed_file)
def __init__(self, ra=False, rp=False, rs=False, auto=False, ra_path=False, rp_path=False, rs_path=False, atc_dir=False, init=False): """Init""" # Check if atc_dir provided if atc_dir: self.atc_dir = atc_dir else: self.atc_dir = ATCconfig.get('md_name_of_root_directory') + '/' # Main logic if auto: self.response_action(ra_path) self.response_playbook(rp_path) self.response_stage(rs_path) if ra: self.response_action(ra_path) if rp: self.response_playbook(rp_path) if rs: self.response_stage(rs_path) if ra_path: ras, ra_paths = ATCutils.load_yamls_with_paths(ra_path) else: ras, ra_paths = ATCutils.load_yamls_with_paths( ATCconfig.get('response_actions_dir')) if rp_path: rps, rp_paths = ATCutils.load_yamls_with_paths(rp_path) else: rps, rp_paths = ATCutils.load_yamls_with_paths( ATCconfig.get('response_playbooks_dir')) if rs_path: rss, rs_paths = ATCutils.load_yamls_with_paths(rs_path) else: rss, rs_paths = ATCutils.load_yamls_with_paths( ATCconfig.get('response_stages_dir')) ra_filenames = [ ra_path.split('/')[-1].replace('.yml', '') for ra_path in ra_paths ] rp_filenames = [ rp_path.split('/')[-1].replace('.yml', '') for rp_path in rp_paths ] rs_filenames = [ rs_path.split('/')[-1].replace('.yml', '') for rs_path in rs_paths ] # Point to the templates directory env = Environment(loader=FileSystemLoader('scripts/templates')) # Get proper template template = env.get_template('mkdocs_config_template.md.j2') 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)] playbooks = [] data_to_render = {} for i in range(len(ras)): ra_updated_title = ras[i].get('id')\ + ": "\ + ATCutils.normalize_react_title(ras[i].get('title')) if "RA1" in ras[i]['id']: preparation.append((ra_updated_title, ra_filenames[i])) elif "RA2" in ras[i]['id']: identification.append((ra_updated_title, ra_filenames[i])) elif "RA3" in ras[i]['id']: containment.append((ra_updated_title, ra_filenames[i])) elif "RA4" in ras[i]['id']: eradication.append((ra_updated_title, ra_filenames[i])) elif "RA5" in ras[i]['id']: recovery.append((ra_updated_title, ra_filenames[i])) elif "RA6" in ras[i]['id']: lessons_learned.append((ra_updated_title, ra_filenames[i])) stages = [(stage_name.replace('_', ' ').capitalize(), sorted(stage_list)) for stage_name, stage_list in stages] for i in range(len(rps)): rp_updated_title = rps[i].get('id')\ + ": "\ + ATCutils.normalize_react_title(rps[i].get('title')) playbooks.append((rp_updated_title, rp_filenames[i])) rs_list = [] for i in range(len(rss)): rs_title = rss[i].get('title') rs_id = rss[i].get('id') rs_list.append((rs_title, rs_id)) data_to_render.update({'stages': stages}) data_to_render.update({'playbooks': sorted(playbooks)}) data_to_render.update({'rs_list': rs_list}) content = template.render(data_to_render) try: ATCutils.write_file('mkdocs.yml', content) print("[+] Created mkdocs.yml") except: print("[-] Failed to create mkdocs.yml")
def __init__(self, ra=False, rp=False, auto=False, ra_path=False, rp_path=False, atc_dir=False, init=False): """Init""" # Check if atc_dir provided if atc_dir: self.atc_dir = atc_dir else: self.atc_dir = ATCconfig.get('md_name_of_root_directory') + '/' # Main logic if auto: self.response_action(ra_path) self.response_playbook(rp_path) if ra: self.response_action(ra_path) if rp: self.response_playbook(rp_path) if ra_path: ras, ra_paths = ATCutils.load_yamls_with_paths(ra_path) else: ras, ra_paths = ATCutils.load_yamls_with_paths(ATCconfig.get('response_actions_dir')) if rp_path: rps, rp_paths = ATCutils.load_yamls_with_paths(rp_path) else: rps, rp_paths = ATCutils.load_yamls_with_paths(ATCconfig.get('response_playbooks_dir')) ra_filenames = [ra_path.split('/')[-1].replace('.yml', '') for ra_path in ra_paths] rp_filenames = [rp_path.split('/')[-1].replace('.yml', '') for rp_path in rp_paths] _preparation = [] _identification = [] _containment = [] _eradication = [] _recovery = [] _lessons_learned = [] stages = [ ('preparation', _preparation), ('identification', _identification), ('containment', _containment), ('eradication', _eradication), ('recovery', _recovery), ('lessons_learned', _lessons_learned) ] for i in range(len(ras)): normalized_title = ATCutils.normalize_react_title(ras[i].get('title')) ra_updated_title = ras[i].get('id')\ + ":"\ + normalized_title if "RA1" in ras[i]['id']: stage = 'preparation' elif "RA2" in ras[i]['id']: stage = 'identification' elif "RA3" in ras[i]['id']: stage = 'containment' elif "RA4" in ras[i]['id']: stage = 'eradication' elif "RA5" in ras[i]['id']: stage = 'recovery' elif "RA6" in ras[i]['id']: stage = 'lessons-learned' kill_chain_phases = [{ "kill_chain_name": 'atc-react', "phase_name": stage }] external_references = [{ "source_name": "atc-react", "external_id": ras[i].get('id'), "url": "https://atc-project.github.io/atc-react/Response_Actions/" + ra_filenames[i] }] ra = ReactAction( name=normalized_title, description=ras[i].get('description'), external_references=external_references, kill_chain_phases=kill_chain_phases, x_mitre_platforms=['Windows', 'Linux', 'macOS'], allow_custom=True ) stix_mem.add(ra) stix_mem.add( [ preparation, identification, containment, eradication, recovery, lessons_learned ]) stix_mem.add(react_matrix) try: stix_mem.save_to_file("docs/react.json") print("[+] Created react.json STIX file") except: print("[-] Failed to create react.json STIX file")