Exemple #1
0
    def update_ESCU_app(self):
        self.log.info("Update ESCU App. This can take some time")
        # 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)
    def dump_attack_data(self, dump_name, last_sim):
        self.log.info("Dump log data")

        folder = "attack_data/" + dump_name
        os.mkdir(os.path.join(os.path.dirname(__file__), '../' + folder))

        server_str = ("ar-splunk-" + self.config['range_name'] + "-" +
                      self.config['key_name'])
        if self.config['cloud_provider'] == 'aws':
            target_public_ip = aws_service.get_single_instance_public_ip(
                server_str, self.config)
            ansible_user = '******'
            ansible_port = 5986
        elif self.config['cloud_provider'] == 'azure':
            target_public_ip = azure_service.get_instance(
                self.config, server_str, self.log)['public_ip']
            ansible_user = '******'
            ansible_port = 5985

        with open(
                os.path.join(os.path.dirname(__file__),
                             '../attack_data/dumps.yml')) as dumps:
            for dump in yaml.full_load(dumps):
                if dump['enabled']:
                    dump_out = dump['dump_parameters']['out']
                    if last_sim:
                        # if last_sim is set, then it overrides time in dumps.yml
                        # and starts dumping from last simulation
                        with open(
                                os.path.join(
                                    os.path.dirname(__file__),
                                    "../attack_data/.%s-last-sim.tmp" %
                                    self.config['range_name']), 'r') as ls:
                            sim_ts = float(ls.readline())
                            dump['dump_parameters']['time'] = "-%ds" % int(
                                time.time() - sim_ts)
                    dump_search = "search %s earliest=%s | sort 0 _time" \
                                  % (dump['dump_parameters']['search'], dump['dump_parameters']['time'])
                    dump_info = "Dumping Splunk Search to %s " % dump_out
                    self.log.info(dump_info)
                    out = open(
                        os.path.join(
                            os.path.dirname(__file__),
                            "../attack_data/" + dump_name + "/" + dump_out),
                        'wb')
                    splunk_sdk.export_search(
                        target_public_ip,
                        s=dump_search,
                        password=self.config['attack_range_password'],
                        out=out)
                    out.close()
                    self.log.info("%s [Completed]" % dump_info)
Exemple #3
0
    def replay_attack_data(self, dump_name, dump, replay_parameters = None):
        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']

        if replay_parameters == None:
            with open(os.path.join(os.path.dirname(__file__), '../attack_data/dumps.yml')) as dump_fh:
                for d in yaml.full_load(dump_fh):
                    if (d['name'] == dump or dump is None) and d['enabled']:
                        self.replay_attack_dataset(splunk_ip, dump_name, d['replay_parameters']['index'], d['replay_parameters']['sourcetype'], d['replay_parameters']['source'], d['dump_parameters']['out'])
        else:
            self.replay_attack_dataset(splunk_ip, dump_name, 'test', replay_parameters['sourcetype'], replay_parameters['source'], replay_parameters['out'])
