GreyNoise Community
GreyNoise is a cybersecurity platform that collects and analyzes Internet-wide scan and attack traffic. With this integration, users can contextualize existing alerts, filter false-positives, identify compromised devices, and track emerging threats. This Integration is design specifically for GreyNoise Community users and only provides the subset of intel available via the GreyNoise Community API.
Data Enrichment & Threat Intelligence · GreyNoise
Details
| ID | GreyNoise Community |
|---|---|
| Provider | GreyNoise |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.5.0 |
| Docker Image | demisto/greynoise:1.0.0.10926121 |
| Supported Modules | Agentix XSIAM |
README
GreyNoise tells security analysts what not to worry about. We do this by curating data on IPs that saturate security
tools with noise. This unique perspective helps analysts confidently ignore irrelevant or harmless activity, creating
more time to uncover and investigate true threats. The Action allows IP enrichment via the GreyNoise Community API.
The GreyNoise Integration
should be used by customers with a paid subscription to GreyNoise with the exception of the IP command, which is available with limit results to free users.
This integration was integrated and tested with version 3.0.0 of GreyNoise Python SDK.
Supported Cortex XSOAR versions: 6.0.0 and later.
Configure GreyNoise in Cortex
| Parameter | Description | Required |
|---|---|---|
| api_key | GreyNoise API Key | True |
| proxy | Use system proxy settings | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
greynoise-community-lookup
Queries IPs in the GreyNoise Community API.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | List of IPs. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | The reliability value. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| IP.Address | string | IP address. |
| IP.ASN | string | ASN Value. |
| IP.Geo.Country | string | Source Country. |
| IP.Geo.Description | string | Additional Geo Information - City, Region, Country Code. |
| IP.Hostname | string | rDNS value. |
| IP.Malicious.Description | string | Description of Malicious IP. |
| IP.Malicious.Vendor | string | Vendor Identifying IP as Malicious. |
| GreyNoise.IP.actor | string | Name of identified organization scanning. |
| GreyNoise.IP.address | string | The IP address of the scanning device IP. |
| GreyNoise.IP.bot | boolean | Identifies if the IP is associated with BOT activity. |
| GreyNoise.IP.category | string | If a business service, identifies the category. |
| GreyNoise.IP.classification | string | Whether the device has been categorized as unknown, benign, or malicious. |
| GreyNoise.IP.description | string | If there is a business service, provides a description of the provider. |
| GreyNoise.IP.explanation | string | If there is a business service, provides an explanation of the category. |
| GreyNoise.IP.first_seen | string | The date of the first observed scanning activity. |
| GreyNoise.IP.found | boolean | Whether the IP is found in GreyNoise. |
| GreyNoise.IP.ip | string | The IP address of the scanning device IP. |
| GreyNoise.IP.last_seen | string | The date of the last observed scanning activity. |
| GreyNoise.IP.last_seen_timestamp | string | The timestamp of the last observed scanning activity. |
| GreyNoise.IP.last_updated | string | If there is a business service, indicates the last time the source record was parsed. |
| GreyNoise.IP.metadata.asn | string | The autonomous system identification number. |
| GreyNoise.IP.metadata.carrier | string | The carrier information for the IP address. |
| GreyNoise.IP.metadata.category | string | Whether the device belongs to a business, isp, hosting, education, or mobile network. |
| GreyNoise.IP.metadata.datacenter | string | The datacenter information for the IP address. |
| GreyNoise.IP.metadata.destination_countries | array | The list of countries targeted by scanning. |
| GreyNoise.IP.metadata.destination_country_codes | array | The list of country codes targeted by scanning. |
| GreyNoise.IP.metadata.domain | string | The domain associated with the IP address. |
| GreyNoise.IP.metadata.latitude | number | The latitude coordinate of the IP address location. |
| GreyNoise.IP.metadata.longitude | number | The longitude coordinate of the IP address location. |
| GreyNoise.IP.metadata.mobile | boolean | Whether the device is on a mobile network. |
| GreyNoise.IP.metadata.organization | string | The organization that owns the network that the IP address belongs to. |
| GreyNoise.IP.metadata.os | string | The name of the operating system of the device. |
| GreyNoise.IP.metadata.rdns | string | Reverse DNS lookup of the IP address. |
| GreyNoise.IP.metadata.rdns_parent | string | The parent domain of the reverse DNS lookup. |
| GreyNoise.IP.metadata.rdns_validated | boolean | Whether the reverse DNS lookup has been validated. |
| GreyNoise.IP.metadata.region | string | The full name of the region the device is geographically located in. |
| GreyNoise.IP.metadata.sensor_count | number | The number of sensors that observed activity from this IP. |
| GreyNoise.IP.metadata.sensor_hits | number | The number of sensors events recorded from this IP. |
| GreyNoise.IP.metadata.single_destination | boolean | Whether the IP targets a single destination. |
| GreyNoise.IP.metadata.source_city | string | The city where the IP is geographically located. |
| GreyNoise.IP.metadata.source_country | string | The full name of the IP source country. |
| GreyNoise.IP.metadata.source_country_code | string | The country code of the IP source country. |
| GreyNoise.IP.name | string | If there is a business service, indicates the provider name. |
| GreyNoise.IP.raw_data.source.bytes | number | The number of bytes sent by the source. |
| GreyNoise.IP.reference | string | If there is a business service, indicates the references used to validate the entry. |
| GreyNoise.IP.riot | boolean | Whether the IP is in the business services dataset. |
| GreyNoise.IP.seen | boolean | Whether the IP is in the internet scanner dataset. |
| GreyNoise.IP.spoofable | boolean | Whether the IP complete a three-way handshake during scanning. |
| GreyNoise.IP.tags.category | string | The category of the given tag. |
| GreyNoise.IP.tags.created | date | The date the tag was added to the GreyNoise system. |
| GreyNoise.IP.tags.description | string | A description of what the tag identifies. |
| GreyNoise.IP.tags.id | string | The unique id of the tag. |
| GreyNoise.IP.tags.intention | string | The intention of the associated activity the tag identifies. |
| GreyNoise.IP.tags.name | string | The name of the tag. |
| GreyNoise.IP.tags.recommend_block | boolean | Indicates if IPs associated with this tag should be blocked. |
| GreyNoise.IP.tags.references | string | A list of references used to create the tag. |
| GreyNoise.IP.tags.slug | string | The unique slug of the tag. |
| GreyNoise.IP.tags.updated_at | date | The date the tag was last updated. |
| GreyNoise.IP.tor | boolean | Whether the IP is on the known TOR exit node list. |
| GreyNoise.IP.trust_level | string | If there is a business service, indicates the level of trustworthiness. |
| GreyNoise.IP.vpn | boolean | Whether the IP is associated with a knwon VPN service. |
| GreyNoise.IP.vpn_service | string | If the IP is part of a VPN, provides the name of the service. |
Command Example
!greynoise-community-lookup ips=1.1.1.1
!IPReputation ip=1.1.1.1
Human Readable Output
IP: 1.1.1.1 found with Reputation: Good
Belongs to Common Business Service: Cloudflare Public DNS
GreyNoise Business Service Intelligence Lookup
| IP | Business Service | Category | Name | Trust Level | Description | Last Updated |
|---|---|---|---|---|---|---|
| 1.1.1.1 | true | public_dns | Cloudflare Public DNS | 1 - Reasonably Ignore | Cloudflare, Inc. is an American web infrastructure and website security company, providing content delivery network (CDN) services, distributed denial of service (DDoS) mitigation, Internet security, and distributed domain name system (DNS) services. This is their public DNS offering. | 2025-06-26T09:10:56Z |
IP: 1.1.1.1 No Mass-Internet Scanning Observed
GreyNoise Internet Scanner Intelligence Lookup
| IP | Internet Scanner |
|---|---|
| 1.1.1.1 | false |
Configuration parameters
integrationReliability— Integration ReliabilityfeedExpirationPolicy—feedExpirationInterval—api_key— API Keycredentials— API Keyproxy— Use system proxy settings
Commands (1)
-
ipGathers information on the IP from the GreyNoise Community API.
import demistomock as demisto from CommonServerPython import * from CommonServerUserPython import * """ Imports """ import copy import traceback import requests import urllib3 # type: ignore from greynoise.api import GreyNoise, APIConfig # type: ignore from greynoise import exceptions, util # type: ignore # Disable insecure warnings urllib3.disable_warnings() util.LOGGER.warning = util.LOGGER.debug """ CONSTANTS """ PRETTY_KEY = PRETTY_KEY = { "ip": "IP", "first_seen": "First Seen", "last_seen": "Last Seen", "last_seen_timestamp": "Last Seen Timestamp", "seen": "Internet Scanner", "tags": "Tags", "actor": "Actor", "spoofable": "Spoofable", "classification": "Classification", "cve": "CVE", "metadata": "MetaData", "asn": "ASN", "city": "City", "country": "Country", "country_code": "Country Code", "destination_countries": "Destination Countries", "destination_country_codes": "Destination Country Codes", "organization": "Organization", "category": "Category", "sensor_count": "Sensor Count", "sensor_hits": "Sensor Hits", "source_country": "Source Country", "source_country_code": "Source Country Code", "tor": "Tor", "rdns": "rDNS", "os": "OS", "region": "Region", "vpn": "VPN", "vpn_service": "VPN Service", "raw_data": "Raw Data", "scan": "Scan", "port": "Port", "protocol": "Protocol", "web": "Web", "path": "Web Paths", "useragent": "User-Agents", "ja3": "JA3", "fingerprint": "Fingerprint", "hassh": "HASSH", "bot": "BOT", "ja4": "JA4", "cipher": "Cipher", "md5": "MD5", "trust_level": "Trust Level", "address": "Address", "found": "Found", } IP_CONTEXT_HEADERS = [ "IP", "Internet Scanner", "Classification", "Actor", "CVE", "Tags", "Spoofable", "VPN", "BOT", "Tor", "Last Seen Timestamp", ] RIOT_HEADERS = [ "IP", "Business Service", "Category", "Name", "Trust Level", "Description", "Last Updated", ] EXCEPTION_MESSAGES = { "API_RATE_LIMIT": "API Rate limit hit. Try after sometime.", "UNAUTHENTICATED": "Unauthenticated. Check the configured API Key.", "COMMAND_FAIL": "Failed to execute {} command.\n Error: {}", "SERVER_ERROR": "The server encountered an internal error for GreyNoise and was unable to complete your request.", "CONNECTION_TIMEOUT": "Connection timed out. Check your network connectivity.", "PROXY": "Proxy Error - cannot connect to proxy. Either try clearing the " "'Use system proxy' check-box or check the host, " "authentication details and connection details for the proxy.", "INVALID_RESPONSE": "Invalid response from GreyNoise. Response: {}", "QUERY_STATS_RESPONSE": "GreyNoise request failed. Reason: {}", } """ CLIENT CLASS """ class Client(GreyNoise): """Client class to interact with the service API""" def authenticate(self): """ Used to authenticate GreyNoise credentials. """ try: self.test_connection() return "ok" except exceptions.RateLimitError: raise DemistoException(EXCEPTION_MESSAGES["API_RATE_LIMIT"]) except exceptions.RequestFailure as err: status_code = err.args[0] body = str(err.args[1]) if status_code == 401: raise DemistoException(EXCEPTION_MESSAGES["UNAUTHENTICATED"]) elif status_code == 429: raise DemistoException(EXCEPTION_MESSAGES["API_RATE_LIMIT"]) elif 400 <= status_code < 500: raise DemistoException(EXCEPTION_MESSAGES["COMMAND_FAIL"].format(demisto.command(), body)) elif status_code >= 500: raise DemistoException(EXCEPTION_MESSAGES["SERVER_ERROR"]) else: raise DemistoException(str(err)) except requests.exceptions.ConnectTimeout: raise DemistoException(EXCEPTION_MESSAGES["CONNECTION_TIMEOUT"]) except requests.exceptions.ProxyError: raise DemistoException(EXCEPTION_MESSAGES["PROXY"]) """ HELPER FUNCTIONS """ def exception_handler(func: Any) -> Any: """ Decorator to handle all type of errors possible with GreyNoise SDK. """ def inner_func(*args, **kwargs): try: return func(*args, **kwargs) except exceptions.RateLimitError: raise DemistoException(EXCEPTION_MESSAGES["API_RATE_LIMIT"]) except exceptions.RequestFailure as err: status_code = err.args[0] body = str(err.args[1]) if status_code == 401: raise DemistoException(EXCEPTION_MESSAGES["UNAUTHENTICATED"]) elif status_code == 429: raise DemistoException(EXCEPTION_MESSAGES["API_RATE_LIMIT"]) elif 400 <= status_code < 500: raise DemistoException(EXCEPTION_MESSAGES["COMMAND_FAIL"].format(demisto.command(), body)) elif status_code >= 500: raise DemistoException(EXCEPTION_MESSAGES["SERVER_ERROR"]) else: raise DemistoException(str(err)) except requests.exceptions.ConnectTimeout: raise DemistoException(EXCEPTION_MESSAGES["CONNECTION_TIMEOUT"]) except requests.exceptions.ProxyError: raise DemistoException(EXCEPTION_MESSAGES["PROXY"]) return inner_func def get_ip_context_data(responses: list) -> list: """Parse ip context and raw data from GreyNoise SDK response. Returns value of ip context data. Returns value of ip raw data. :type responses: ``list`` :param responses: list of values of ip-context or ip-query. :return: list of ips context data. :rtype: ``list`` """ ip_context_responses = [] responses = remove_empty_elements(responses) for response in responses: metadata_list: list = [] tmp_response: dict = {} tags = get_ip_tag_names(response.get("tags", [])) response["tags"] = tags for key, value in response.get("metadata", {}).items(): if value != "": metadata_list.append(f"{PRETTY_KEY.get(key, key)}: {value}") tmp_response["MetaData"] = metadata_list for key, value in response.items(): if value != "" and key not in ["metadata", "raw_data"]: tmp_response[PRETTY_KEY.get(key, key)] = value ip = tmp_response["IP"] tmp_response["IP"] = f"[{ip}](https://viz.greynoise.io/ip/{ip})" ip_context_responses.append(tmp_response) return ip_context_responses def get_ip_reputation_score(classification: str) -> tuple[int, str]: """Get DBot score and human-readable of score. :type classification: ``str`` :param classification: classification of ip provided from GreyNoise. :return: tuple of dbot score and it's readable form. :rtype: ``tuple`` """ if classification == "benign": return Common.DBotScore.GOOD, "Good" elif classification == "suspicious": return Common.DBotScore.SUSPICIOUS, "Suspicious" elif classification == "malicious": return Common.DBotScore.BAD, "Bad" else: return Common.DBotScore.NONE, "Unknown" def get_ip_tag_names(tags: list) -> list: """Get tag names from tags list. :type tags: ``list`` :param tags: list of tags. :return: list of tag names. :rtype: ``list`` """ tag_names = [] for tag in tags: tag_name = tag.get("name") + " (" + tag.get("intention") + " - " + tag.get("category") + ")" tag_names.append(tag_name) return tag_names """ COMMAND FUNCTIONS """ @exception_handler @logger def test_module(client: Client) -> str: """Tests API connectivity and authentication' Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. Raises exceptions if something goes wrong. :type client: ``Client`` :param client: Client object for interaction with GreyNoise. :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ return client.authenticate() @exception_handler @logger def ip_reputation_command(client: Client, args: dict, reliability: str) -> List[CommandResults]: """Get information about a given IP address. Returns classification (benign, malicious or unknown), IP metadata (network owner, ASN, reverse DNS pointer, country), associated actors, activity tags, and raw port scan and web request information. :type client: ``Client`` :param client: Client object for interaction with GreyNoise. :type args: ``dict`` :param args: All command arguments, usually passed from ``demisto.args()``. :return: A list of ``CommandResults`` object that is then passed to ``return_results``, that contains the IP information. :rtype: ``List[CommandResults]`` :type reliability: ``String`` :param reliability: string """ ips = argToList(args.get("ip"), ",") command_results = [] for ip in ips: try: demisto.debug(f"Querying GreyNoise with ip: {ip}") api_response = client.ip(ip) except Exception as e: demisto.debug(f"Error in ip_reputation_command: {e}") raise DemistoException(EXCEPTION_MESSAGES["INVALID_RESPONSE"].format(e)) if "internet_scanner_intelligence" in api_response: response = copy.deepcopy(api_response["internet_scanner_intelligence"]) response["seen"] = response.get("found", False) response["address"] = api_response["ip"] response["ip"] = api_response["ip"] riot_response = copy.deepcopy(api_response["business_service_intelligence"]) riot_response["riot"] = riot_response.get("found", False) riot_response["address"] = api_response["ip"] else: response = {} riot_response = {} original_response = copy.deepcopy(api_response) tmp_response = get_ip_context_data([response]) response = remove_empty_elements(response) riot_response = remove_empty_elements(riot_response) if riot_response["riot"]: if riot_response.get("trust_level") == "1": riot_response["classification"] = "benign" riot_response["trust_level"] = "1 - Reasonably Ignore" elif riot_response.get("trust_level") == "2": riot_response["classification"] = "unknown" riot_response["trust_level"] = "2 - Commonly Seen" elif riot_response.get("trust_level") == "3": riot_response["classification"] = "unknown" riot_response["trust_level"] = "3 - Context Only" if riot_response.get("logo_url", "") != "": del riot_response["logo_url"] if original_response.get("business_service_intelligence", {}).get("logo_url", "") != "": del original_response["business_service_intelligence"]["logo_url"] if response["seen"] and response.get("classification") == "malicious": malicious_description = "This IP has been observed scanning the internet in a malicious manner." else: malicious_description = "" # Prepare the output response - this should be the full API response with ip renamed to address # without modifying the nested objects output_response = copy.deepcopy(original_response) if "ip" in output_response: output_response["address"] = output_response["ip"] del output_response["ip"] if response["seen"] and not riot_response["riot"]: dbot_score_int, dbot_score_string = get_ip_reputation_score(response.get("classification")) human_readable = f"### IP: {ip} found with Reputation: {dbot_score_string}\n" human_readable += tableToMarkdown( name="GreyNoise Internet Scanner Intelligence Lookup", t=tmp_response, headers=IP_CONTEXT_HEADERS, removeNull=True ) riot_tmp_response = {"IP": riot_response.get("address"), "Business Service": riot_response.get("riot")} human_readable += f"### IP: {ip} Not Associated with a Business Service\n" human_readable += tableToMarkdown( name="GreyNoise Business Service Intelligence Lookup", t=riot_tmp_response, headers=["IP", "Business Service"], removeNull=False, ) dbot_score = Common.DBotScore( indicator=response.get("address"), indicator_type=DBotScoreType.IP, score=dbot_score_int, integration_name="GreyNoise", malicious_description=malicious_description, reliability=reliability, ) city = response.get("metadata", {}).get("source_city", "") region = response.get("metadata", {}).get("region", "") country_code = response.get("metadata", {}).get("source_country_code", "") geo_description = ( f"City: {city}, Region: {region}, Country Code: {country_code}" if (city or region or country_code) else "" ) ip_standard_context = Common.IP( ip=response.get("address"), asn=response.get("metadata", {}).get("asn"), hostname=response.get("actor"), geo_country=response.get("metadata", {}).get("source_country"), geo_description=geo_description, dbot_score=dbot_score, ) command_results.append( CommandResults( readable_output=human_readable, outputs_prefix="GreyNoise.IP", outputs_key_field="address", outputs=output_response, indicator=ip_standard_context, raw_response=original_response, ) ) if riot_response["riot"] and not response["seen"]: riot_tmp_response = { "IP": f"[{riot_response.get('address')}](https://viz.greynoise.io/ip/{riot_response.get('address')})", "Business Service": riot_response.get("riot"), "Name": riot_response.get("name"), "Category": riot_response.get("category"), "Trust Level": riot_response.get("trust_level"), "Description": riot_response.get("description"), "Last Updated": riot_response.get("last_updated"), } dbot_score_int, dbot_score_string = get_ip_reputation_score(riot_response.get("classification")) human_readable = f"### IP: {ip} found with Reputation: {dbot_score_string}\n" human_readable += f"#### Belongs to Common Business Service: {riot_response.get('name', 'Unknown')}\n" human_readable += tableToMarkdown( name="GreyNoise Business Service Intelligence Lookup", t=riot_tmp_response, headers=RIOT_HEADERS, removeNull=False ) tmp_response = [{"IP": response.get("address"), "Internet Scanner": response.get("seen")}] human_readable += f"### IP: {ip} No Mass-Internet Scanning Observed\n" human_readable += tableToMarkdown( name="GreyNoise Internet Scanner Intelligence Lookup", t=tmp_response, headers=["IP", "Internet Scanner"], removeNull=False, ) dbot_score = Common.DBotScore( indicator=response.get("address"), indicator_type=DBotScoreType.IP, score=dbot_score_int, integration_name="GreyNoise", malicious_description=malicious_description, reliability=reliability, ) ip_standard_context = Common.IP(ip=response.get("address"), dbot_score=dbot_score) command_results.append( CommandResults( readable_output=human_readable, outputs_prefix="GreyNoise.IP", outputs_key_field="address", outputs=output_response, indicator=ip_standard_context, raw_response=original_response, ) ) if response["seen"] and riot_response["riot"]: combo_response = response.copy() combo_response.update(riot_response) dbot_score_int, dbot_score_string = get_ip_reputation_score(response.get("classification")) human_readable = f"### IP: {ip} found with Reputation: {dbot_score_string}\n" human_readable += tableToMarkdown( name="GreyNoise Internet Scanner Intelligence Lookup", t=tmp_response, headers=IP_CONTEXT_HEADERS, removeNull=True ) dbot_score = Common.DBotScore( indicator=response.get("address"), indicator_type=DBotScoreType.IP, score=dbot_score_int, integration_name="GreyNoise", malicious_description=malicious_description, reliability=reliability, ) city = response.get("metadata", {}).get("source_city", "") region = response.get("metadata", {}).get("region", "") country_code = response.get("metadata", {}).get("source_country_code", "") geo_description = ( f"City: {city}, Region: {region}, Country Code: {country_code}" if (city or region or country_code) else "" ) ip_standard_context = Common.IP( ip=response.get("address"), asn=response.get("metadata", {}).get("asn"), hostname=response.get("actor"), geo_country=response.get("metadata", {}).get("source_country"), geo_description=geo_description, dbot_score=dbot_score, ) riot_tmp_response = { "IP": f"[{riot_response.get('address')}](https://viz.greynoise.io/ip/{riot_response.get('address')})", "Business Service": riot_response.get("riot"), "Name": riot_response.get("name"), "Category": riot_response.get("category"), "Trust Level": riot_response.get("trust_level"), "Description": riot_response.get("description"), "Last Updated": riot_response.get("last_updated"), } human_readable += f"### IP: {ip} found with Reputation: {dbot_score_string}\n" human_readable += f"#### Belongs to Common Business Service: {riot_response.get('name', 'Unknown')}\n" human_readable += tableToMarkdown( name="GreyNoise Business Service Intelligence Lookup", t=riot_tmp_response, headers=RIOT_HEADERS, removeNull=False ) command_results.append( CommandResults( readable_output=human_readable, outputs_prefix="GreyNoise.IP", outputs_key_field="address", outputs=output_response, indicator=ip_standard_context, raw_response=original_response, ) ) if not response["seen"] and not riot_response["riot"]: combo_response = response.copy() combo_response.update(riot_response) combo_tmp_response = { "IP": combo_response.get("address"), "Business Service": combo_response.get("riot"), "Internet Scanner": combo_response.get("seen"), } dbot_score_int, dbot_score_string = get_ip_reputation_score(combo_response.get("classification")) dbot_score = Common.DBotScore( indicator=combo_response.get("address"), indicator_type=DBotScoreType.IP, score=dbot_score_int, integration_name="GreyNoise", malicious_description=malicious_description, reliability=reliability, ) ip_standard_context = Common.IP(ip=response.get("address"), dbot_score=dbot_score) human_readable = f"### IP: {ip} No Mass-Internet Scanning Observed\n" human_readable += tableToMarkdown( name="GreyNoise Internet Scanner Intelligence Lookup", t=combo_tmp_response, headers=["IP", "Internet Scanner"], removeNull=True, ) human_readable += f"### IP: {ip} Not Associated with a Business Service\n" human_readable += tableToMarkdown( name="GreyNoise Business Service Intelligence Lookup", t=combo_tmp_response, headers=["IP", "Business Service"], removeNull=True, ) command_results.append( CommandResults( readable_output=human_readable, outputs_prefix="GreyNoise.IP", outputs_key_field="address", indicator=ip_standard_context, outputs=output_response, raw_response=original_response, ) ) return command_results """ MAIN FUNCTION """ def main() -> None: # pragma: no cover """main function, parses params and runs command functions :return: :rtype: """ # get pack version - use default if any step fails # get pack version - use default if any step fails pack_version = "2.1.0" try: pack_version = get_pack_version() except Exception as e: demisto.debug(f"Failed to retrieve pack version, using default: {str(e)}") api_key = demisto.params().get("credentials", {}).get("password") or demisto.params().get("api_key") if not api_key: return_error("Please provide a valid API token") proxy = demisto.params().get("proxy", False) reliability = demisto.params().get("integrationReliability", "B - Usually reliable") reliability = reliability if reliability else DBotScoreReliability.B if DBotScoreReliability.is_valid_type(reliability): reliability = DBotScoreReliability.get_dbot_score_reliability_from_str(reliability) else: Exception("Please provide a valid value for the Integration Reliability parameter.") demisto.debug(f"Command being called is {demisto.command()}") try: api_config = APIConfig( api_key=api_key, proxy=handle_proxy("proxy", proxy).get("https", ""), use_cache=False, integration_name=f"xsoar-community-integration-v{pack_version}", psychic=False, ) client = Client(api_config) if demisto.command() == "test-module": # This is the call made when pressing the integration Test button. result: Any = test_module(client) return_results(result) elif demisto.command() == "ip": result = ip_reputation_command(client, demisto.args(), reliability) return_results(result) # Log exceptions and return errors except exceptions.RequestFailure: raise DemistoException(EXCEPTION_MESSAGES["UNAUTHENTICATED"]) except Exception as err: demisto.error(traceback.format_exc()) # print the traceback return_error(EXCEPTION_MESSAGES["COMMAND_FAIL"].format(demisto.command(), str(err))) """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()