def _detonate_file(self, param): config = self.get_config() api_submit_file_object = ApiSubmitFile( config[PAYLOAD_SECURITY_API_KEY], self._base_url, self) self.save_progress(PAYLOAD_SECURITY_MSG_SUBMITTING_FILE) action_result = self.add_action_result(ActionResult(dict(param))) return_value, files = self._get_file_dict(param, action_result) if phantom.is_fail(return_value): return action_result.get_status() api_submit_file_object.attach_files(files) api_submit_file_object.attach_data( {'environment_id': param['environment_id']}) try: self._make_api_call_with_err_handling(api_submit_file_object, 'File submit failed.') report_api_json_response = self._detonation_partial( param, api_submit_file_object) except VxError as exc: action_result.set_status(phantom.APP_ERROR, '{}'.format(str(exc))) return action_result.get_status() action_result.add_data(report_api_json_response) return action_result.set_status( phantom.APP_SUCCESS, 'Successfully submitted file and retrieved analysis result. Sample sha256: \'{}\' and environment ID: \'{}\'' .format(report_api_json_response['sha256'], param['environment_id']))
def main(): try: if os.path.exists('config.py'): from config import get_config config = get_config() else: raise MissingConfigurationError( 'Configuration is missing. Before running CLI, please copy the file \'config_tpl.py\' from current dir, rename it to \'config.py\', and fill' ) program_name = 'VxWebService Python API Connector' program_version = __version__ vxapi_cli_headers = {'User-agent': 'VxApi CLI Connector'} if config['server'].endswith('/'): config['server'] = config['server'][:-1] if config['server'].endswith('vxstream-sandbox.com'): config['server'] = config['server'].replace( 'vxstream-sandbox.com', 'falcon-sandbox.com') map_of_available_actions = OrderedDict([ (ACTION_GET_API_LIMITS, CliApiLimitsSummary( ApiApiLimitsSummary(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_API_QUERY_LIMITS, CliApiQueryLimits( ApiApiQueryLimits(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_API_SUBMISSION_LIMITS, CliApiSubmissionLimits( ApiApiSubmissionLimits(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_ENVIRONMENTS, CliEnvironments( ApiEnvironments(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_FEED, CliFeed( ApiFeed(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_NSSF_FILES, CliNssfDownload( ApiNssfDownload(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_NSSF_LIST, CliNssfList( ApiNssfList(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_RELATIONSHIPS, CliRelationships( ApiRelationships(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_RESULT, CliResult( ApiResult(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SAMPLE_DROPPED_FILES, CliSampleDroppedFiles( ApiSampleDroppedFiles(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SAMPLE_SCREENSHOTS, CliSampleScreenshots( ApiSampleScreenshots(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SCAN, CliScan( ApiScan(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_BULK_SCAN, CliBulkScan( ApiBulkScan(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_STATE, CliState( ApiState(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SUMMARY, CliSummary( ApiSummary(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_BULK_SUMMARY, CliBulkSummary( ApiBulkSummary(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SYSTEM_BACKEND, CliSystemBackend( ApiSystemBackend(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SYSTEM_IN_PROGRESS, CliSystemInProgress( ApiSystemInProgress(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SYSTEM_HEARTBEAT, CliSystemHeartbeat( ApiSystemHeartbeat(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SYSTEM_STATE, CliSystemState( ApiSystemState(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SYSTEM_STATS, CliSystemStats( ApiSystemStats(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_SYSTEM_QUEUE_SIZE, CliSystemQueueSize( ApiSystemQueueSize(config['api_key'], config['api_secret'], config['server']))), (ACTION_GET_URL_HASH, CliUrlHash( ApiUrlHash(config['api_key'], config['api_secret'], config['server']))), (ACTION_REANALYZE_SAMPLE, CliReanalyze( ApiReanalyze(config['api_key'], config['api_secret'], config['server']))), (ACTION_SEARCH, CliSearch( ApiSearch(config['api_key'], config['api_secret'], config['server']))), (ACTION_SUBMIT_DROPPED_FILE, CliDroppedFileSubmit( ApiDroppedFileSubmit(config['api_key'], config['api_secret'], config['server']))), (ACTION_SUBMIT_FILE, CliSubmitFile( ApiSubmitFile(config['api_key'], config['api_secret'], config['server']))), (ACTION_SUBMIT_URL_FILE, CliSubmitUrlFile( ApiSubmitFile(config['api_key'], config['api_secret'], config['server']))), (ACTION_SUBMIT_URL, CliSubmitUrl( ApiSubmitUrl(config['api_key'], config['api_secret'], config['server']))), ]) request_session = requests.Session() api_object_api_key_data = ApiApiKeyData(config['api_key'], config['api_secret'], config['server']) api_object_api_key_data.call(request_session, vxapi_cli_headers) api_key_data_json_response = api_object_api_key_data.get_response_json( ) if api_object_api_key_data.get_response_status_code( ) != 200 or api_key_data_json_response['response_code'] != 0: base_error_message = 'Can\'t retrieve data for given API Key \'{}\' in the webservice: \'{}\'. Response status code: \'{}\''.format( config['api_key'], config['server'], api_object_api_key_data.get_response_status_code()) if 'response' in api_key_data_json_response and 'error' in api_key_data_json_response[ 'response']: base_error_message += '. Response message: \'{}\''.format( api_key_data_json_response['response']['error']) raise RetrievingApiKeyDataError(base_error_message) used_api_key_data = api_key_data_json_response['response'] parser = argparse.ArgumentParser( description=program_name, formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False) parser.add_argument('--version', '-ver', action='version', version='{} - version {}'.format( program_name, program_version)) CliArgumentBuilder(parser).add_help_argument() subparsers = parser.add_subparsers( help='Action names for \'{}\' auth level'.format( used_api_key_data['auth_level_name']), dest="chosen_action") for name, cli_object in map_of_available_actions.items(): if cli_object.api_object.endpoint_auth_level <= used_api_key_data[ 'auth_level']: child_parser = subparsers.add_parser( name=name, help=cli_object.help_description, add_help=False) cli_object.add_parser_args(child_parser) args = vars(parser.parse_args()) if args['chosen_action'] is not None: args_iterations = [] if_multiple_calls = True if args[ 'chosen_action'] == ACTION_SUBMIT_FILE and len( args['file']) > 1 else False if args['chosen_action'] == ACTION_SUBMIT_FILE: for file in args['file']: arg_iter = args.copy() arg_iter['file'] = file args_iterations.append(arg_iter) else: args_iterations = [args] cli_object = map_of_available_actions[args['chosen_action']] if args['verbose'] is True: cli_object.init_verbose_mode() print( Color.control('Running \'{}\' in version \'{}\''.format( program_name, program_version))) CliHelper.prompt_for_dir_content_submission(args) CliHelper.prompt_for_sharing_confirmation(args, config['server']) CliHelper.check_if_version_is_supported( args, ApiInstanceVersion(config['api_key'], config['api_secret'], config['server']), request_session, vxapi_cli_headers, MINIMAL_SUPPORTED_INSTANCE_VERSION) for index, arg_iter in enumerate(args_iterations): cli_object.attach_args(arg_iter) if arg_iter['verbose'] is True: if arg_iter['chosen_action'] != ACTION_GET_API_LIMITS and ( if_multiple_calls is False or index == 0): # API limits checking should be done here, to ensure that user always will be able to run command in help mode. Also there is no need to run it in non verbose mode. api_object_api_limits = ApiApiQueryLimits( config['api_key'], config['api_secret'], config['server']) api_object_api_limits.call(request_session, vxapi_cli_headers) api_limits_response_json = api_object_api_limits.get_response_json( ) # Ignore when WebService doesn't have that endpoint if api_object_api_limits.get_response_status_code( ) != 404: if api_object_api_limits.get_response_status_code( ) != 200 or api_limits_response_json[ 'response_code'] == -1: raise RetrievingApiKeyDataError( 'Can\'t check API limits before calling requested endpoint in webservice: \'{}\'. Response status code: \'{}\'' .format( config['server'], api_object_api_limits. get_response_status_code())) if api_object_api_limits.get_response_status_code( ) == 200 and api_limits_response_json[ 'response_code'] == 0 and api_limits_response_json[ 'response']['limit_reached'] is True: name_of_reached_limit = api_limits_response_json[ 'response']['name_of_reached_limit'] raise ReachedApiLimitError( 'Exceeded maximum API requests per {}({}). Please try again later.' .format( name_of_reached_limit, api_limits_response_json['response'] ['used'][name_of_reached_limit])) if api_object_api_limits.get_response_status_code( ) == 200 and api_limits_response_json[ 'response_code'] == 0 and api_limits_response_json[ 'response']['used']: api_usage = OrderedDict() api_usage_limits = api_limits_response_json[ 'response']['limits'] is_api_limit_reached = False for period, used_limit in api_limits_response_json[ 'response']['used'].items(): # Given request is made after checking api limits. It means that we have to add 1 to current limits, to simulate that what happen after making requested API call api_usage[period] = used_limit + 1 if is_api_limit_reached is False and api_usage[ period] == api_usage_limits[period]: is_api_limit_reached = True print(Color.control('API Limits for used API Key')) print('Webservice API usage limits: {}'.format( api_usage_limits)) print('Current API usage: {}'.format( json.dumps(api_usage))) print('Is limit reached: {}'.format( Color.success('No') if is_api_limit_reached is False else Color.error('Yes'))) if if_multiple_calls is False or index == 0: print(Color.control('Used API Key')) print('API Key: {}'.format( used_api_key_data['api_key'])) print('Auth Level: {}'.format( used_api_key_data['auth_level_name'])) if used_api_key_data['user'] is not None: print('User: {} ({})'.format( used_api_key_data['user']['name'], used_api_key_data['user']['email'])) if arg_iter['chosen_action'] == ACTION_SUBMIT_FILE: if if_multiple_calls is True and index == 0: print( Color.control( 'Starting the process of sending multiple files ...' )) cli_object.attach_file(arg_iter['file']) CliHelper.print_call_info(cli_object) elif arg_iter['chosen_action'] == ACTION_SUBMIT_FILE: cli_object.attach_file(arg_iter['file']) try: cli_object.api_object.call(request_session, vxapi_cli_headers) except Exception as e: if if_multiple_calls is True: CliHelper.print_error_info(e) else: raise e if arg_iter['verbose'] is True: print( Color.control('Received response at ' + '{:%Y-%m-%d %H:%M:%S}'.format( datetime.datetime.now()))) print('Response status code: {}'.format( cli_object.get_colored_response_status_code())) print('Message: {}'.format( cli_object.get_colored_prepared_response_msg())) show_response_msg = 'Showing response' if if_multiple_calls is True: show_response_msg = '{} for file \'{}\''.format( show_response_msg, arg_iter['file'].name) print(Color.control(show_response_msg)) elif if_multiple_calls: print(Color.control(arg_iter['file'].name)) print(cli_object.get_result_msg()) if cli_object.api_object.get_response_msg_success_nature( ) is False and if_multiple_calls is True and cli_object.api_object.api_expected_data_type == ApiCaller.CONST_EXPECTED_DATA_TYPE_JSON: response_json = cli_object.api_object.get_response_json() if 'response_code' in response_json and 'Exceeded maximum API requests' in response_json[ 'response']['error']: raise Exception( 'Requests exceeded maximum API requests, the rest of the unsubmitted files won\'t be processed, exiting ...' ) cli_object.do_post_processing() if arg_iter['verbose'] is True: print('\n') else: print( Color.control( 'No option was selected. To check CLI options, run script in help mode: \'{} -h\'' .format(__file__))) except Exception as e: CliHelper.print_error_info(e)
def main(): try: if os.path.exists('config.py'): from config import get_config config = get_config() else: raise MissingConfigurationError( 'Configuration is missing. Before running CLI, please copy the file \'config_tpl.pl\' from current dir, rename it to \'config.pl\', and fill' ) program_name = 'VxWebService Python API Connector' program_version = __version__ vxapi_cli_headers = {'User-agent': 'VxApi CLI Connector'} if config['server'].endswith('/'): config['server'] = config['server'][:-1] map_of_available_actions = OrderedDict([ ('get_api_limits', CliApiLimits( ApiApiLimits(config['api_key'], config['api_secret'], config['server']))), ('get_feed', CliFeed( ApiFeed(config['api_key'], config['api_secret'], config['server']))), ('get_relationships', CliRelationships( ApiRelationships(config['api_key'], config['api_secret'], config['server']))), ('get_result', CliResult( ApiResult(config['api_key'], config['api_secret'], config['server']))), ('get_sample_dropped_files', CliSampleDroppedFiles( ApiSampleDroppedFiles(config['api_key'], config['api_secret'], config['server']))), ('get_sample_screenshots', CliSampleScreenshots( ApiSampleScreenshots(config['api_key'], config['api_secret'], config['server']))), ('get_scan', CliScan( ApiScan(config['api_key'], config['api_secret'], config['server']))), ('get_state', CliState( ApiState(config['api_key'], config['api_secret'], config['server']))), ('get_summary', CliSummary( ApiSummary(config['api_key'], config['api_secret'], config['server']))), ('get_system_backend', CliSystemBackend( ApiSystemBackend(config['api_key'], config['api_secret'], config['server']))), ('get_system_in_progress', CliSystemInProgress( ApiSystemInProgress(config['api_key'], config['api_secret'], config['server']))), ('get_system_heartbeat', CliSystemHeartbeat( ApiSystemHeartbeat(config['api_key'], config['api_secret'], config['server']))), ('get_system_state', CliSystemState( ApiSystemState(config['api_key'], config['api_secret'], config['server']))), ('get_system_stats', CliSystemStats( ApiSystemStats(config['api_key'], config['api_secret'], config['server']))), ('get_system_queue_size', CliSystemQueueSize( ApiSystemQueueSize(config['api_key'], config['api_secret'], config['server']))), ('get_quota', CliQuota( ApiQuota(config['api_key'], config['api_secret'], config['server']))), ('reanalyze_sample', CliReanalyze( ApiReanalyze(config['api_key'], config['api_secret'], config['server']))), ('search', CliSearch( ApiSearch(config['api_key'], config['api_secret'], config['server']))), ('submit_dropped_file', CliDroppedFileSubmit( ApiDroppedFileSubmit(config['api_key'], config['api_secret'], config['server']))), ('submit_file', CliSubmitFile( ApiSubmitFile(config['api_key'], config['api_secret'], config['server']))), ('submit_url_file', CliSubmitUrlFile( ApiSubmitFile(config['api_key'], config['api_secret'], config['server']))), ('submit_url', CliSubmitUrl( ApiSubmitUrl(config['api_key'], config['api_secret'], config['server']))), ]) request_session = requests.Session() api_object_api_key_data = ApiApiKeyData(config['api_key'], config['api_secret'], config['server']) api_object_api_key_data.call(request_session, vxapi_cli_headers) if api_object_api_key_data.get_response_status_code( ) != 200 or api_object_api_key_data.get_response_json( )['response_code'] != 0: raise RetrievingApiKeyDataError( 'Can\'t retrieve data for api_key \'{}\' in the webservice: \'{}\'. Response status code: \'{}\'' .format(config['api_key'], config['server'], api_object_api_key_data.get_response_status_code())) used_api_key_data = api_object_api_key_data.get_response_json( )['response'] parser = argparse.ArgumentParser( description=program_name, formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False) parser.add_argument('--version', '-ver', action='version', version='{} - version {}'.format( program_name, program_version)) CliArgumentBuilder(parser).add_help_argument() subparsers = parser.add_subparsers( help='Action names for \'{}\' auth level'.format( used_api_key_data['auth_level_name']), dest="chosen_action") for name, cli_object in map_of_available_actions.items(): if cli_object.api_object.endpoint_auth_level <= used_api_key_data[ 'auth_level']: child_parser = subparsers.add_parser( name=name, help=cli_object.help_description, add_help=False) cli_object.add_parser_args(child_parser) args = vars(parser.parse_args()) if args['chosen_action'] is not None: cli_object = map_of_available_actions[args['chosen_action']] cli_object.attach_args(args) if args['verbose'] is True: cli_object.init_verbose_mode() print( Color.control('Running \'{}\' in version \'{}\''.format( program_name, program_version))) if args['chosen_action'] != 'get_api_limits': # API limits checking should be done here, to ensure that user always will be able to run command in help mode. Also there is no need to run it in non verbose mode. api_object_api_limits = ApiApiLimits( config['api_key'], config['api_secret'], config['server']) api_object_api_limits.call(request_session, vxapi_cli_headers) api_limits_response_json = api_object_api_limits.get_response_json( ) # Ignore when WebService doesn't have that endpoint if api_object_api_limits.get_response_status_code() != 404: if api_object_api_limits.get_response_status_code( ) != 200 or api_limits_response_json[ 'response_code'] == -1: raise RetrievingApiKeyDataError( 'Can\'t check API limits before calling requested endpoint in webservice: \'{}\'. Response status code: \'{}\'' .format( config['server'], api_object_api_limits. get_response_status_code())) if api_object_api_limits.get_response_status_code( ) == 200 and api_limits_response_json[ 'response_code'] == 0 and api_limits_response_json[ 'response']['limit_reached'] is True: name_of_reached_limit = api_limits_response_json[ 'response']['name_of_reached_limit'] raise ReachedApiLimitError( 'Exceeded maximum API requests per {}({}). Please try again later.' .format( name_of_reached_limit, api_limits_response_json['response'] ['used'][name_of_reached_limit])) if api_object_api_limits.get_response_status_code( ) == 200 and api_limits_response_json['response_code'] == 0: api_usage = OrderedDict() api_usage_limits = api_limits_response_json[ 'response']['limits'] is_api_limit_reached = False for period, used_limit in api_limits_response_json[ 'response']['used'].items(): # Given request is made after checking api limits. It means that we have to add 1 to current limits, to simulate that what happen after making requested API call api_usage[period] = used_limit + 1 if is_api_limit_reached is False and api_usage[ period] == api_usage_limits[period]: is_api_limit_reached = True print(Color.control('API Limits for used API Key')) print('Webservice API usage limits: {}'.format( api_usage_limits)) print('Current API usage: {}'.format( json.dumps(api_usage))) print('Is limit reached: {}'.format( Color.success('No') if is_api_limit_reached is False else Color.error('Yes'))) print(Color.control('Used API Key')) print('API Key: {}'.format(used_api_key_data['api_key'])) print('Auth Level: {}'.format( used_api_key_data['auth_level_name'])) if used_api_key_data['user'] is not None: print('User: {} ({})'.format( used_api_key_data['user']['name'], used_api_key_data['user']['email'])) print( Color.control('Request was sent at ' + '{:%Y-%m-%d %H:%M:%S}'.format( datetime.datetime.now()))) print('Endpoint URL: {}'.format( cli_object.api_object.get_full_endpoint_url())) print('HTTP Method: {}'.format( cli_object.api_object.request_method_name.upper())) print('Sent GET params: {}'.format( cli_object.api_object.params)) print('Sent POST params: {}'.format( cli_object.api_object.data)) print('Sent files: {}'.format(cli_object.api_object.files)) cli_object.api_object.call(request_session, vxapi_cli_headers) if args['verbose'] is True: print( Color.control('Received response at ' + '{:%Y-%m-%d %H:%M:%S}'.format( datetime.datetime.now()))) print('Response status code: {}'.format( cli_object.get_colored_response_status_code())) print('Message: {}'.format( cli_object.get_colored_prepared_response_msg())) print(Color.control('Showing response')) print(cli_object.get_result_msg()) cli_object.do_post_processing() if args['verbose'] is True: print('\n') else: print( Color.control( 'No option was selected. To check CLI options, run script in help mode: \'{} -h\'' .format(__file__))) except Exception as exc: print( Color.control( 'During the code execution, error has occurred. Please try again or contact the support.' )) print(Color.error('Message: \'{}\'.').format(str(exc)) + '\n')