Exemple #4
0
    def execute_savedsearch(self, search_name, earliest, latest):
        self.log.info("Execute savedsearch " + search_name)

        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']

        splunk_sdk.execute_savedsearch(splunk_ip,
                                       self.config['attack_range_password'],
                                       search_name, earliest, latest)
    def store_attack_data(self, results, test_file):
        target_public_ip = aws_service.get_single_instance_public_ip(
            test_file['target'], self.config)
        if test_file['target'] == 'attack-range-windows-client':
            runner = ansible_runner.run(
                private_data_dir='.attack_range/',
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path="../ansible/roles",
                playbook='../ansible/playbooks/attack_data.yml',
                extravars={
                    'ansible_user': '******',
                    'ansible_password': self.config['win_password'],
                    'ansible_port': 5985,
                    'ansible_winrm_scheme': 'http'
                },
                verbosity=0)
        else:
            runner = ansible_runner.run(
                private_data_dir='.attack_range/',
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path="../ansible/roles",
                playbook='../ansible/playbooks/attack_data.yml',
                extravars={
                    'ansible_user': '******',
                    'ansible_password': self.config['win_password']
                },
                verbosity=0)

        aws_service.upload_file_s3_bucket('tmp/attack_data.txt', results,
                                          test_file, False)

        with tarfile.open('tmp/attack_data.tar.gz', "w:gz") as tar:
            tar.add('tmp/attack_data.txt', arcname="attack_data.txt")

        aws_service.upload_file_s3_bucket('tmp/attack_data.tar.gz', results,
                                          test_file, True)

        if os.path.exists('tmp/attack_data.tar.gz'):
            os.remove('tmp/attack_data.tar.gz')

        if os.path.exists('tmp/attack_data.txt'):
            os.remove('tmp/attack_data.txt')

        if runner.status == "successful":
            self.log.info("successfully stored attack data in S3 bucket")
        else:
            self.log.info("failed to store attack data in S3 bucket")
    def simulate(self, target, simulation_techniques):
        target_public_ip = aws_service.get_single_instance_public_ip(
            target, self.config)
        if target == 'attack-range-windows-client':
            runner = ansible_runner.run(
                private_data_dir='.attack_range/',
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path="../ansible/roles",
                playbook='../ansible/playbooks/atomic_red_team.yml',
                extravars={
                    'art_run_techniques': simulation_techniques,
                    'ansible_user': '******',
                    'ansible_password': self.config['win_password'],
                    'ansible_port': 5985,
                    'ansible_winrm_scheme': 'http',
                    'art_repository': self.config['art_repository'],
                    'art_branch': self.config['art_branch']
                },
                verbosity=0)
        else:
            runner = ansible_runner.run(
                private_data_dir='.attack_range/',
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path="../ansible/roles",
                playbook='../ansible/playbooks/atomic_red_team.yml',
                extravars={
                    'art_run_techniques': simulation_techniques,
                    'ansible_user': '******',
                    'ansible_password': self.config['win_password'],
                    'art_repository': self.config['art_repository'],
                    'art_branch': self.config['art_branch']
                },
                verbosity=0)

        if runner.status == "successful":
            self.log.info(
                "successfully executed technique ID {0} against target: {1}".
                format(simulation_techniques, target))
        else:
            self.log.error(
                "failed to executed technique ID {0} against target: {1}".
                format(simulation_techniques, target))
            sys.exit(1)
Exemple #7
0
    def replay_attack_data(self, dump_name, attack_data):
        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']

        # preset our ansible vars
        ansible_vars = {}
        ansible_vars['dump_name'] = dump_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['ansible_port'] = 22

        ansible_vars['out'] = attack_data['file_name']
        ansible_vars['sourcetype'] = attack_data['sourcetype']
        ansible_vars['source'] = attack_data['source']
        ansible_vars['index'] = attack_data['index']
        ansible_vars['update_timestamp'] = attack_data['update_timestamp']

        if 'data' in attack_data:
            ansible_vars['data'] = attack_data['data']
            ansible_vars['local_data'] = False
        else:
            ansible_vars['local_data'] = True

        # call ansible
        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_test.yml'),
            extravars=ansible_vars,
        )
    def replay_attack_data(self, dump_name, dump):
        with open(
                os.path.join(os.path.dirname(__file__),
                             '../attack_data/dumps.yml')) as dump_fh:
            for d in yaml.full_load(dump_fh):
                if (d['name'] == dump or dump is None) and d['enabled']:
                    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']
                    #splunk_ip = aws_service.get_single_instance_public_ip("aws-" + self.config['range_name'] + "-splunk", self.config)
                    # Upload the replay logs to the Splunk server
                    ansible_vars = {}
                    ansible_vars['dump_name'] = dump_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'] = d['dump_parameters']['out']
                    ansible_vars['sourcetype'] = d['replay_parameters'][
                        'sourcetype']
                    ansible_vars['source'] = d['replay_parameters']['source']
                    ansible_vars['index'] = d['replay_parameters']['index']

                    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)
