def analyze_by_hash_command(intezer_api: IntezerApi, args: Dict[str, str]) -> CommandResults: file_hash = args.get('file_hash') if not file_hash: raise ValueError('Missing file hash') analysis = Analysis(file_hash=file_hash, api=intezer_api) try: analysis.send() analysis_id = analysis.analysis_id context_json = { 'ID': analysis.analysis_id, 'Status': 'Created', 'type': 'File' } return CommandResults( outputs_prefix='Intezer.Analysis', outputs_key_field='ID', outputs=context_json, readable_output='Analysis created successfully: {}'.format( analysis_id)) except HashDoesNotExistError: return _get_missing_file_result(file_hash) except AnalysisIsAlreadyRunning as error: return _get_analysis_running_result(response=error.response)
def test_analysis_check_status_before_send_raise_error(self): # Arrange analysis = Analysis(file_hash='a') # Act + Assert with self.assertRaises(errors.IntezerError): analysis.check_status()
def test_send_analysis_by_file_with_disable_unpacking(self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze', status=201, json={'result_url': 'a/sd/asd'}) mock.add('GET', url=self.full_url + '/analyses/asd', status=200, json={'result': 'report'}) analysis = Analysis(file_path='a', disable_dynamic_unpacking=True, disable_static_unpacking=True) with patch(self.patch_prop, mock_open(read_data='data')): # Act analysis.send(wait=True) # Assert self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH) self.assertEqual(analysis.result(), 'report') request_body = mock.calls[0].request.body.decode() self.assertTrue( 'Content-Disposition: form-data; name="disable_static_extraction"\r\n\r\nTrue' in request_body) self.assertTrue( 'Content-Disposition: form-data; name="disable_dynamic_execution"\r\n\r\nTrue' in request_body)
def send_file_with_wait( file_path, dynamic_unpacking=None, static_unpacking=None): # type: (str, bool, bool) -> None api.set_global_api('<api_key>') analysis = Analysis(file_path=file_path, dynamic_unpacking=dynamic_unpacking, static_unpacking=static_unpacking) analysis.send(wait=True) pprint(analysis.result())
def test_send_analysis_by_sha256_that_dont_exist_raise_error(self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze-by-hash', status=404) analysis = Analysis(file_hash='a' * 64) # Act + Assert with self.assertRaises(errors.HashDoesNotExistError): analysis.send()
def test_send_analysis_that_running_on_server_raise_error(self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze-by-hash', status=409, json={'result_url': 'a/sd/asd'}) analysis = Analysis(file_hash='a' * 64) # Act + Assert with self.assertRaises(errors.AnalysisIsAlreadyRunning): analysis.send()
def test_send_analysis_by_file_sent_analysis_with_pulling_and_get_status_finish( self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze', status=201, json={'result_url': 'a/sd/asd'}) mock.add('GET', url=self.full_url + '/analyses/asd', status=202) mock.add('GET', url=self.full_url + '/analyses/asd', status=202) mock.add('GET', url=self.full_url + '/analyses/asd', status=200, json={'result': 'report'}) analysis = Analysis(file_path='a') with patch(self.patch_prop, mock_open(read_data='data')): # Act analysis.send() analysis.check_status() analysis.check_status() analysis.check_status() # Assert self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
def test_send_analysis_by_sha256_sent_analysis_and_sets_status(self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze-by-hash', status=201, json={'result_url': 'a/sd/asd'}) analysis = Analysis(file_hash='a' * 64) # Act analysis.send() # Assert self.assertEqual(analysis.status, consts.AnalysisStatusCode.CREATED)
def test_send_analysis_by_file_with_file_stream_sent_analysis(self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze', status=201, json={'result_url': 'a/sd/asd'}) analysis = Analysis(file_stream=__file__) # Act analysis.send() # Assert self.assertEqual(analysis.status, consts.AnalysisStatusCode.CREATED)
def test_analysis_by_file_correct_code_item_type(self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze', status=201, json={'result_url': 'a/sd/asd'}) analysis = Analysis(file_path='a', code_item_type='memory_module') with patch(self.patch_prop, mock_open(read_data='data')): # Act analysis.send() # Assert self.assertEqual(analysis.status, consts.AnalysisStatusCode.CREATED)
def analyze_by_txt_file_command(path: str): try: hashes = get_hashes_from_file(path) with click.progressbar(length=len(hashes), label='Analyze files', show_pos=True, width=0) as progressbar: for file_hash in hashes: try: Analysis(file_hash=file_hash).send() except sdk_errors.HashDoesNotExistError: click.echo('Hash: {} does not exist in the system'.format(file_hash)) except sdk_errors.IntezerError: click.echo('Error occurred with hash: {}'.format(file_hash)) progressbar.update(1) if default_config.is_cloud: click.echo('analysis created. In order to check their results, go to: {}' .format(default_config.analyses_url)) else: click.echo( 'analysis created. In order to check their results go to Intezer Analyze history page') except IOError: click.echo('No read permissions for {}'.format(path)) click.Abort()
def test_analysis_by_sha256_raise_value_error_when_sha256_file_path_and_file_stream_given( self): # Assert with self.assertRaises(ValueError): Analysis(file_hash='a', file_stream=__file__, file_path='/test/test')
def analyze_file_command(file_path, no_unpacking, no_static_unpacking): if not utilities.is_supported_file(file_path): click.echo('File is not PE, ELF, DEX or APK') return try: analysis = Analysis(file_path=file_path, dynamic_unpacking=no_unpacking, static_unpacking=no_static_unpacking) analysis.send() if default_config.is_cloud: click.echo( 'Analysis created. In order to check its result, go to: {}/{}'.format(default_config.analyses_url, analysis.analysis_id)) else: click.echo('Analysis created. In order to check its result go to Intezer analyze history page') except sdk_errors.IntezerError as e: click.echo('Analyze error: {}'.format(e))
def intezer_upload(): if not len(config.INTEZER_APIKEY): return jsonify({"error": "NO API KEY"}), 200 path = request.args.get('path', '') if not os.path.isfile(path): return jsonify({"error": "%s is not a valid file or the system could not access it" % path}), 200 try: api.set_global_api(config.INTEZER_APIKEY) analysis = Analysis(file_path=path, dynamic_unpacking=None, static_unpacking=None) analysis.send(True) except errors.IntezerError as e: return jsonify({"error": "Error occurred: " + e.args[0]}), 200 return jsonify(analysis.result()), 200
def test_send_analysis_by_file_sends_analysis_with_waits_to_compilation_when_requested( self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze', status=201, json={'result_url': 'a/sd/asd'}) mock.add('GET', url=self.full_url + '/analyses/asd', status=200, json={'result': 'report'}) analysis = Analysis(file_path='a') with patch(self.patch_prop, mock_open(read_data='data')): # Act analysis.send(wait=True) # Assert self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
def send_file_without_wait( file_path, dynamic_unpacking, static_unpacking): # type: (str, bool, bool) -> None api.set_global_api('<api_key>') analysis = Analysis(file_path=file_path, dynamic_unpacking=dynamic_unpacking, static_unpacking=static_unpacking) analysis.send() analysis.wait_for_completion() pprint(analysis.result())
def analyze_by_uploaded_file_command(intezer_api: IntezerApi, args: dict) -> CommandResults: file_id = args.get('file_entry_id') file_data = demisto.getFilePath(file_id) try: analysis = Analysis(file_path=file_data['path'], api=intezer_api) analysis.send() context_json = { 'ID': analysis.analysis_id, 'Status': 'Created', 'type': 'File' } return CommandResults( outputs_prefix='Intezer.Analysis', outputs_key_field='ID', outputs=context_json, readable_output='Analysis created successfully: {}'.format( analysis.analysis_id)) except AnalysisIsAlreadyRunning as error: return _get_analysis_running_result(response=error.response)
def analyze_directory_command(path, no_unpacking, no_static_unpacking): success_number = 0 failed_number = 0 unsupported_number = 0 for root, dirs, files in os.walk(path): number_of_files = len(files) utilities.check_should_continue_for_large_dir(number_of_files, default_config.unusual_amount_in_dir) with click.progressbar(length=number_of_files, label='Sending files for analysis', show_pos=True) as progressbar: for file_name in files: file_path = os.path.join(root, file_name) if utilities.is_supported_file(file_path): try: Analysis(file_path=file_path, dynamic_unpacking=no_unpacking, static_unpacking=no_static_unpacking).send() success_number += 1 except sdk_errors.InsufficientQuota: raise sdk_errors.InsufficientQuota except sdk_errors.IntezerError: failed_number += 1 else: unsupported_number += 1 progressbar.update(1) if success_number != 0: if default_config.is_cloud: click.echo('{} analysis created. In order to check their results, go to: {}'.format(success_number, default_config.analyses_url)) else: click.echo('{} analysis created. In order to check their results ' 'go to Intezer analyze history page'.format(success_number)) if failed_number != 0: click.echo('{} analysis failed'.format(failed_number)) if unsupported_number != 0: click.echo('{} unsupported files'.format(unsupported_number))
def run(self): result = {} try: intezer_sdk.consts.USER_AGENT = "IntelOwl" # run analysis analysis = Analysis(file_hash=self.observable_name) analysis.send(wait=False) analysis.wait_for_completion( interval=self.poll_interval, sleep_before_first_check=True, timeout=timedelta(seconds=self.timeout), ) result.update(analysis.result(), hash_found=True) except (intezer_errors.HashDoesNotExistError, intezer_errors.InsufficientQuota): result.update(hash_found=False) except intezer_errors.IntezerError as e: raise AnalyzerRunException(e) return result
def test_analysis_check_status_after_analysis_finish_raise_error(self): # Arrange with responses.RequestsMock() as mock: mock.add('POST', url=self.full_url + '/analyze', status=201, json={'result_url': 'a/sd/asd'}) mock.add('GET', url=self.full_url + '/analyses/asd', status=200, json={'result': 'report'}) analysis = Analysis(file_path='a') with patch(self.patch_prop, mock_open(read_data='data')): # Act analysis.send(wait=True) # Assert with self.assertRaises(errors.IntezerError): analysis.check_status()
def test_analysis_by_file_wrong_code_item_type(self): # Act + Assert with self.assertRaises(ValueError): Analysis(file_path='a', code_item_type='anderson_paak')
def test_analysis_get_report_for_not_finish_analyze_raise_error(self): # Arrange analysis = Analysis(file_hash='a') # Act + Assert with self.assertRaises(errors.ReportDoesNotExistError): analysis.result()
def analysis_by_hash_without_wait(file_hash): # type: (str) -> None api.set_global_api('<api_key>') analysis = Analysis(file_hash=file_hash) analysis.send() analysis.wait_for_completion() pprint(analysis.result())
def analysis_by_hash_with_wait(file_hash): # type: (str) -> None api.set_global_api('<api_key>') analysis = Analysis(file_hash=file_hash) analysis.send(wait=True) pprint(analysis.result())
def test_analysis_by_sha256_and_file_sent_analysis_and_raise_value_error( self): # Assert with self.assertRaises(ValueError): Analysis(file_hash='a', file_path='/test/test')
def test_analysis_raise_value_error_when_no_file_option_given(self): # Assert with self.assertRaises(ValueError): Analysis()
def analyze_directory_command(path: str, disable_dynamic_unpacking: bool, disable_static_unpacking: bool, code_item_type: str, ignore_directory_count_limit: bool): success_number = 0 failed_number = 0 unsupported_number = 0 for root, dirs, files in os.walk(path): files = [f for f in files if not is_hidden(os.path.join(root, f))] dirs[:] = [d for d in dirs if not is_hidden(os.path.join(root, d))] number_of_files = len(files) if not ignore_directory_count_limit: utilities.check_should_continue_for_large_dir(number_of_files, default_config.unusual_amount_in_dir) if not files: continue with click.progressbar(length=number_of_files, label='Sending files for analysis', show_pos=True) as progressbar: for file_name in files: file_path = os.path.join(root, file_name) if disable_dynamic_unpacking and not utilities.is_supported_file(file_path): unsupported_number += 1 else: try: Analysis(file_path=file_path, code_item_type=code_item_type, disable_dynamic_unpacking=disable_dynamic_unpacking, disable_static_unpacking=disable_static_unpacking).send() success_number += 1 except sdk_errors.IntezerError as ex: # We cannot continue analyzing the directory if the account is out of quota if isinstance(ex, sdk_errors.InsufficientQuota): logger.error('Failed to analyze %s', file_path) raise logger.exception('Error while analyzing directory') failed_number += 1 except Exception: logger.exception('Failed to analyze %s', file_path) failed_number += 1 progressbar.update(1) if success_number != 0: if default_config.is_cloud: click.echo('{} analysis created. In order to check their results, go to: {}'.format( success_number, default_config.analyses_url) ) else: click.echo('{} analysis created. In order to check their results ' 'go to Intezer Analyze history page'.format(success_number)) if failed_number != 0: click.echo('{} analysis failed'.format(failed_number)) if unsupported_number != 0: click.echo('{} unsupported files'.format(unsupported_number))