def test(self, test_file):
        # read test file
        test_file = self.load_file(test_file)

        # build attack range
        self.build()

        # simulate attack
        self.simulate(test_file['target'], test_file['simulation_technique'])

        # wait
        self.log.info('Wait for 500 seconds before running the detections.')
        time.sleep(500)

        # run detection
        result = []

        for detection_obj in test_file['detections']:
            detection_file_name = detection_obj['name'].replace(
                '-', '_').replace(' ', '_').lower() + '.yml'
            detection = self.load_file('../security-content/detections/' +
                                       detection_file_name)
            result_obj = dict()
            result_obj['detection'] = detection_obj['name']
            instance = aws_service.get_instance_by_name(
                "attack-range-splunk-server", self.config)
            if instance['State']['Name'] == 'running':
                result_obj['error'], result_obj[
                    'results'] = splunk_sdk.test_search(
                        instance['NetworkInterfaces'][0]
                        ['Association']['PublicIp'],
                        str(self.config['splunk_admin_password']),
                        detection['search'], detection_obj['pass_condition'],
                        detection['name'], self.log)
            else:
                self.log.error('ERROR: Splunk server is not running.')
            result.append(result_obj)

        #print(result)

        # store attack data
        if self.config['capture_attack_data'] == '1':
            self.store_attack_data(result, test_file)

        # destroy attack range
        self.destroy()

        #result_cond = False
        for result_obj in result:
            if result_obj['error']:
                self.log.error('Detection Testing failed: ' +
                               result_obj['results']['detection_name'])
                if self.config['automated_testing'] == '1':
                    github_service.create_issue(
                        result_obj['results']['detection_name'], self.config)
            #result_cond |= result_obj['error']
        sys.exit(0)