Exemple #9
0
    def dump_attack_data(self, dump_name, dump_data):
        self.log.info("Dump log data")

        folder = "attack_data/" + dump_name
        if os.path.isdir(
                os.path.join(os.path.dirname(__file__), '../' + folder)):
            self.log.error("folder already. please specify another directory")
            sys.exit(1)
        else:
            os.mkdir(os.path.join(os.path.dirname(__file__), '../' + folder))

        server_str = ("ar-splunk-" + self.config['range_name'] + "-" +
                      self.config['key_name'])
        if self.config['cloud_provider'] == 'aws':
            target_public_ip = aws_service.get_single_instance_public_ip(
                server_str, self.config)
            ansible_user = '******'
            ansible_port = 5986
        elif self.config['cloud_provider'] == 'azure':
            target_public_ip = azure_service.get_instance(
                self.config, server_str, self.log)['public_ip']
            ansible_user = '******'
            ansible_port = 5985


        dump_search = "search %s earliest=-%s latest=%s | sort 0 _time" \
            % (dump_data['search'], dump_data['earliest'], dump_data['latest'])
        dump_info = "Dumping Splunk Search to %s " % dump_data['out']
        self.log.info(dump_info)
        out = open(
            os.path.join(
                os.path.dirname(__file__),
                "../attack_data/" + dump_name + "/" + dump_data['out']), 'wb')
        splunk_sdk.export_search(target_public_ip,
                                 s=dump_search,
                                 password=self.config['attack_range_password'],
                                 out=out)
        out.close()
        self.log.info("%s [Completed]" % dump_info)
    def dump_attack_data(self, dump_name):

        # copy json from nxlog
        # copy raw data using powershell
        # copy indexes
        # packet capture with netsh
        # see https://medium.com/threat-hunters-forge/mordor-pcaps-part-1-capturing-network-packets-from-windows-endpoints-with-network-shell-e117b84ec971

        self.log.info("Dump log data")

        folder = "attack_data/" + dump_name
        os.mkdir(folder)

        servers = []
        if self.config['windows_domain_controller'] == '1':
            servers.append('windows_domain_controller')
        if self.config['windows_server'] == '1':
            servers.append('windows_server')

        # dump json and windows event logs from Windows servers
        for server in servers:
            server_str = ("attack-range-" + server).replace("_", "-")
            target_public_ip = aws_service.get_single_instance_public_ip(
                server_str, self.config)

            if server_str == 'attack-range-windows-client':
                runner = ansible_runner.run(
                    private_data_dir='.attack_range/',
                    cmdline=str('-i ' + target_public_ip + ', '),
                    roles_path="../ansible/roles",
                    playbook='../ansible/playbooks/attack_data.yml',
                    extravars={
                        'ansible_user': '******',
                        'ansible_password': self.config['win_password'],
                        'ansible_port': 5985,
                        'ansible_winrm_scheme': 'http',
                        'hostname': server_str,
                        'folder': dump_name
                    },
                    verbosity=0)
            else:
                runner = ansible_runner.run(
                    private_data_dir='.attack_range/',
                    cmdline=str('-i ' + target_public_ip + ', '),
                    roles_path="../ansible/roles",
                    playbook='../ansible/playbooks/attack_data.yml',
                    extravars={
                        'ansible_user': '******',
                        'ansible_password': self.config['win_password'],
                        'hostname': server_str,
                        'folder': dump_name
                    },
                    verbosity=0)

        if self.config['sync_to_s3_bucket'] == '1':
            for file in glob.glob(folder + "/*"):
                self.log.info(
                    "upload attack data to S3 bucket. This can take some time")
                aws_service.upload_file_s3_bucket(
                    self.config['s3_bucket_attack_data'], file,
                    str(dump_name + '/' + os.path.basename(file)))
    def simulate(self,
                 target,
                 simulation_techniques,
                 simulation_atomics,
                 var_str='no'):
        target_public_ip = aws_service.get_single_instance_public_ip(
            target, self.config)

        # check if specific atomics are used then it's not allowed to multiple techniques
        techniques_arr = simulation_techniques.split(',')
        if (len(techniques_arr) > 1) and (simulation_atomics != 'no'):
            self.log.error(
                'ERROR: if simulation_atomics are used, only a single simulation_technique is allowed.'
            )
            sys.exit(1)

        run_specific_atomic_tests = 'True'
        if simulation_atomics == 'no':
            run_specific_atomic_tests = 'False'

        if target == 'attack-range-windows-client':
            runner = ansible_runner.run(
                private_data_dir='.attack_range/',
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path="../ansible/roles",
                playbook='../ansible/playbooks/atomic_red_team.yml',
                extravars={
                    'var_str': var_str,
                    'run_specific_atomic_tests': run_specific_atomic_tests,
                    'art_run_tests': simulation_atomics,
                    'art_run_techniques': simulation_techniques,
                    'ansible_user': '******',
                    'ansible_password': self.config['win_password'],
                    'ansible_port': 5985,
                    'ansible_winrm_scheme': 'http',
                    'art_repository': self.config['art_repository'],
                    'art_branch': self.config['art_branch']
                },
                verbosity=0)
        else:
            runner = ansible_runner.run(
                private_data_dir='.attack_range/',
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path="../ansible/roles",
                playbook='../ansible/playbooks/atomic_red_team.yml',
                extravars={
                    'var_str': var_str,
                    'run_specific_atomic_tests': run_specific_atomic_tests,
                    'art_run_tests': simulation_atomics,
                    'art_run_techniques': simulation_techniques,
                    'ansible_user': '******',
                    'ansible_password': self.config['win_password'],
                    'art_repository': self.config['art_repository'],
                    'art_branch': self.config['art_branch']
                },
                verbosity=0)

        if runner.status == "successful":
            self.log.info(
                "successfully executed technique ID {0} against target: {1}".
                format(simulation_techniques, target))
        else:
            self.log.error(
                "failed to executed technique ID {0} against target: {1}".
                format(simulation_techniques, target))
            sys.exit(1)
