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())
Beispiel #2
0
def main(c_auth=None):

    try:
        REACTConfig = REACTutils.load_config("config.yml")
        confluence_space_name = REACTConfig.get('confluence_space_name')
        confluence_space_home_page_name = REACTConfig.get(
            'confluence_space_home_page_name')
        confluence_rest_api_url = REACTConfig.get('confluence_rest_api_url')
        confluence_name_of_root_directory = REACTConfig.get(
            'confluence_name_of_root_directory')

    except Exception as e:
        raise e
        pass

    if not c_auth:
        mail = input("Login: "******""

    print("[*] Creating RE&CT root page...")

    data = {
        "title": confluence_name_of_root_directory,
        "spacekey": confluence_space_name,
        "parentid": str(REACTutils.confluence_get_page_id(
            url, auth, confluence_space_name,
            confluence_space_home_page_name)),
        "confluencecontent": content,
    }

    if not REACTutils.push_to_confluence(data, url, auth):
        raise Exception("[-] Could not create or update the page. " +
                        "Is the parent name correct?")

    pages = ["Response Actions","Response Playbooks","Response Stages"]

    for page in pages:
        print("[*] Creating %s..." % page)
        data = {
            "title": page,
            "spacekey": confluence_space_name,
            "parentid": str(REACTutils.confluence_get_page_id(
                url, auth, confluence_space_name,
                confluence_name_of_root_directory)),
            "confluencecontent": content,
        }

        if not REACTutils.push_to_confluence(data, url, auth):
            raise Exception("[*] Could not create or update the page. " +
                            "Is the parent name correct?")
    print("[+] Initial Confluence page structure created!")
    return True
    def response_stage(self, rs_path):
        """Populate Response Stages"""

        print("[*] Populating Response Stages...")
        if rs_path:
            rs_list = glob.glob(rs_path + '*.yml')
        else:
            rs_dir = REACTConfig.get('response_stages_dir')
            rs_list = glob.glob(rs_dir + '/*.yml')

        for rs_file in rs_list:
            try:
                rs = ResponseStage(rs_file)
                rs.render_template("markdown")
                rs.save_markdown_file(atc_dir=self.atc_dir)
            except Exception as e:
                print(rs_file + " failed\n\n%s\n\n" % e)
                print("Err message: %s" % e)
                print('-' * 60)
                traceback.print_exc(file=sys.stdout)
                print('-' * 60)

        template = env.get_template('markdown_responsestage_main_template.j2')

        rss, rs_paths = REACTutils.load_yamls_with_paths(
            REACTConfig.get('response_stages_dir'))

        rs_filenames = [
            _rs_path.split('/')[-1].replace('.yml', '')
            for _rs_path in rs_paths
        ]

        rss_dict = {}
        rss_list = []

        for i in range(len(rss)):

            rs_title = rss[i].get('title')
            rs_id = rss[i].get('id')
            rs_description = rss[i].get('description')

            rss_list.append((rs_id, rs_title, rs_description))

        rss_dict.update({'rss_list': sorted(rss_list)})

        content = template.render(rss_dict)

        REACTutils.write_file(rs_summary_dir + '/responsestages.md', content)
        print("[+] Response Stages populated!")
    def __init__(self):

        UpdateReactMapping()

        response_actions = []
        for ra_id, ra_name in ra_mapping.items():
            ra_color = ""
            category_score = int(ra_id[3:6])
            ra_category = REACTutils.get_ra_category(ra_id)

            for category_name, category_color in category_colors.items():
                if ra_category == category_name:
                    ra_color = category_color
                    break

            response_actions.append({
                "techniqueID": ra_id,
                "color": ra_color,
                "score": category_score,        # for sorting
            })

        NAVIGATOR_TEMPLATE['techniques'] = response_actions

        with open(directory + '/' + filename, 'w') as fp:
            json.dump(NAVIGATOR_TEMPLATE, fp)
        print(f'[+] Created {filename}')
    def response_action(self, ra_path):
        """Nothing here yet"""

        print("[*] Populating Response Actions...")
        if ra_path:
            ra_list = glob.glob(ra_path + '*.yml')
        else:
            ra_dir = REACTConfig.get('response_actions_dir')
            ra_list = glob.glob(ra_dir + '/*.yml')

        for ra_file in ra_list:
            try:
                ra = ResponseAction(ra_file,
                                    apipath=self.apipath,
                                    auth=self.auth,
                                    space=self.space)
                ra.render_template("confluence")

                confluence_data = {
                    "title":
                    ra.ra_parsed_file['title'],
                    "spacekey":
                    self.space,
                    "parentid":
                    str(
                        REACTutils.confluence_get_page_id(
                            self.apipath, self.auth, self.space,
                            "Response Actions")),
                    "confluencecontent":
                    ra.content,
                }

                res = REACTutils.push_to_confluence(confluence_data,
                                                    self.apipath, self.auth)
                if res == 'Page updated':
                    print("==> updated page: RA '" +
                          ra.ra_parsed_file['title'] + "'")
                # print("Done: ", ra.ra_parsed_file['title'])
            except Exception as err:
                print(ra_file + " failed")
                print("Err message: %s" % err)
                print('-' * 60)
                traceback.print_exc(file=sys.stdout)
                print('-' * 60)

        print("[+] Response Actions populated!")
Beispiel #6
0
    def save_markdown_file(self, atc_dir=REACTConfig.get('md_name_of_root_directory')):
        """Write content (md template filled with data) to a file"""

        base = os.path.basename(self.yaml_file)
        title = os.path.splitext(base)[0]

        file_path = atc_dir + self.parent_title + "/" + \
            title + ".md"

        return REACTutils.write_file(file_path, self.content)
Beispiel #7
0
def react_create_markdown_dirs():
    REACTConfig = REACTutils.load_config('config.yml')
    base_dir = Path(REACTConfig.get('md_name_of_root_directory', '../docs'))

    target_dir_list = [
        'Response_Actions', 'Response_Playbooks', 'Response_Stages'
    ]

    for item in target_dir_list:
        (base_dir / item).mkdir(parents=True, exist_ok=True)
    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)))
