def set_config(self, additional_config_params): api_key_name = additional_config_params.get("api_key_name", "HONEYDB_API_KEY") api_id_name = additional_config_params.get("api_id_name", "HONEYDB_API_ID") self.analysis_type = additional_config_params.get( "honeydb_analysis", "all") self.endpoints = [ "scan_twitter", "ip_query", "ip_history", "internet_scanner", "ip_info", ] if self.analysis_type not in self.endpoints and self.analysis_type != "all": raise AnalyzerConfigurationException( f"analysis_type is not valid: {self.analysis_type}") self.__api_key = secrets.get_secret(api_key_name) self.__api_id = secrets.get_secret(api_id_name) if not self.__api_key: raise AnalyzerConfigurationException( "No HoneyDB API Key retrieved") if not self.__api_id: raise AnalyzerConfigurationException("No HoneyDB API ID retrieved") self.headers = { "X-HoneyDb-ApiKey": self.__api_key, "X-HoneyDb-ApiId": self.__api_id, } self.result = {}
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "MISP_KEY") self.__api_key = secrets.get_secret(self.api_key_name) self.url_key_name = additional_config_params.get( "url_key_name", "MISP_URL") self.url_name = secrets.get_secret(self.url_key_name)
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get("api_key_name", "XFORCE_KEY") self.api_password_name = additional_config_params.get( "api_password_name", "XFORCE_PASSWORD" ) self.__api_key = secrets.get_secret(self.api_key_name) self.__api_password = secrets.get_secret(self.api_password_name)
def set_config(self, additional_config_params): self.analysis_type = additional_config_params.get( "censys_analysis", "search") api_id_name = additional_config_params.get("api_id_name", "CENSYS_API_ID") api_secret_name = additional_config_params.get("api_secret_name", "CENSYS_API_SECRET") self.__api_id = secrets.get_secret(api_id_name) self.__api_secret = secrets.get_secret(api_secret_name)
def set_config(self, additional_config_params): api_key_name = additional_config_params.get("api_key_name", "HONEYDB_API_KEY") api_id_name = additional_config_params.get("api_id_name", "HONEYDB_API_ID") self.analysis_type = additional_config_params.get( "honeydb_analysis", "ip_query") self.__api_key = secrets.get_secret(api_key_name) self.__api_id = secrets.get_secret(api_id_name)
def run(analyzer_name, job_id, filepath, filename, md5, additional_config_params): logger.info("started analyzer {} job_id {}" "".format(analyzer_name, job_id)) report = general.get_basic_report_template(analyzer_name) try: # cuckoo installation can be with or without the api_token # it depends on version and configuration api_key_name = additional_config_params.get("api_key_name", "") if api_key_name: api_key = secrets.get_secret(api_key_name) else: api_key = None logger.info("job_id {} md5 {} analyzer {} no API key set" "".format(job_id, md5, analyzer_name)) cuckoo_url = secrets.get_secret("CUCKOO_URL") if not cuckoo_url: raise AnalyzerRunException("cuckoo URL missing") cuckoo_analysis = CuckooAnalysis(api_key, cuckoo_url) binary = general.get_binary(job_id) if not binary: raise AnalyzerRunException("is the binary empty?!") _cuckoo_scan_file(cuckoo_analysis, additional_config_params, filename, md5, binary) result = cuckoo_analysis.report # pprint.pprint(result) report["report"] = result except AnalyzerRunException as e: error_message = ( "job_id:{} analyzer:{} md5:{} filename: {} Analyzer Error {}" "".format(job_id, analyzer_name, md5, filename, e)) logger.error(error_message) report["errors"].append(error_message) report["success"] = False except Exception as e: traceback.print_exc() error_message = ( "job_id:{} analyzer:{} md5:{} filename: {} Unexpected Error {}" "".format(job_id, analyzer_name, md5, filename, e)) logger.exception(error_message) report["errors"].append(str(e)) report["success"] = False else: report["success"] = True general.set_report_and_cleanup(job_id, report) logger.info("ended analyzer {} job_id {}" "".format(analyzer_name, job_id)) return report
def run( analyzer_name, job_id, observable_name, observable_classification, additional_config_params, ): logger.info("started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) report = general.get_basic_report_template(analyzer_name) try: api_id_name = additional_config_params.get("api_id_name", "CENSYS_API_ID") api_secret_name = additional_config_params.get("api_secret_name", "CENSYS_API_SECRET") api_id = secrets.get_secret(api_id_name) api_secret = secrets.get_secret(api_secret_name) if not (api_id and api_secret): raise AnalyzerRunException("no api credentials retrieved") result = _censys_get_report( (api_id, api_secret), observable_name, observable_classification, additional_config_params, ) # pprint.pprint(result) report["report"] = result except AnalyzerRunException as e: error_message = ( "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" "".format(job_id, analyzer_name, observable_name, e)) logger.error(error_message) report["errors"].append(error_message) report["success"] = False except Exception as e: traceback.print_exc() error_message = ( "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" "".format(job_id, analyzer_name, observable_name, e)) logger.exception(error_message) report["errors"].append(str(e)) report["success"] = False else: report["success"] = True general.set_report_and_cleanup(job_id, report) logger.info("ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) return report
def run(self): result = {} headers = { "Content-Type": "application/json", "User-Agent": "IntelOwl/v1.x" } api_key = secrets.get_secret(self.api_key_name) if not api_key: if self.analysis_type == "search": logger.warning( f"{self.__repr__()} -> Continuing w/o API key..") else: raise AnalyzerRunException( f"No API key retrieved for name {self.api_key_name}.") else: headers["API-Key"] = api_key self.session = requests.Session() self.session.headers = headers if self.analysis_type == "search": result = self.__urlscan_search() elif self.analysis_type == "submit_result": req_api_token = self.__urlscan_submit() result = self.__poll_for_result(req_api_token) else: raise AnalyzerRunException( f"not supported analysis_type {self.analysis_type}." " Supported is 'search' and 'submit_result'.") return result
def run(self): if self.api_version == "v1": url = f"{self.base_url}/v1/query/ip" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = {"ip": self.observable_name} response = requests.post(url, data=data, headers=headers) response.raise_for_status() elif self.api_version == "v2": url = f"{self.base_url}/v2/noise/context/{self.observable_name}" api_key = secrets.get_secret(self.api_key_name) if not api_key: raise AnalyzerRunException(f"{self.api_key_name} not specified.") headers = {"Accept": "application/json", "key": api_key} response = requests.get(url, headers=headers) response.raise_for_status() else: raise AnalyzerRunException( "Invalid API Version. Supported are: v1 (free) & v2 (paid)." ) result = response.json() if "records" in result: result["records"] = result["records"][: self.max_records_to_retrieve] return result
def run(self): api_key = secrets.get_secret(self.api_key_name) if not api_key: raise AnalyzerRunException( f"no MISP API key retrieved with name: {self.api_key_name}") if not self.url_name: raise AnalyzerRunException( f"no MISP URL retrieved, key value: {self.url_key_name}") misp_instance = pymisp.ExpandedPyMISP(self.url_name, api_key) # debug=True) # we check only for events not older than 90 days and max 50 results now = datetime.datetime.now() date_from = now - datetime.timedelta(days=90) params = { # even if docs say to use "values",... # .. at the moment it works correctly only with "value" "value": self.observable_name, "type_attribute": [self.observable_classification], "date_from": date_from.strftime("%Y-%m-%d %H:%M:%S"), "limit": 50, "enforce_warninglist": True, } if self.observable_classification == "hash": params["type_attribute"] = ["md5", "sha1", "sha256"] result_search = misp_instance.search(**params) if isinstance(result_search, dict): errors = result_search.get("errors", []) if errors: raise AnalyzerRunException(errors) return {"result_search": result_search, "instance_url": self.url_name}
def get_verification(self, raw_instance: dict) -> ConfigVerificationType: # raw instance because input is json and not django model object # get all missing secrets secrets = raw_instance["secrets"] missing_secrets = [] for s_key, s_dict in secrets.items(): # check if available in environment secret_val = secrets_store.get_secret(s_dict["env_var_key"], default=None) if not secret_val and s_dict["required"]: missing_secrets.append(s_key) num_missing_secrets = len(missing_secrets) if num_missing_secrets: configured = False num_total_secrets = len(secrets.keys()) error_message = "(%s) not set; (%d of %d satisfied)" % ( ",".join(missing_secrets), num_total_secrets - num_missing_secrets, num_total_secrets, ) else: configured = True error_message = None return { "configured": configured, "error_message": error_message, "missing_secrets": missing_secrets, }
def run(self): api_key = secrets.get_secret(self.api_key_name) if not api_key: raise AnalyzerRunException( f"no API key retrieved with name: '{self.api_key_name}'" ) headers = { "Authorization": f"apikey {api_key}", "Content-Type": "application/json", } obs_clsfn = self.observable_classification if obs_clsfn == "domain": uri = f"domain/{self.observable_name}" elif obs_clsfn == "ip": uri = f"ip/{self.observable_name}" elif obs_clsfn == "url": uri = f"hostname/{self.observable_name}" else: raise AnalyzerRunException( f"not supported observable type {obs_clsfn}." " Supported are: ip, domain and url." ) try: response = requests.get(self.base_url + uri, headers=headers) response.raise_for_status() except requests.RequestException as e: raise AnalyzerRunException(e) return response.json()
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "MWDB_KEY") self.__api_key = secrets.get_secret(self.api_key_name) self.upload_file = additional_config_params.get("upload_file", False) self.max_tries = additional_config_params.get("max_tries", 50) self.poll_distance = 5
def run( analyzer_name, job_id, observable_name, observable_classification, additional_config_params, ): logger.info("started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) report = general.get_basic_report_template(analyzer_name) try: api_version = additional_config_params.get("greynoise_api_version", "v1") if api_version == "v1": url = "https://api.greynoise.io/v1/query/ip" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = {"ip": observable_name} response = requests.post(url, data=data, headers=headers) response.raise_for_status() elif api_version == "v2": url = f"https://api.greynoise.io/v2/noise/context/{observable_name}" api_key_name = additional_config_params.get( "api_key_name", "GREYNOISE_API_KEY") api_key = secrets.get_secret(api_key_name) if not api_key: raise AnalyzerRunException("GREYNOISE_API_KEY not specified.") headers = {"Accept": "application/json", "key": api_key} response = requests.get(url, headers=headers) response.raise_for_status() else: raise AnalyzerRunException( "Invalid API Version. Supported are: v1 (free) & v2 (paid).") result = response.json() report["report"] = result except AnalyzerRunException as e: error_message = ( "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" "".format(job_id, analyzer_name, observable_name, e)) logger.error(error_message) report["errors"].append(error_message) report["success"] = False except Exception as e: traceback.print_exc() error_message = ( "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" "".format(job_id, analyzer_name, observable_name, e)) logger.exception(error_message) report["errors"].append(str(e)) report["success"] = False else: report["success"] = True general.set_report_and_cleanup(job_id, report) logger.info("ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) return report
def run(analyzer_name, job_id, observable_name, observable_classification, additional_config_params): logger.info("started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) report = general.get_basic_report_template(analyzer_name) try: # You should save CIRCL credentials with this template: "<user>|<pwd>" credentials = secrets.get_secret("CIRCL_CREDENTIALS") if not credentials: raise AnalyzerRunException("no credentials retrieved") split_credentials = credentials.split('|') if len(split_credentials) != 2: raise AnalyzerRunException( "CIRCL credentials not properly configured." "Template to use: '<user>|<pwd>'") user = split_credentials[0] pwd = split_credentials[1] pdns = pypdns.PyPDNS(basic_auth=(user, pwd)) domain = observable_name if observable_classification == 'url': domain = urlparse(observable_name).hostname result = pdns.query(domain) for result_item in result: keys_to_decode = ['time_first', 'time_last'] for key_to_decode in keys_to_decode: time_extracted = result_item.get(key_to_decode, None) if time_extracted and isinstance(time_extracted, datetime.datetime): result_item[key_to_decode] = time_extracted.strftime( "%Y-%m-%d %H:%M:%S") # pprint.pprint(result) report['report'] = result except AnalyzerRunException as e: error_message = "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" \ "".format(job_id, analyzer_name, observable_name, e) logger.error(error_message) report['errors'].append(error_message) report['success'] = False except Exception as e: traceback.print_exc() error_message = "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" \ "".format(job_id, analyzer_name, observable_name, e) logger.exception(error_message) report['errors'].append(str(e)) report['success'] = False else: report['success'] = True general.set_report_and_cleanup(job_id, report, logger) logger.info("ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) return report
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "MISP_KEY") self.url_key_name = additional_config_params.get( "url_key_name", "MISP_URL") self.ssl_check = additional_config_params.get("ssl_check", True) self.debug = additional_config_params.get("debug", False) self.url_name = secrets.get_secret(self.url_key_name)
def run(analyzer_name, job_id, observable_name, observable_classification, additional_config_params): logger.info("started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) report = general.get_basic_report_template(analyzer_name) try: api_key_name = additional_config_params.get('api_key_name', 'HONEYDB_API_KEY') api_id_name = additional_config_params.get('api_id_name', 'HONEYDB_API_ID') api_key = secrets.get_secret(api_key_name) api_id = secrets.get_secret(api_id_name) if not api_key: raise AnalyzerRunException("no HoneyDB API Key retrieved") if not api_id: raise AnalyzerRunException("no HoneyDB API ID retrieved") headers = { 'X-HoneyDb-ApiKey': api_key, 'X-HoneyDb-ApiId': api_id } url = f'https://honeydb.io/api/twitter-threat-feed/{observable_name}' response = requests.get(url, headers=headers) response.raise_for_status() json_response = response.json() report['report'] = json_response except AnalyzerRunException as e: error_message = "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" \ "".format(job_id, analyzer_name, observable_name, e) logger.error(error_message) report['errors'].append(error_message) report['success'] = False except Exception as e: traceback.print_exc() error_message = "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" \ "".format(job_id, analyzer_name, observable_name, e) logger.exception(error_message) report['errors'].append(str(e)) report['success'] = False else: report['success'] = True general.set_report_and_cleanup(job_id, report, logger) logger.info("ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) return report
def set_config(self, additional_config_params): # cuckoo installation can be with or without the api_token # it depends on version and configuration self.session = requests.Session() api_key_name = additional_config_params.get("api_key_name", None) if api_key_name: api_key = secrets.get_secret(api_key_name) self.session.headers["Authorization"] = f"Bearer {api_key}" else: logger.info("job_id {} md5 {} analyzer {} no API key set." "".format(self.job_id, self.md5, self.analyzer_name)) self.cuckoo_url = secrets.get_secret("CUCKOO_URL") self.task_id = 0 self.result = {} # no. of tries requesting new scan self.max_post_tries = additional_config_params.get("max_post_tries", 5) # no. of tries when polling for result self.max_get_tries = additional_config_params.get("max_poll_tries", 20)
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "VT_KEY") self.__api_key = secrets.get_secret(self.api_key_name) self.additional_config_params = additional_config_params # max no. of tries when polling for result self.max_tries = additional_config_params.get("max_tries", 100) # interval b/w HTTP requests when polling self.poll_distance = 5
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "INQUEST_API_KEY" ) self.__api_key = secrets.get_secret(self.api_key_name) self.analysis_type = additional_config_params.get( "inquest_analysis", "dfi_search" ) self.generic_identifier_mode = "user-defined" # Or auto
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "ZOOMEYE_KEY") self.search_type = additional_config_params.get("search_type", "host") self.query = additional_config_params.get("query", "") self.page = additional_config_params.get("page", 1) self.facets = additional_config_params.get("facets", "") self.history = additional_config_params.get("history", True) self.__api_key = secrets.get_secret(self.api_key_name)
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "INTEZER_KEY") self.__api_key = secrets.get_secret(self.api_key_name) # max no. of tries when polling for result self.max_tries = additional_config_params.get("max_tries", 200) # interval b/w HTTP requests when polling self.poll_distance = 3 self.is_test = additional_config_params.get("is_test", False)
def run(analyzer_name, job_id, observable_name, observable_classification, additional_config_params): logger.info("started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) report = general.get_basic_report_template(analyzer_name) try: # You should save CIRCL credentials with this template: "<user>|<pwd>" credentials = secrets.get_secret("CIRCL_CREDENTIALS") if not credentials: raise AnalyzerRunException("no credentials retrieved") split_credentials = credentials.split('|') if len(split_credentials) != 2: raise AnalyzerRunException("CIRCL credentials not properly configured." "Template to use: '<user>|<pwd>'") user = split_credentials[0] pwd = split_credentials[1] pssl = pypssl.PyPSSL(basic_auth=(user, pwd)) result = pssl.query(observable_name) certificates = [] if result.get(observable_name, {}): certificates = list(result.get(observable_name).get('certificates', [])) parsed_result = {'ip': observable_name, 'certificates': []} for cert in certificates: subject = result.get(observable_name).get('subjects', {}).get(cert, {}).get('values', []) if subject: parsed_result['certificates'].append({'fingerprint': cert, 'subject': subject[0]}) # pprint.pprint(parsed_result) report['report'] = parsed_result except AnalyzerRunException as e: error_message = "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" \ "".format(job_id, analyzer_name, observable_name, e) logger.error(error_message) report['errors'].append(error_message) report['success'] = False except Exception as e: traceback.print_exc() error_message = "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" \ "".format(job_id, analyzer_name, observable_name, e) logger.exception(error_message) report['errors'].append(str(e)) report['success'] = False else: report['success'] = True general.set_report_and_cleanup(job_id, report, logger) logger.info("ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) return report
def run(self): api_key = secrets.get_secret(self.api_key_name) if not api_key: raise AnalyzerRunException( f"No API key retrieved with name: {self.api_key_name}") otx = OTXv2.OTXv2(api_key) obs_clsf = self.observable_classification to_analyze_observable = self.observable_name if obs_clsf == "ip": otx_type = OTXv2.IndicatorTypes.IPv4 elif obs_clsf == "url": to_analyze_observable = urlparse(self.observable_name).hostname try: to_analyze_observable = IPv4Address(to_analyze_observable) except AddressValueError: otx_type = OTXv2.IndicatorTypes.DOMAIN else: otx_type = OTXv2.IndicatorTypes.IPv4 if not to_analyze_observable: raise AnalyzerRunException("extracted observable is None") elif obs_clsf == "domain": otx_type = OTXv2.IndicatorTypes.DOMAIN elif obs_clsf == "hash": otx_type = OTXv2.IndicatorTypes.FILE_HASH_MD5 else: raise AnalyzerRunException( f"not supported observable classification {obs_clsf}") result = {} details = otx.get_indicator_details_full(otx_type, to_analyze_observable) result["pulses"] = (details.get("general", {}).get("pulse_info", {}).get("pulses", [])) # for some observables the output could really be overwhelming if not self.verbose and result["pulses"]: result["pulses"] = result["pulses"][:20] result["geo"] = details.get("geo", {}) result["malware_samples"] = [ d.get("hash", "") for d in details.get("malware", {}).get("data", []) ] result["passive_dns"] = details.get("passive_dns", {}).get("passive_dns", []) result["reputation"] = details.get("reputation", {}).get("reputation", None) result["url_list"] = details.get("url_list", {}).get("url_list", []) result["analysis"] = details.get("analysis", {}).get("analysis", {}) if not self.verbose: if result["analysis"] and "plugins" in result["analysis"]: result["analysis"]["plugins"] = "removed because too long" return result
def run( analyzer_name, job_id, observable_name, observable_classification, additional_config_params, ): logger.info( "started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name) ) report = general.get_basic_report_template(analyzer_name) try: api_key_name = additional_config_params.get("api_key_name", "") if not api_key_name: api_key_name = "AUTH0_KEY" api_key = secrets.get_secret(api_key_name) if not api_key: raise AnalyzerRunException("no api key retrieved") headers = {"X-Auth-Token": api_key} url = "https://signals.api.auth0.com/v2.0/ip/{}".format(observable_name) response = requests.get(url, headers=headers) response.raise_for_status() json_response = response.json() # pprint.pprint(json_response) report["report"] = json_response except AnalyzerRunException as e: error_message = ( "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" "".format(job_id, analyzer_name, observable_name, e) ) logger.error(error_message) report["errors"].append(error_message) report["success"] = False except Exception as e: traceback.print_exc() error_message = ( "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" "".format(job_id, analyzer_name, observable_name, e) ) logger.exception(error_message) report["errors"].append(str(e)) report["success"] = False else: report["success"] = True general.set_report_and_cleanup(job_id, report) logger.info( "ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name) ) return report
def set_config(self, additional_config_params): self.api_key_name = additional_config_params.get( "api_key_name", "UNPAC_ME_API_KEY") private = additional_config_params.get("private", False) self.private = "private" if private else "public" self.__api_key = secrets.get_secret(self.api_key_name) # max no. of tries when polling for result self.max_tries = additional_config_params.get("max_tries", 30) # interval b/w HTTP requests when polling self.poll_distance = 5
def set_config(self, additional_config_params): # cuckoo installation can be with or without the api_token # it depends on version and configuration self.session = requests.Session() api_key_name = additional_config_params.get("api_key_name", None) if api_key_name: api_key = secrets.get_secret(api_key_name) self.session.headers["Authorization"] = f"Bearer {api_key}" else: logger.info( f"{self.__repr__()}, (md5: {self.md5}) -> Continuing w/o API key.." ) self.cuckoo_url = secrets.get_secret("CUCKOO_URL") self.task_id = 0 self.result = {} # no. of tries requesting new scan self.max_post_tries = additional_config_params.get("max_post_tries", 5) # no. of tries when polling for result self.max_get_tries = additional_config_params.get("max_poll_tries", 20)
def set_config(self, additional_config_params): self.endpoint = additional_config_params.get("endpoint", "public") if self.endpoint == "private": self.base_url = self.private_url self.api_key_name = additional_config_params.get("api_key_name", "TRIAGE_KEY") self.__api_key = secrets.get_secret(self.api_key_name) self.report_type = additional_config_params.get("report_type", "overview") self.max_tries = additional_config_params.get("max_tries", 200) self.poll_distance = 3
def run( analyzer_name, job_id, observable_name, observable_classification, additional_config_params, ): logger.info("started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) report = general.get_basic_report_template(analyzer_name) try: api_key_name = additional_config_params.get("api_key_name", "") if not api_key_name: api_key_name = "ABUSEIPDB_KEY" api_key = secrets.get_secret(api_key_name) if not api_key: raise AnalyzerRunException("no api key retrieved") headers = {"Key": api_key, "Accept": "application/json"} params = { "ipAddress": observable_name, "maxAgeInDays": 180, "verbose": True } url = "https://api.abuseipdb.com/api/v2/check" response = requests.get(url, params=params, headers=headers) response.raise_for_status() json_response = response.json() # pprint.pprint(json_response) report["report"] = json_response except AnalyzerRunException as e: error_message = ( "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" "".format(job_id, analyzer_name, observable_name, e)) logger.error(error_message) report["errors"].append(error_message) report["success"] = False except Exception as e: traceback.print_exc() error_message = ( "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" "".format(job_id, analyzer_name, observable_name, e)) logger.exception(error_message) report["errors"].append(str(e)) report["success"] = False else: report["success"] = True general.set_report_and_cleanup(job_id, report) logger.info("ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name)) return report
def run( analyzer_name, job_id, observable_name, observable_classification, additional_config_params, ): logger.info( "started analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name) ) report = general.get_basic_report_template(analyzer_name) try: api_key_name = additional_config_params.get("api_key_name", "HUNTER_API_KEY") api_key = secrets.get_secret(api_key_name) if not api_key: raise AnalyzerRunException("no Hunter.io API Key retrieved") url = ( "https://api.hunter.io/v2/domain-search?" f"domain={observable_name}&api_key={api_key}" ) response = requests.get(url) response.raise_for_status() json_response = response.json() report["report"] = json_response except AnalyzerRunException as e: error_message = ( "job_id:{} analyzer:{} observable_name:{} Analyzer error {}" "".format(job_id, analyzer_name, observable_name, e) ) logger.error(error_message) report["errors"].append(error_message) report["success"] = False except Exception as e: traceback.print_exc() error_message = ( "job_id:{} analyzer:{} observable_name:{} Unexpected error {}" "".format(job_id, analyzer_name, observable_name, e) ) logger.exception(error_message) report["errors"].append(str(e)) report["success"] = False else: report["success"] = True general.set_report_and_cleanup(job_id, report) logger.info( "ended analyzer {} job_id {} observable {}" "".format(analyzer_name, job_id, observable_name) ) return report