Ejemplo n.º 2
0
    def test(self, test_file):
        # read test file
        test_file = self.load_file(test_file)

        # build attack range
        self.build()

        random_number = str(randrange(10000))
        folder_name = "attack_data_" + random_number
        os.mkdir(
            os.path.join(os.path.dirname(__file__),
                         '../attack_data/' + folder_name))

        simulation = False
        output = 'loaded attack data'
        if 'attack_data' in test_file:
            for data in test_file['attack_data']:
                dumps_yml = self.load_file(
                    os.path.join(os.path.dirname(__file__),
                                 '../attack_data/dumps.yml'))

                url = data['data']
                r = requests.get(url, allow_redirects=True)
                open(
                    os.path.join(
                        os.path.dirname(__file__), '../attack_data/' +
                        folder_name + '/' + data['file_name']),
                    'wb').write(r.content)

                if self.config['cloud_provider'] == 'aws':
                    splunk_ip = aws_service.get_single_instance_public_ip(
                        'ar-splunk-' + self.config['range_name'] + '-' +
                        self.config['key_name'], self.config)
                elif self.config['cloud_provider'] == 'azure':
                    splunk_ip = azure_service.get_instance(
                        self.config, "ar-splunk-" + self.config['range_name'] +
                        "-" + self.config['key_name'], self.log)['public_ip']

                # Upload the replay logs to the Splunk server
                ansible_vars = {}
                ansible_vars['dump_name'] = folder_name
                ansible_vars['ansible_user'] = '******'
                ansible_vars['ansible_ssh_private_key_file'] = self.config[
                    'private_key_path']
                ansible_vars['splunk_password'] = self.config[
                    'attack_range_password']
                ansible_vars['out'] = data['file_name']
                ansible_vars['sourcetype'] = data['sourcetype']
                ansible_vars['source'] = data['source']
                ansible_vars['index'] = 'test'

                cmdline = "-i %s, -u ubuntu" % (splunk_ip)
                runner = ansible_runner.run(
                    private_data_dir=os.path.join(os.path.dirname(__file__),
                                                  '../'),
                    cmdline=cmdline,
                    roles_path=os.path.join(os.path.dirname(__file__),
                                            '../ansible/roles'),
                    playbook=os.path.join(
                        os.path.dirname(__file__),
                        '../ansible/playbooks/attack_replay.yml'),
                    extravars=ansible_vars)

        else:
            simulation = True

        # update ESCU
        if self.config['update_escu_app'] == '1':
            # upload package
            if self.config['cloud_provider'] == 'aws':
                splunk_ip = aws_service.get_single_instance_public_ip(
                    'ar-splunk-' + self.config['range_name'] + '-' +
                    self.config['key_name'], self.config)
            elif self.config['cloud_provider'] == 'azure':
                splunk_ip = azure_service.get_instance(
                    self.config, "ar-splunk-" + self.config['range_name'] +
                    "-" + self.config['key_name'], self.log)['public_ip']
            # Upload the replay logs to the Splunk server
            ansible_vars = {}
            ansible_vars['ansible_user'] = '******'
            ansible_vars['ansible_ssh_private_key_file'] = self.config[
                'private_key_path']
            ansible_vars['splunk_password'] = self.config[
                'attack_range_password']
            ansible_vars['security_content_path'] = self.config[
                'security_content_path']

            cmdline = "-i %s, -u ubuntu" % (splunk_ip)
            runner = ansible_runner.run(
                private_data_dir=os.path.join(os.path.dirname(__file__),
                                              '../'),
                cmdline=cmdline,
                roles_path=os.path.join(os.path.dirname(__file__),
                                        '../ansible/roles'),
                playbook=os.path.join(os.path.dirname(__file__),
                                      '../ansible/playbooks/update_escu.yml'),
                extravars=ansible_vars)

        if simulation:

            # wait
            self.log.info('Wait for 200 seconds before running simulations.')
            time.sleep(200)

            # simulate attack
            # create vars string for custom vars:
            if 'vars' in test_file:
                var_str = '$myArgs = @{ '
                i = 0
                for key, value in test_file['vars'].items():
                    if i == 0:
                        var_str += '"' + key + '" = "' + value + '"'
                        i += 1
                    else:
                        var_str += '; "' + key + '" = "' + value + '"'
                        i += 1

                var_str += ' }'
                print(var_str)

                output = self.simulate(test_file['target'],
                                       test_file['simulation_technique'], 'no',
                                       var_str)

            else:
                output = self.simulate(test_file['target'],
                                       test_file['simulation_technique'], 'no')

        # wait
        self.log.info('Wait for 200 seconds before running the detections.')
        time.sleep(200)

        # run detection
        result = []

        for detection_obj in test_file['detections']:
            detection_file_name = detection_obj['file']
            detection = self.load_file(
                os.path.join(
                    os.path.dirname(__file__),
                    '../../security-content/detections/' +
                    detection_file_name))
            result_obj = dict()
            result_obj['detection'] = detection_obj['name']
            result_obj['detection_file'] = detection_obj['file']
            if self.config['cloud_provider'] == 'aws':
                instance = aws_service.get_instance_by_name(
                    'ar-splunk-' + self.config['range_name'] + '-' +
                    self.config['key_name'], self.config)
                if instance['State']['Name'] == 'running':
                    result_obj['error'], result_obj[
                        'results'] = splunk_sdk.test_search(
                            instance['NetworkInterfaces'][0]['Association']
                            ['PublicIp'],
                            str(self.config['attack_range_password']),
                            detection['search'],
                            detection_obj['pass_condition'], detection['name'],
                            detection_obj['file'], self.log)
                else:
                    self.log.error('ERROR: Splunk server is not running.')
            elif self.config['cloud_provider'] == 'azure':
                instance = azure_service.get_instance(
                    self.config, "ar-splunk-" + self.config['range_name'] +
                    "-" + self.config['key_name'], self.log)
                if instance['vm_obj'].instance_view.statuses[
                        1].display_status == "VM running":
                    result_obj['error'], result_obj[
                        'results'] = splunk_sdk.test_search(
                            instance['public_ip'],
                            str(self.config['attack_range_password']),
                            detection['search'],
                            detection_obj['pass_condition'], detection['name'],
                            detection_obj['file'], self.log)

            result.append(result_obj)

        # destroy attack range
        self.destroy()

        # return results
        return {'results': result, 'simulation_output': output}