Beispiel #9
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(
Beispiel #10
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\"]")

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

        self.ra_parsed_file.update(
            {'category': REACTutils.get_ra_category(self.ra_parsed_file
                .get('id'))}
        )

        self.ra_parsed_file.update(
            {'description': self.ra_parsed_file.get('description').strip()}
        )

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

            template = env.get_template(
                'markdown_responseaction_template.md.j2'
            )
    
            self.ra_parsed_file.update(
                {'title': REACTutils.normalize_react_title(self.ra_parsed_file
                    .get('title'),REACTConfig.get('titlefmtrules'))}
            )
    
            stage_list = []
            stage = self.ra_parsed_file.get('stage')
    
            for rs_id, rs_name in rs_mapping.items():
                if REACTutils.normalize_rs_name(stage) == rs_name:
                    stage_list.append((rs_id, rs_name))
    
            self.ra_parsed_file.update(
                {'stage': stage_list}
            )

        elif template_type == "confluence":

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

            new_title = self.ra_parsed_file.get('id')\
                + ": "\
                + REACTutils.normalize_react_title(self.ra_parsed_file.get('title'),REACTConfig.get('titlefmtrules'))

            self.ra_parsed_file.update(
                {'title': new_title}
            )

            self.ra_parsed_file.update(
                {'confluence_viewpage_url': REACTConfig.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 REACTutils.normalize_rs_name(stage) == rs_name:
                    if self.apipath and self.auth and self.space:
                        rs_confluence_page_name = rs_id + ": " + rs_name
                        rs_confluence_page_id = str(REACTutils.confluence_get_page_id(
                            self.apipath, self.auth, self.space, rs_confluence_page_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}
            )

        #
        # POST: Common for both Markdown and Confluence templates
        #
        self.content = template.render(self.ra_parsed_file)
Beispiel #11
0
    def parse_into_fields(self, yaml_file):
        """Description"""

        self.ra_parsed_file = REACTutils.read_yaml_file(yaml_file)
Beispiel #12
0
#!/usr/bin/env python3

from jinja2 import Environment, FileSystemLoader
import os

try:
    from scripts.reactutils import REACTutils
    from scripts.react_mapping import rs_mapping
    env = Environment(loader=FileSystemLoader('scripts/templates'))
except:
    from response.atc_react.scripts.reactutils import REACTutils
    from response.atc_react.scripts.react_mapping import rs_mapping
    env = Environment(loader=FileSystemLoader(
        'response/atc_react/scripts/templates'))

REACTConfig = REACTutils.load_config("config.yml")


class ResponseAction:
    """Class for the Playbook Actions entity"""

    def __init__(self, yaml_file, apipath=None, auth=None, space=None):
        """Init method"""

        # Init vars
        self.yaml_file = yaml_file
        self.apipath = apipath
        self.auth = auth
        self.space = space
        # The name of the directory containing future markdown Response_Actions
        self.parent_title = "Response_Actions"
Beispiel #13
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)
    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 = REACTConfig.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 = REACTutils.load_yamls_with_paths(ra_path)
        else:
            ras, ra_paths = REACTutils.load_yamls_with_paths(
                REACTConfig.get('response_actions_dir'))

        if rp_path:
            rps, rp_paths = REACTutils.load_yamls_with_paths(rp_path)
        else:
            rps, rp_paths = REACTutils.load_yamls_with_paths(
                REACTConfig.get('response_playbooks_dir'))

        if rs_path:
            rss, rs_paths = REACTutils.load_yamls_with_paths(rs_path)
        else:
            rss, rs_paths = REACTutils.load_yamls_with_paths(
                REACTConfig.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')\
                + ": "\
                + REACTutils.normalize_react_title(ras[i].get('title'),REACTConfig.get('titlefmtrules'))

            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')\
                + ": "\
                + REACTutils.normalize_react_title(rps[i].get('title'),REACTConfig.get('titlefmtrules'))

            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:
            REACTutils.write_file('mkdocs.yml', content)
            print("[+] Created mkdocs.yml")
        except:
            print("[-] Failed to create mkdocs.yml")
Beispiel #15
0
    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 = REACTConfig.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 = REACTutils.load_yamls_with_paths(ra_path)
        else:
            ras, ra_paths = REACTutils.load_yamls_with_paths(
                REACTConfig.get('response_actions_dir'))

        if rp_path:
            rps, rp_paths = REACTutils.load_yamls_with_paths(rp_path)
        else:
            rps, rp_paths = REACTutils.load_yamls_with_paths(
                REACTConfig.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 = REACTutils.normalize_react_title(
                ras[i].get('title'), REACTConfig.get('titlefmtrules'))

            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":
                react_web_kb_base_url + "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(local_react_json_url)
            print("[+] Created react.json STIX file")
        except:
            print("[-] Failed to create react.json STIX file")
    def response_stage(self, rs_path):
        """Nothing here yet"""

        print("[*] Populating Response Stages...")
        if rs_path:
            rs_list = glob.glob(rs_path + '*.yml')
        else:
            rs_dir = REACTConfig.get('response_stages_dir')
            rs_list = glob.glob(rs_dir + '/*.yml')

        for rs_file in rs_list:
            try:
                rs = ResponseStage(rs_file,
                                   apipath=self.apipath,
                                   auth=self.auth,
                                   space=self.space)
                rs.render_template("confluence")

                base = os.path.basename(rs_file)

                confluence_data = {
                    "title":
                    rs.rs_parsed_file['title'],
                    "spacekey":
                    self.space,
                    "parentid":
                    str(
                        REACTutils.confluence_get_page_id(
                            self.apipath, self.auth, self.space,
                            "Response Stages")),
                    "confluencecontent":
                    rs.content,
                }

                res = REACTutils.push_to_confluence(confluence_data,
                                                    self.apipath, self.auth)
                if res == 'Page updated':
                    print("==> updated page: RS '" + base + "'")
            except Exception as err:
                print(rs_file + " failed")
                print("Err message: %s" % err)
                print('-' * 60)
                traceback.print_exc(file=sys.stdout)
                print('-' * 60)

        #
        # Populate Response Stages root page
        #

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

        rss, rs_paths = REACTutils.load_yamls_with_paths(
            REACTConfig.get('response_stages_dir'))

        rss_dict = {}
        rss_list = []

        for i in range(len(rss)):
            rs_id = rss[i].get('id')
            rs_title = rss[i].get('title')
            rs_confluence_page_name = rs_id + ": " + rs_title
            rs_confluence_page_id = str(
                REACTutils.confluence_get_page_id(self.apipath, self.auth,
                                                  self.space,
                                                  rs_confluence_page_name))
            rs_description = rss[i].get('description')

            rss_list.append(
                (rs_id, rs_title, rs_description, rs_confluence_page_id))

        rss_dict.update({'rss_list': sorted(rss_list)})
        rss_dict.update({
            'confluence_viewpage_url':
            REACTConfig.get('confluence_viewpage_url')
        })

        content = template.render(rss_dict)

        try:
            data = {
                "title":
                "Response Stages",
                "spacekey":
                self.space,
                "parentid":
                str(
                    REACTutils.confluence_get_page_id(self.apipath, self.auth,
                                                      self.space,
                                                      self.root_name)),
                "confluencecontent":
                content,
            }

            res = REACTutils.push_to_confluence(data, self.apipath, self.auth)
            if res == 'Page updated':
                print("==> updated page: Response Stages root page")
        except Exception as err:
            print("Response Stages root page" + " failed")
            print("Err message: %s" % err)
            print('-' * 60)
            traceback.print_exc(file=sys.stdout)
            print('-' * 60)

        print("[+] Response Stages populated!")