def render_template(self, template_type): """Description template_type: - "confluence" """ if template_type not in ["confluence"]: raise Exception("Bad template_type. Available value:" + " \"confluence\"]") # Get proper template template = env.get_template( 'confluence_responseaction_template.html.j2') new_title = self.ra_parsed_file.get('id')\ + ": "\ + ATCutils.normalize_react_title(self.ra_parsed_file.get('title')) self.ra_parsed_file.update({'title': new_title}) self.ra_parsed_file.update({ 'confluence_viewpage_url': ATCconfig.get('confluence_viewpage_url') }) ## ## Add link to a stage ## stage = self.ra_parsed_file.get('stage') rs_list = [] for rs_id, rs_name in rs_mapping.items(): if ATCutils.normalize_rs_name(stage) == rs_name: if self.apipath and self.auth and self.space: rs_confluence_page_id = str( ATCutils.confluence_get_page_id( self.apipath, self.auth, self.space, rs_name)) rs_list.append((rs_id, rs_name, rs_confluence_page_id)) else: rs_confluence_page_id = "" rs_list.append((rs_id, rs_name, rs_confluence_page_id)) break self.ra_parsed_file.update({'stage': rs_list}) # Category self.ra_parsed_file.update({ 'category': ATCutils.get_ra_category(self.ra_parsed_file.get('id')) }) self.ra_parsed_file.update( {'description': self.ra_parsed_file.get('description').strip()}) self.ra_parsed_file.update( {'workflow': self.ra_parsed_file.get('workflow')}) self.content = template.render(self.ra_parsed_file)
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') 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') 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') 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)
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_responseaction_template.md.j2') self.ra_parsed_file.update({ 'title': ATCutils.normalize_react_title( self.ra_parsed_file.get('title')) }) self.ra_parsed_file.update({ 'description': self.ra_parsed_file.get('description').strip() }) elif template_type == "confluence": template = env.get_template( 'confluence_responseaction_template.html.j2') new_title = self.ra_parsed_file.get('id')\ + ": "\ + ATCutils.normalize_react_title(self.ra_parsed_file.get('title')) self.ra_parsed_file.update({'title': new_title}) self.ra_parsed_file.update({ 'confluence_viewpage_url': ATCconfig.get('confluence_viewpage_url') }) linked_ra = self.ra_parsed_file.get("linked_ra") if linked_ra: linked_ra_with_id = [] for ra in linked_ra: if self.apipath and self.auth and self.space: linked_ra_id = str( ATCutils.confluence_get_page_id( self.apipath, self.auth, self.space, ra)) else: linked_ra_id = "" ra = (ra, linked_ra_id) linked_ra_with_id.append(ra) self.ra_parsed_file.update({'linkedra': linked_ra_with_id}) self.ra_parsed_file.update({ 'description': self.ra_parsed_file.get('description').strip() }) self.ra_parsed_file.update( {'workflow': self.ra_parsed_file.get('workflow')}) self.content = template.render(self.ra_parsed_file)
def render_template(self, template_type): """Description template_type: - "markdown" """ if template_type not in ["confluence"]: raise Exception("Bad template_type. Available values:" + " \"confluence\"]") template = env.get_template( 'confluence_responsestage_template.html.j2') self.rs_parsed_file.update( {'description': self.rs_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.rs_parsed_file.get('id') self.rs_parsed_file.update({ 'confluence_viewpage_url': ATCconfig.get('confluence_viewpage_url') }) 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() ra_confluence_page_name = ra_id + ": " + ra_title print(ra_confluence_page_name) if self.apipath and self.auth and self.space: ra_confluence_page_id = str( ATCutils.confluence_get_page_id( self.apipath, self.auth, self.space, ra_confluence_page_name)) else: ra_confluence_page_id = "" print(ra_confluence_page_id) stage_list.append((ra_id, ra_filename, ra_title, ra_description, ra_confluence_page_id)) new_title = self.rs_parsed_file.get('id')\ + ": "\ + ATCutils.normalize_react_title(self.rs_parsed_file.get('title')) self.rs_parsed_file.update({'title': new_title}) self.rs_parsed_file.update({'stage_list': sorted(stage_list)}) self.content = template.render(self.rs_parsed_file)