Exemple #12
0
    def simulate(self,
                 target,
                 simulation_techniques,
                 simulation_atomics,
                 var_str='no'):
        if self.config['cloud_provider'] == 'aws':
            target_public_ip = aws_service.get_single_instance_public_ip(
                target, self.config)
            ansible_user = '******'
            ansible_port = 5986
        elif self.config['cloud_provider'] == 'azure':
            target_public_ip = azure_service.get_instance(
                self.config, target, self.log)['public_ip']
            ansible_user = '******'
            ansible_port = 5985

        start_time = time.time()

        # check if specific atomics are used then it's not allowed to multiple techniques
        techniques_arr = simulation_techniques.split(',')
        if (len(techniques_arr) > 1) and (simulation_atomics != 'no'):
            self.log.error(
                'ERROR: if simulation_atomics are used, only a single simulation_technique is allowed.'
            )
            sys.exit(1)

        run_specific_atomic_tests = 'True'
        if simulation_atomics == 'no':
            run_specific_atomic_tests = 'False'

        if target == "ar-win-client-" + self.config[
                'range_name'] + "-" + self.config['key_name']:
            runner = ansible_runner.run(
                private_data_dir=os.path.join(os.path.dirname(__file__),
                                              '../'),
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path=os.path.join(os.path.dirname(__file__),
                                        '../ansible/roles'),
                playbook=os.path.join(
                    os.path.dirname(__file__),
                    '../ansible/playbooks/atomic_red_team.yml'),
                extravars={
                    'ansible_port': 5985,
                    'var_str': var_str,
                    'run_specific_atomic_tests': run_specific_atomic_tests,
                    'art_run_tests': simulation_atomics,
                    'art_run_techniques': simulation_techniques,
                    'ansible_user': ansible_user,
                    'ansible_password': self.config['attack_range_password'],
                    'ansible_port': 5985,
                    'ansible_winrm_scheme': 'http',
                    'art_repository': self.config['art_repository'],
                    'art_branch': self.config['art_branch']
                },
                verbosity=0)
        else:
            runner = ansible_runner.run(
                private_data_dir=os.path.join(os.path.dirname(__file__),
                                              '../'),
                cmdline=str('-i ' + target_public_ip + ', '),
                roles_path=os.path.join(os.path.dirname(__file__),
                                        '../ansible/roles'),
                playbook=os.path.join(
                    os.path.dirname(__file__),
                    '../ansible/playbooks/atomic_red_team.yml'),
                extravars={
                    'ansible_port': ansible_port,
                    'var_str': var_str,
                    'run_specific_atomic_tests': run_specific_atomic_tests,
                    'art_run_tests': simulation_atomics,
                    'art_run_techniques': simulation_techniques,
                    'ansible_user': ansible_user,
                    'ansible_password': self.config['attack_range_password'],
                    'art_repository': self.config['art_repository'],
                    'art_branch': self.config['art_branch']
                },
                verbosity=0)

        if runner.status == "successful":
            output = []
            if 'output_art' in runner.get_fact_cache(target_public_ip):
                stdout_lines = runner.get_fact_cache(
                    target_public_ip)['output_art']['stdout_lines']
            else:
                stdout_lines = runner.get_fact_cache(
                    target_public_ip)['output_art_var']['stdout_lines']

            i = 0
            for line in stdout_lines:
                match = re.search(r'Executing test: (.*)', line)
                if match is not None:
                    #print(match.group(1))
                    if re.match(r'Done executing test', stdout_lines[i + 1]):
                        msg = 'Return value unclear for test ' + match.group(1)
                        self.log.info(msg)
                        output.append(msg)
                    else:
                        msg = 'Successful Execution of test ' + match.group(1)
                        self.log.info(msg)
                        output.append(msg)
                i += 1

            with open(
                    os.path.join(
                        os.path.dirname(__file__),
                        "../attack_data/.%s-last-sim.tmp" %
                        self.config['range_name']), 'w') as last_sim:
                last_sim.write("%s" % start_time)
            return output
        else:
            self.log.error(
                "failed to executed technique ID {0} against target: {1}".
                format(simulation_techniques, target))
            sys.exit(1)
    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}