Esempio n. 1
0
    def checkRA(self, stage):
        if self.rp_rule.get(stage):
            for rule in self.rp_rule.get(stage):
                try:
                    rtask = REACTutils.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) + " | "\
                    + rtask.get('id')\
                    + ": "\
                    + REACTutils.normalize_react_title(rtask.get('title'),REACTConfig.get('titlefmtrules'))

                if rtask.get('stage'):
                    task.group = REACTutils.normalize_rs_name(
                        rtask.get('stage'))
                else:
                    task.group = 'Unknown stage'

                task.description = str(rtask.get('workflow'))
                if rtask.get('owner'):
                    task.owner = str(rtask.get('owner'))
                self.case.tasks.append(task.return_dictionary())
Esempio n. 2
0
    def convertRPToTemplate(self, file_input, output_file):

        self.rp_rule = REACTutils.read_yaml_file(file_input)

        self.case = THC.TheHiveCase()
        self.case.name = self.rp_rule.get('id')\
            + ": "\
            + REACTutils.normalize_react_title(self.rp_rule.get('title'),REACTConfig.get('titlefmtrules'))

        self.case.description = str(self.rp_rule.get('description')) + \
            '\n\nWorkflow:\n\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)))
Esempio n. 3
0
     UpdateAttackMapping()
     ReactPopulateMarkdown(auto=args.auto, ra=args.responseactions,
                           rp=args.responseplaybook, rs=args.responsestage,
                           init=args.init)
     GenerateMkdocs()
     GenerateSTIX()
     GenerateNavigator()
 elif args.mkdocs:
     GenerateMkdocs()
 elif args.stix:
     GenerateSTIX()
 elif args.navigator:
     GenerateNavigator()
 elif args.thehive:
     UpdateAttackMapping()
     REACTConfig = REACTutils.read_yaml_file("config.yml")
     REACTConfig2 = REACTutils.read_yaml_file("scripts/config.default.yml")
     #print("HINT: Make sure proper directories are " +
     #      "configured in the scripts/config.yml")
     
     if REACTConfig.get(
             'response_playbooks_dir',
             REACTConfig2.get('response_playbooks_dir')) and \
             REACTConfig.get(
                 'response_actions_dir',
                 REACTConfig2.get('response_actions_dir')) and \
             REACTConfig.get(
                 'thehive_templates_dir',
                 REACTConfig2.get('thehive_templates_dir')):
         RPTheHive(
             inputRP=REACTConfig.get(
Esempio n. 4
0
    def parse_into_fields(self, yaml_file):
        """Description"""

        self.ra_parsed_file = REACTutils.read_yaml_file(yaml_file)
Esempio n. 5
0
    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\"]]")

        # Get proper template
        if template_type == "markdown":

            template = env.get_template(
                'markdown_responseplaybook_template.md.j2')

            self.rp_parsed_file.update({
                'title':
                REACTutils.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{4}(\.\d{3})?$')
            # 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 = REACTutils.read_yaml_file(
                            REACTConfig.get('response_actions_dir') + '/' +
                            task + '.yml')

                        action_title = action.get('id')\
                            + ": "\
                            + REACTutils.normalize_react_title(action.get('title'))

                        stage_list.append(
                            (action_title, task, action.get('description'),
                             action.get('workflow')))
                except TypeError:
                    pass

        elif template_type == "confluence":

            template = env.get_template(
                'confluence_responseplaybook_template.html.j2')

            new_title = self.rp_parsed_file.get('id')\
              + ": "\
              + REACTutils.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':
                REACTConfig.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{4}(\.\d{3})?$')
            # 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 = REACTutils.read_yaml_file(
                            REACTConfig.get('response_actions_dir') + '/' +
                            task + '.yml')

                        action_title = action.get('id')\
                            + ": "\
                            + REACTutils.normalize_react_title(action.get('title'))

                        if self.apipath and self.auth and self.space:
                            stage_list.append(
                                (action_title,
                                 str(
                                     REACTutils.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 = REACTutils.read_yaml_file(
                            REACTConfig.get('response_actions_dir') + '/' +
                            task + '.yml')
                        stage_list.append((action.get('description'),
                                           action.get('workflow')))
                except TypeError:
                    pass

        #
        # POST: Common for both Markdown and Confluence templates
        #

        # 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)