Team Cymru Scout
Team Cymru's Scout integration with Palo Alto XSOAR helps streamline incident triage and accelerate threat response by providing domain and threat intelligence data.
Data Enrichment & Threat Intelligence · Team Cymru
Details
| ID | Team Cymru Scout |
|---|---|
| Provider | Audax Private Equity |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Overview
Team Cymru’s Scout integration with Palo Alto XSOAR helps streamline incident triage and accelerate threat response by providing domain and threat intelligence data.
This integration was integrated and tested with API of Team Cymru Scout.
Key Features
- Leverage communication data to identify correlations between IP addresses, identify compromised hosts, and uncover other indications of an attack.
- Access a quick summary of NetFlow communications, Whois information, PDNS, X509 certificates, and fingerprinting details.
- Supports both IPv4 and IPv6 address queries.
- Provides real-time threat intelligence and helps in identifying and mitigating potential security threats.
- Offers extensive documentation and support resources to assist with setup, configuration, and troubleshooting.
Prerequisites for configuring integration instance
- Access to the Team Cymru Scout platform.
- An API Key or Basic Auth credentials for authentication.
Generate API Keys
If you prefer to use an API key for authentication, you can generate one as follows:
- Go to the API Keys page.
- Click on the “Create” button.
- Provide the description for the key, if needed.
- Click on the “Create Key” button to generate the API key.
Note:
- The number of API keys allowed for each organization is equal to the number of user seats. Therefore, an individual user may have multiple keys, but all the users in your organization may have a maximum of 5 keys. The API Keys page shows the total number of keys used by your organization.
- If the “Create” button is disabled, it indicates that you have reached the maximum number of keys allowed for your organization. To generate a new key, you need to:
- Click on the “Revoke” button next to an old key.
- Click on the “Create Key” button to start generating a new key.
Configure Team Cymru Scout in Cortex
- Navigate to Settings > Integrations
- Search for Team Cymru Scout.
- Click Add instance to create and configure a new integration instance.
| Parameter | Description | Required |
|---|---|---|
| Authentication Type | The authentication type used for secure communication with the Team Cymru Scout platform. | True |
| API Key | The API key used for secure communication with the Team Cymru Scout platform. Required if “API Key” as Authentication Type is selected. | False |
| Username, Password | The username and password used for secure communication with the Team Cymru Scout platform. Required if “Basic Auth” as Authentication Type is selected. | False |
| Source Reliability | Reliability of the source providing the intelligence data. | False |
| Create relationships | Create relationships between indicators as part of enrichment. | False |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | 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.
scout-api-usage
Returns all the information on used queries and remaining queries with the query limit.
Base Command
scout-api-usage
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| TeamCymruScout.QueryUsage.command_name | String | The name of the Cortex XSOAR command that triggered the Foundation API. |
| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. |
| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. |
| TeamCymruScout.QueryUsage.query_limit | Number | The total number of queries allowed. |
| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used for the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Number | The total number of queries allowed for the Foundation API. |
Command example
#### Context Example
```json
{
"TeamCymruScout": {
"QueryUsage": {
"command_name": "scout-api-usage",
"foundation_api_usage": {
"query_limit": 0,
"remaining_queries": 0,
"used_queries": 9
},
"query_limit": 50000,
"remaining_queries": 49834,
"used_queries": 166
}
}
}
Human Readable Output
API Usage
Used Queries Remaining Queries Query Limit Foundation Used Queries Foundation Remaining Queries Foundation Query Limit 166 49834 50000 9 0 0
ip
Return all the detailed information available for the given IP address.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | The IP address for which to retrieve available IP details. | Required |
| start_date | The start date for detailed information. Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd. For example: 01 June 2024, 2024-06-17. Default is 30 days. |
Optional |
| end_date | The end date for detailed information. Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd. For example: 01 June 2024, 2024-06-17. Default is now. |
Optional |
| days | Relative offset in days from the current time. It cannot exceed the maximum range of 30 days. Note: This will take priority over start_date and end_date if all three are passed. |
Optional |
| size | The maximum number of records to return. Note: The maximum allowed size is 1000. |
Optional |
| force_use_scout_details_api | If set to yes, it will forcefully use the Scout Details API endpoint, overriding the “Use Foundation API for IP enrichment” parameter in the integration configuration. Possible values are: Yes, No. Default is No. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| IP.Address | String | IP address. |
| IP.Relationships.EntityA | String | The source of the relationship. |
| IP.Relationships.EntityB | String | The destination of the relationship. |
| IP.Relationships.Relationship | String | The name of the relationship. |
| IP.Relationships.EntityAType | String | The type of the source of the relationship. |
| IP.Relationships.EntityBType | String | The type of the destination of the relationship. |
| IP.ASN | String | The autonomous system name for the IP address, for example: “AS8948”. |
| IP.Hostname | String | The hostname that is mapped to this IP address. |
| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. |
| IP.Geo.Country | String | The country in which the IP address is located. |
| IP.Geo.Description | String | Additional information about the location. |
| IP.DetectionEngines | Number | The total number of engines that checked the indicator. |
| IP.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. |
| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. |
| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. |
| IP.Tags | Unknown | (List) Tags of the IP address. |
| IP.FeedRelatedIndicators.value | String | Indicators that are associated with the IP address. |
| IP.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the IP address. |
| IP.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the IP address. |
| IP.MalwareFamily | String | The malware family associated with the IP address. |
| IP.Organization.Name | String | The organization of the IP address. |
| IP.Organization.Type | String | The organization type of the IP address. |
| IP.ASOwner | String | The autonomous system owner of the IP address. |
| IP.Region | String | The region in which the IP address is located. |
| IP.Port | String | Ports that are associated with the IP address. |
| IP.Internal | Boolean | Whether the IP address is internal or external. |
| IP.UpdatedDate | Date | The date that the IP address was last updated. |
| IP.Registrar.Abuse.Name | String | The name of the contact for reporting abuse. |
| IP.Registrar.Abuse.Address | String | The address of the contact for reporting abuse. |
| IP.Registrar.Abuse.Country | String | The country of the contact for reporting abuse. |
| IP.Registrar.Abuse.Network | String | The network of the contact for reporting abuse. |
| IP.Registrar.Abuse.Phone | String | The phone number of the contact for reporting abuse. |
| IP.Registrar.Abuse.Email | String | The email address of the contact for reporting abuse. |
| IP.Campaign | String | The campaign associated with the IP address. |
| IP.TrafficLightProtocol | String | The Traffic Light Protocol (TLP) color that is suitable for the IP address. |
| IP.CommunityNotes.note | String | Notes on the IP address that were given by the community. |
| IP.CommunityNotes.timestamp | Date | The time in which the note was published. |
| IP.Publications.source | String | The source in which the article was published. |
| IP.Publications.title | String | The name of the article. |
| IP.Publications.link | String | A link to the original article. |
| IP.Publications.timestamp | Date | The time in which the article was published. |
| IP.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. |
| IP.ThreatTypes.threatcategoryconfidence | String | The confidence level provided by the vendor for the threat type category For example, a confidence of 90 for the threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware. |
| TeamCymruScout.QueryUsage.request_id | String | The request ID of the API call. |
| TeamCymruScout.QueryUsage.size | Number | The number of records returned. |
| TeamCymruScout.QueryUsage.start_date | Date | The earliest date for detailed information. |
| TeamCymruScout.QueryUsage.end_date | Date | The latest date for detailed information. |
| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. |
| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. |
| TeamCymruScout.QueryUsage.query_limit | Number | The maximum number of queries allowed. |
| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used by the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Numbe | The maximum number of queries allowed for the Foundation API. |
| TeamCymruScout.IP.ip | String | The IP address. |
| TeamCymruScout.IP.sections | String | The sections of data returned. |
| TeamCymruScout.IP.identity.tags | Unknown | The tags associated with the IP address. |
| TeamCymruScout.IP.identity.reverse_hostnames | Unknown | The reverse hostnames associated with the IP address. |
| TeamCymruScout.IP.identity.asn | Number | The autonomous system number associated with the IP address. |
| TeamCymruScout.IP.identity.as_name | String | The name associated with the autonomous system number. |
| TeamCymruScout.IP.identity.net_name | String | The name associated with the network. |
| TeamCymruScout.IP.identity.org_name | String | The name associated with the organization. |
| TeamCymruScout.IP.whois.modified | Date | The date the WHOIS information was last modified. |
| TeamCymruScout.IP.whois.asn | Number | The autonomous system number associated with the IP address. |
| TeamCymruScout.IP.whois.cidr | String | The network associated with the IP address. |
| TeamCymruScout.IP.whois.as_name | String | The name associated with the autonomous system number. |
| TeamCymruScout.IP.whois.bgp_asn | Number | The Border Gateway Protocol (BGP) autonomous system number (ASN) associated with the IP address. |
| TeamCymruScout.IP.whois.bgp_asn_name | String | The name associated with the Border Gateway Protocol (BGP) autonomous system number (ASN). |
| TeamCymruScout.IP.whois.net_name | String | The name associated with the network. |
| TeamCymruScout.IP.whois.net_handle | String | The handle associated with the network. |
| TeamCymruScout.IP.whois.description | String | The description associated with the network. |
| TeamCymruScout.IP.whois.cc | String | The country code associated with the network. |
| TeamCymruScout.IP.whois.city | String | The city associated with the network. |
| TeamCymruScout.IP.whois.address | String | The address associated with the network. |
| TeamCymruScout.IP.whois.abuse_contact_id | String | The abuse contact ID associated with the network. |
| TeamCymruScout.IP.whois.about_contact_role | String | The role associated with the about contact. |
| TeamCymruScout.IP.whois.about_contact_person | String | The person associated with the about contact. |
| TeamCymruScout.IP.whois.about_contact_email | String | The email associated with the about contact. |
| TeamCymruScout.IP.whois.about_contact_phone | String | The phone number associated with the about contact. |
| TeamCymruScout.IP.whois.about_contact_country | String | The country associated with the about contact. |
| TeamCymruScout.IP.whois.about_contact_city | String | The city associated with the about contact. |
| TeamCymruScout.IP.whois.about_contact_address | String | The address associated with the about contact. |
| TeamCymruScout.IP.whois.admin_contact_id | String | The ID associated with the admin contact. |
| TeamCymruScout.IP.whois.admin_contact_role | String | The role associated with the admin contact. |
| TeamCymruScout.IP.whois.admin_contact_person | String | The person associated with the admin contact. |
| TeamCymruScout.IP.whois.admin_contact_email | String | The email associated with the admin contact. |
| TeamCymruScout.IP.whois.admin_contact_phone | String | The phone number associated with the admin contact. |
| TeamCymruScout.IP.whois.admin_contact_country | String | The country associated with the admin contact. |
| TeamCymruScout.IP.whois.admin_contact_city | String | The city associated with the admin contact. |
| TeamCymruScout.IP.whois.admin_contact_address | String | The address associated with the admin contact. |
| TeamCymruScout.IP.whois.tech_contact_id | String | The ID associated with the tech contact. |
| TeamCymruScout.IP.whois.tech_contact_role | String | The role associated with the tech contact. |
| TeamCymruScout.IP.whois.tech_contact_person | String | The person associated with the tech contact. |
| TeamCymruScout.IP.whois.tech_contact_email | String | The email associated with the tech contact. |
| TeamCymruScout.IP.whois.tech_contact_phone | String | The phone number associated with the tech contact. |
| TeamCymruScout.IP.whois.tech_contact_country | String | The country associated with the tech contact. |
| TeamCymruScout.IP.whois.tech_contact_city | String | The city associated with the tech contact. |
| TeamCymruScout.IP.whois.tech_contact_address | String | The address associated with the tech contact. |
| TeamCymruScout.IP.whois.org_id | String | The ID associated with the organization. |
| TeamCymruScout.IP.whois.org_name | String | The name associated with the organization. |
| TeamCymruScout.IP.whois.org_email | String | The email associated with the organization. |
| TeamCymruScout.IP.whois.org_phone | String | The phone number associated with the organization. |
| TeamCymruScout.IP.whois.org_country | String | The country associated with the organization. |
| TeamCymruScout.IP.whois.org_city | String | The city associated with the organization. |
| TeamCymruScout.IP.whois.org_address | String | The address associated with the organization. |
| TeamCymruScout.IP.whois.mnt_by_email | String | The email associated with the maintainer. |
| TeamCymruScout.IP.whois.mnt_lower_email | String | The email associated with the lower maintenance router. |
| TeamCymruScout.IP.whois.mnt_router_email | String | The email associated with the maintenance router. |
| TeamCymruScout.IP.communications.event_count | Number | The count of events associated with the communication. |
| TeamCymruScout.IP.communications.peers.proto | Number | The protocol associated with the peer. |
| TeamCymruScout.IP.communications.peers.proto_text | String | The text associated with the protocol of the peer. |
| TeamCymruScout.IP.communications.peers.local.ip | String | The IP address associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.min_port | Number | The minimum port associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.max_port | Number | The maximum port associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.country_codes | String | The country codes associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.as_info.asn | Number | The autonomous system number associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.as_info.as_name | String | The name associated with the autonomous system number of the local peer. |
| TeamCymruScout.IP.communications.peers.local.tags.id | Number | The ID of the tags associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.tags.name | String | The name of the tags associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.tags.children.id | Number | The ID of the child tags associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.tags.children.name | String | The name of the child tags associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.tags.children.children | Unknown | The children of the child tags associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.unique_ports | Number | The unique ports associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.top_services.service_name | String | The name of the top service associated with the local peer. |
| TeamCymruScout.IP.communications.peers.local.top_services.port | Number | The port associated with the top service of the local peer. |
| TeamCymruScout.IP.communications.peers.local.top_services.proto_number | Number | The protocol number associated with the top service of the local peer. |
| TeamCymruScout.IP.communications.peers.local.top_services.description | String | The description associated with the top service of the local peer. |
| TeamCymruScout.IP.communications.peers.peer.ip | String | The IP address associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.min_port | Number | The minimum port associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.max_port | Number | The maximum port associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.country_codes | String | The country codes associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.as_info.asn | Number | The autonomous system number associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.as_info.as_name | String | The name associated with the autonomous system number of the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags | Unknown | The tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.unique_ports | Number | The unique ports associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.top_services.service_name | String | The name of the top service associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.top_services.port | Number | The port associated with the top service of the peer. |
| TeamCymruScout.IP.communications.peers.peer.top_services.proto_number | Number | The protocol number associated with the top service of the peer. |
| TeamCymruScout.IP.communications.peers.peer.top_services.description | String | The description associated with the top service of the peer. |
| TeamCymruScout.IP.communications.peers.event_count | Number | The number of events associated with the communication. |
| TeamCymruScout.IP.communications.peers.first_seen | Date | The first seen date associated with the communication. |
| TeamCymruScout.IP.communications.peers.last_seen | Date | The last seen date associated with the communication. |
| TeamCymruScout.IP.communications.peers.peer.tags.id | Number | The ID of the tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.name | String | The name of the tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.children.id | Number | The ID of the child tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.children.name | String | The name of the child tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.children.children.id | Number | The ID of the grandchild tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.children.children.name | String | The name of the grandchild tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.children.children.children | Unknown | The children of the grandchild tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.children.children | Unknown | The grandchild tags associated with the peer. |
| TeamCymruScout.IP.communications.peers.peer.tags.children | Unknown | The child tags associated with the peer. |
| TeamCymruScout.IP.pdns.event_count | Number | The number of events associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.ip | String | The IP address associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.domain | String | The domain associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.root | String | The root associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.tld | String | The top level domain (TLD) associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.type | String | The type associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.registrar | String | The registrar associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.domain_created | Date | The creation date associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.domain_expires | Date | The expiration date associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.nameservers.root | String | The root of the nameserver associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.nameservers.nameservers | String | The nameservers associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.country_codes | String | The country codes associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.as_info.asn | Number | The autonomous system number associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.as_info.as_name | String | The name associated with the autonomous system number of the PDNS. |
| TeamCymruScout.IP.pdns.pdns.tags | Unknown | The tags associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.distinct_ips | Number | The number of distinct IP addresses associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.active_days | Number | The number of active days associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.event_count | Number | The count of events associated with the PDNS. |
| TeamCymruScout.IP.pdns.pdns.first_seen | Date | The first date the PDNS was seen. |
| TeamCymruScout.IP.pdns.pdns.last_seen | Date | The last date the PDNS was seen. |
| TeamCymruScout.IP.pdns.pdns.nameservers | Unknown | The nameservers of the PDNS. |
| TeamCymruScout.IP.fingerprints.event_count | Number | The number of events associated with the fingerprints. |
| TeamCymruScout.IP.fingerprints.fingerprints.ip | String | The IP address of the fingerprint. |
| TeamCymruScout.IP.fingerprints.fingerprints.type | String | The type of the fingerprint. |
| TeamCymruScout.IP.fingerprints.fingerprints.fingerprint | String | The fingerprint of the host. |
| TeamCymruScout.IP.fingerprints.fingerprints.port | Number | The port of the fingerprint. |
| TeamCymruScout.IP.fingerprints.fingerprints.first_seen | Date | The first date the fingerprint was seen. |
| TeamCymruScout.IP.fingerprints.fingerprints.last_seen | Date | The last date the fingerprint was seen. |
| TeamCymruScout.IP.fingerprints.fingerprints.distinct_ips | Number | The number of distinct IP addresses associated with the fingerprints. |
| TeamCymruScout.IP.fingerprints.fingerprints.active_days | Number | The number of active days associated with the fingerprints. |
| TeamCymruScout.IP.fingerprints.fingerprints.event_count | Number | The number of events associated with the fingerprints. |
| TeamCymruScout.IP.open_ports.event_count | Number | The number of events associated with the open ports. |
| TeamCymruScout.IP.open_ports.unique_ports | Number | The number of unique ports in the open ports. |
| TeamCymruScout.IP.open_ports.open_ports.ip | String | The IP address of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.port | Number | The port of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.protocol | Number | The protocol of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.protocol_text | String | The protocol text of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.service | String | The service of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.banner | String | The banner of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.banner_sha1 | String | The SHA1 hash of the banner of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.first_seen | Date | The first date the open port was seen. |
| TeamCymruScout.IP.open_ports.open_ports.last_seen | Date | The last date the open port was seen. |
| TeamCymruScout.IP.open_ports.open_ports.country_codes | String | The country codes of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.as_info.asn | Number | The autonomous system number of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.as_info.as_name | String | The name of the autonomous system number of the open port. |
| TeamCymruScout.IP.open_ports.open_ports.tags.id | Number | The ID of the tag associated with the open port. |
| TeamCymruScout.IP.open_ports.open_ports.tags.name | String | The name of the tag associated with the open port. |
| TeamCymruScout.IP.open_ports.open_ports.tags.children.id | Number | The ID of the child tag associated with the open port. |
| TeamCymruScout.IP.open_ports.open_ports.tags.children.name | String | The name of the child tag associated with the open port. |
| TeamCymruScout.IP.open_ports.open_ports.tags.children.children | Unknown | The child tags of the child tag associated with the open port. |
| TeamCymruScout.IP.open_ports.open_ports.event_count | Number | The number of events associated with the open port. |
| TeamCymruScout.IP.x509.event_count | Number | The number of events associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.ip | String | The IP address associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.issuer | String | The issuer of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.issuer_common_name | String | The common name of the issuer of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.common_name | String | The common name of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.altnames | String | The alternative names associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.serial | String | The serial number of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.subject | String | The subject of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.not_after | Date | The expiration date of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.not_before | Date | The start date of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.validity_period | String | The validity period of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.md5 | String | The MD5 hash of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.sha1 | String | The SHA1 hash of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.sha256 | String | The SHA256 hash of the x509 certificate. |
| TeamCymruScout.IP.x509.x509.first_seen | Date | The first date the x509 certificate was seen. |
| TeamCymruScout.IP.x509.x509.last_seen | Date | The last date the x509 certificate was seen. |
| TeamCymruScout.IP.x509.x509.port | Number | The port associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.self_signed | Boolean | Indicates whether the x509 certificate is self-signed. |
| TeamCymruScout.IP.x509.x509.country_codes | String | The country codes associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.as_info.asn | Number | The autonomous system number associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.as_info.as_name | String | The autonomous system name associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.tags.id | Number | The ID of the tag associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.tags.name | String | The name of the tag associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.tags.children.id | Number | The ID of the child tag associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.tags.children.name | String | The name of the child tag associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.tags.children.children | Unknown | The children of the child tag associated with the x509 certificate. |
| TeamCymruScout.IP.x509.x509.count | Number | The count of the x509 certificate. |
| TeamCymruScout.IP.summary.total | Number | The total count of the summary. |
| TeamCymruScout.IP.summary.ip | String | The IP address associated with the summary. |
| TeamCymruScout.IP.summary.start_date | Date | The start date of the summary. |
| TeamCymruScout.IP.summary.end_date | Date | The end date of the summary. |
| TeamCymruScout.IP.summary.geo_ip_cc | String | The country code associated with the geographic IP. |
| TeamCymruScout.IP.summary.tags.id | Number | The ID of the tag associated with the summary. |
| TeamCymruScout.IP.summary.tags.name | String | The name of the tag associated with the summary. |
| TeamCymruScout.IP.summary.tags.children.id | Number | The ID of the child tag associated with the summary. |
| TeamCymruScout.IP.summary.tags.children.name | String | The name of the child tag associated with the summary. |
| TeamCymruScout.IP.summary.tags.children.children | Unknown | The children of the child tag associated with the summary. |
| TeamCymruScout.IP.summary.reverse_hostnames | Unknown | The reverse hostnames associated with the summary. |
| TeamCymruScout.IP.summary.bgp_asn | Number | The autonomous system number associated with the BGP. |
| TeamCymruScout.IP.summary.bgp_asname | String | The autonomous system name associated with the BGP. |
| TeamCymruScout.IP.summary.whois.asn | Number | The autonomous system number associated with the IP address. |
| TeamCymruScout.IP.summary.whois.as_name | String | The name associated with the autonomous system number. |
| TeamCymruScout.IP.summary.whois.net_name | String | The name associated with the network. |
| TeamCymruScout.IP.summary.whois.org_name | String | The name associated with the organization. |
| TeamCymruScout.IP.summary.pdns.total | Number | The total count of the DNS queries associated with the IP address. |
| TeamCymruScout.IP.summary.pdns.top_pdns.event_count | Number | The number of events associated with the top DNS query. |
| TeamCymruScout.IP.summary.pdns.top_pdns.domain | String | The domain associated with the top DNS query. |
| TeamCymruScout.IP.summary.pdns.top_pdns.first_seen | Date | The first date the top DNS query was seen. |
| TeamCymruScout.IP.summary.pdns.top_pdns.last_seen | Date | The last date the top DNS query was seen. |
| TeamCymruScout.IP.summary.pdns.top_pdns.css_color | String | The CSS color associated with the top DNS query. |
| TeamCymruScout.IP.summary.open_ports.total | Number | The total number of the open ports associated with the IP address. |
| TeamCymruScout.IP.summary.open_ports.unique_ports | Number | The number of unique ports in the open ports. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.event_count | Number | The number of events associated with the top open port. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.port | Number | The port associated with the top open port. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.protocol | Number | The protocol number associated with the top open port. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.protocol_text | String | The protocol text associated with the top open port. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.service | String | The service associated with the top open port. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.inferred_service_name | Unknown | The inferred service name associated with the top open port. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.first_seen | Date | The first date the top open port was seen. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.last_seen | Date | The last date the top open port was seen. |
| TeamCymruScout.IP.summary.open_ports.top_open_ports.css_color | String | The CSS color associated with the top open port. |
| TeamCymruScout.IP.summary.certs.top_certs.issuer | String | The issuer of the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.issuer_common_name | String | The common name of the issuer of the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.common_name | String | The common name of the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.subject | String | The subject of the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.port | Number | The port associated with the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.first_seen | Date | The first date the certificate was seen. |
| TeamCymruScout.IP.summary.certs.top_certs.last_seen | Date | The last date the certificate was seen. |
| TeamCymruScout.IP.summary.certs.top_certs.self_signed | Boolean | Indicates whether the certificate is self-signed. |
| TeamCymruScout.IP.summary.certs.top_certs.not_before | Date | The date before which the certificate is not valid. |
| TeamCymruScout.IP.summary.certs.top_certs.not_after | Date | The date after which the certificate is not valid. |
| TeamCymruScout.IP.summary.certs.top_certs.valid_days | Number | The number of valid days for the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.md5 | String | The MD5 hash of the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.sha1 | String | The SHA1 hash of the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.sha256 | String | The SHA256 hash of the certificate. |
| TeamCymruScout.IP.summary.certs.top_certs.css_color | String | The CSS color associated with the certificate. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.id | Number | The ID of the tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.name | String | The name of the tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.description | String | The description of the tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parent_ids | Number | The parent IDs of the tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.css_color | String | The CSS color associated with the tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents | Unknown | The parents of the tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.first_seen | Date | The first date the tag was seen. |
| TeamCymruScout.IP.summary.tag_timeline.data.last_seen | Date | The last date the tag was seen. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.id | Number | The ID of the parent tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.name | String | The name of the parent tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.description | String | The description of the parent tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.parent_ids | Unknown | The parent IDs of the parent tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.css_color | String | The CSS color associated with the parent tag. |
| TeamCymruScout.IP.summary.tag_timeline.data.tag.parents.parents | Unknown | The parents of the parent tag. |
| TeamCymruScout.IP.summary.insights.overall_rating | String | The overall rating of the insights. |
| TeamCymruScout.IP.summary.insights.total | Number | The total count of the insights. |
| TeamCymruScout.IP.summary.insights.insights.rating | String | The rating of the insight. |
| TeamCymruScout.IP.summary.insights.insights.message | String | The message of the insight. |
| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.type | String | The type of the fingerprint. |
| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.signature | String | The signature of the fingerprint. |
| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.port | Number | The port associated with the fingerprint. |
| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.first_seen | Date | The first date the fingerprint was seen. |
| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.last_seen | Date | The last date the fingerprint was seen. |
| TeamCymruScout.IP.summary.fingerprints.top_fingerprints.count | Number | The count of the fingerprint. |
| TeamCymruScout.IP.country_code | String | The country code. |
| TeamCymruScout.IP.as_info.asn | Number | The autonomous system number. |
| TeamCymruScout.IP.as_info.as_name | String | The autonomous system name. |
| TeamCymruScout.IP.insights.overall_rating | String | The overall rating for the IP address. |
| TeamCymruScout.IP.insights.insights.rating | String | The individual insight rating for the IP address. |
| TeamCymruScout.IP.insights.insights.message | String | The individual insight message for the IP address. |
| TeamCymruScout.IP.tags.id | Number | The ID of the tag. |
| TeamCymruScout.IP.tags.name | String | The name of the tag. |
| TeamCymruScout.IP.tags.children.id | Number | The ID of the child tag. |
| TeamCymruScout.IP.tags.children.name | String | The name of the child tag. |
| TeamCymruScout.IP.tags.children.children | Unknown | The children of the child tag. |
Command example
!ip ip=0.0.0.1
Context Example
{
"DBotScore": {
"Indicator": "0.0.0.1",
"Reliability": "A - Completely reliable",
"Score": 2,
"Type": "ip",
"Vendor": "Team Cymru Scout"
},
"IP": {
"ASN": 15133,
"ASOwner": "test_name",
"Address": "0.0.0.1",
"Description": "[\"data-03-EU-93-184-216-0-24\"]",
"Organization": {
"Name": "test_name Inc."
},
"Port": "443, 80",
"Region": "EU",
"Relationships": [
{
"EntityA": "0.0.0.1",
"EntityAType": "IP",
"EntityB": "0.0.0.2",
"EntityBType": "IP",
"Relationship": "communicated-with"
}
],
"Tags": "cdn: (test_name)",
"UpdatedDate": "2012-06-22"
},
"TeamCymruScout": {
"IP": {
"ip": "0.0.0.1",
"sections": [
"identity",
"comms",
"pdns",
"open_ports",
"x509",
"fingerprints",
"whois",
"summary"
],
"identity": {
"asn": 15133,
"as_name": "test_name",
"net_name": "test_name-data-03",
"org_name": "test_name Inc."
},
"whois": {
"modified": "2012-06-22",
"asn": 15133,
"cidr": "0.0.0.1/24",
"as_name": "test_name",
"bgp_asn": 15133,
"bgp_asn_name": "test_name, US",
"net_name": "test_name-data-03",
"net_handle": "",
"description": "[\"data-03-EU-93-184-216-0-24\"]",
"cc": "EU",
"city": "",
"address": "",
"abuse_contact_id": "",
"about_contact_role": "",
"about_contact_person": "",
"about_contact_email": "",
"about_contact_phone": "",
"about_contact_country": "",
"about_contact_city": "",
"about_contact_address": "",
"admin_contact_id": "DS7892-RIPE",
"admin_contact_role": "",
"admin_contact_person": "Derrick Sawyer",
"admin_contact_email": "",
"admin_contact_phone": "+18123456789",
"admin_contact_country": "",
"admin_contact_city": "",
"admin_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]",
"tech_contact_id": "DS7892-RIPE",
"tech_contact_role": "",
"tech_contact_person": "Derrick Sawyer",
"tech_contact_email": "",
"tech_contact_phone": "+18987654321",
"tech_contact_country": "",
"tech_contact_city": "",
"tech_contact_address": "[\"11811 N. Tatum Blvd, Suite 3031, Phoenix, AZ 85028\"]",
"org_id": "",
"org_name": "test_name Inc.",
"org_email": "",
"org_phone": "",
"org_country": "",
"org_city": "",
"org_address": "",
"mnt_by_email": "",
"mnt_lower_email": "",
"mnt_router_email": ""
},
"communications": {
"event_count": 33264,
"peers": [
{
"proto": 6,
"proto_text": "TCP",
"local": {
"ip": "0.0.0.1",
"min_port": 80,
"max_port": 80,
"country_codes": [
"US"
],
"as_info": [
{
"asn": 15133,
"as_name": "test_name, US"
}
],
"tags": [
{
"id": 176,
"name": "cdn",
"children": [
{
"id": 206,
"name": "test_name"
}
]
}
],
"unique_ports": 1,
"top_services": [
{
"service_name": "http",
"port": 80,
"proto_number": 6,
"description": "World Wide Web HTTP"
}
]
},
"peer": {
"ip": "0.0.0.2",
"min_port": 52049,
"max_port": 64552,
"country_codes": [
"ZA"
],
"as_info": [
{
"asn": 327983,
"as_name": "Interworks-Wireless-Solutions, ZA"
}
],
"unique_ports": 3669,
"top_services": [
{
"service_name": "",
"port": 64552,
"proto_number": 6,
"description": ""
}
]
},
"event_count": 6040,
"first_seen": "2024-06-04",
"last_seen": "2024-06-04"
}
]
},
"pdns": {
"event_count": 1338,
"pdns": [
{
"ip": "0.0.0.1",
"domain": "test1.aaa",
"root": "test1.aaa",
"tld": "aaa",
"type": "A",
"registrar": "PDR Ltd. d/b/a test1.com",
"domain_created": "2023-03-03",
"domain_expires": "2025-03-03",
"nameservers": [
{
"root": "test1.com.br",
"nameservers": [
"ns1036.test1.com.br",
"ns1037.test1.com.br"
]
}
],
"country_codes": [
"US"
],
"as_info": [
{
"asn": 15133,
"as_name": ""
}
],
"distinct_ips": 1,
"active_days": 20,
"event_count": 78,
"first_seen": "2024-05-27",
"last_seen": "2024-06-25"
}
]
},
"fingerprints": {
"event_count": 5,
"fingerprints": [
{
"ip": "0.0.0.1",
"type": "jarm",
"fingerprint": "testsignature",
"port": 443,
"first_seen": "2024-05-30",
"last_seen": "2024-06-21",
"distinct_ips": 830,
"active_days": 5,
"event_count": 5
}
]
},
"open_ports": {
"event_count": 2,
"unique_ports": 2,
"open_ports": [
{
"ip": "0.0.0.1",
"port": 443,
"protocol": 6,
"protocol_text": "TCP",
"service": "https",
"banner": "TLS/1.1 cipher:0xc013, www.example.org, www.example.org, example.net, example.edu, example.com, example.org, www.example.com, www.example.edu, www.example.net",
"banner_sha1": "test_sha1",
"first_seen": "2024-05-30",
"last_seen": "2024-06-21",
"country_codes": [
"US"
],
"as_info": [
{
"asn": 15133,
"as_name": "test_name, US"
}
],
"tags": [
{
"id": 176,
"name": "cdn",
"children": [
{
"id": 206,
"name": "test_name"
}
]
}
],
"event_count": 5
}
]
},
"x509": {
"event_count": 5,
"x509": [
{
"ip": "0.0.0.1",
"issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US",
"issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1",
"common_name": "www.example.org",
"altnames": [
"example.com",
"example.edu",
"example.net",
"example.org",
"www.example.com",
"www.example.edu",
"www.example.net",
"www.example.org"
],
"serial": "testserial",
"subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.",
"not_after": "2025-03-01",
"not_before": "2024-01-30",
"validity_period": "397 Days",
"md5": "testmd5",
"sha1": "testsha1",
"sha256": "testsha256",
"first_seen": "2024-05-30",
"last_seen": "2024-06-21",
"port": 443,
"self_signed": false,
"country_codes": [
"US"
],
"as_info": [
{
"asn": 15133,
"as_name": "test_name, US"
}
],
"tags": [
{
"id": 176,
"name": "cdn",
"children": [
{
"id": 206,
"name": "test_name"
}
]
}
],
"count": 5
}
]
},
"summary": {
"total": 1,
"ip": "0.0.0.1",
"start_date": "2024-05-27",
"end_date": "2024-06-25",
"geo_ip_cc": "US",
"tags": [
{
"id": 176,
"name": "cdn",
"children": [
{
"id": 206,
"name": "test_name"
}
]
}
],
"bgp_asn": 15133,
"bgp_asname": "test_name, US",
"whois": {
"asn": 15133,
"as_name": "test_name",
"net_name": "test_name-data-03",
"org_name": "test_name Inc."
},
"pdns": {
"total": 1338,
"top_pdns": [
{
"event_count": 78,
"domain": "test1.aaa",
"first_seen": "2024-05-27",
"last_seen": "2024-06-25",
"css_color": "#a6abb7"
}
]
},
"open_ports": {
"total": 2,
"unique_ports": 2,
"top_open_ports": [
{
"event_count": 53,
"port": 80,
"protocol": 6,
"protocol_text": "TCP",
"service": "http",
"first_seen": "2024-05-27",
"last_seen": "2024-06-25",
"css_color": "#a6abb7"
}
]
},
"certs": {
"top_certs": [
{
"issuer": "CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US",
"issuer_common_name": "DigiCert Global G2 TLS RSA SHA256 2020 CA1",
"common_name": "www.example.org",
"subject": "CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.",
"port": 443,
"first_seen": "2024-05-30",
"last_seen": "2024-06-21",
"self_signed": false,
"not_before": "2024-01-30",
"not_after": "2025-03-01",
"valid_days": 397,
"md5": "testmd5",
"sha1": "testsha1",
"sha256": "testsha256",
"css_color": "#b382d9"
}
]
},
"tag_timeline": {
"data": [
{
"tag": {
"id": 176,
"name": "cdn",
"description": "The CDN tag characterizes IP addresses associated with Content Delivery Networks (CDNs).",
"css_color": "#8A532C"
},
"first_seen": "2024-05-27",
"last_seen": "2024-06-25"
}
]
},
"insights": {
"overall_rating": "suspicious",
"total": 8,
"insights": [
{
"rating": "no_rating",
"message": "x509 subject \"CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers."
}
]
},
"fingerprints": {
"top_fingerprints": [
{
"type": "jarm",
"signature": "testsignature",
"port": 443,
"first_seen": "2024-05-30",
"last_seen": "2024-06-21",
"count": 5
}
]
}
}
},
"QueryUsage": {
"command_name": "ip",
"foundation_api_usage": {
"query_limit": 0,
"remaining_queries": 0,
"used_queries": 15
},
"query_limit": 50000,
"remaining_queries": 49739,
"request_id": "test_id",
"size": 1000,
"start_date": "2024-05-27",
"end_date": "2024-06-25",
"used_queries": 261
}
}
}
Human Readable Output
Summary Information For The Given Suspicious IP: 0.0.0.1
Country Code Whois Tags Insights US asn: 15133
as_name: test_name
net_name: test_name-data-03
org_name: test_name Inc.- id: 176
name: cdn
children:
- id: 206
name: test_name- rating: no_rating
message: x509 subject “CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers.Top PDNS
Domain Event Count First Seen Last Seen test1.aaa 78 2024-05-27 2024-06-25 Top Peers
Proto Client IP Client Country Code(s) Client Services Server IP Server Country Code(s) Server Tag(s) Server Services Event Count First Seen Last Seen Client AS Name Server AS Name TCP 0.0.0.2 ZA - port: 64552
proto_number: 60.0.0.1 US cdn: (test_name) - service_name: http
port: 80
proto_number: 6
description: World Wide Web HTTP6040 2024-06-04 2024-06-04 Interworks-Wireless-Solutions, ZA test_name, US Top Open Ports
Event Count Port Protocol Protocol Text Service First Seen Last Seen 53 80 6 TCP http 2024-05-27 2024-06-25 Top Fingerprints
Count First Seen Last Seen Port Signature Type 5 2024-05-30 2024-06-21 443 testsignature jarm Top Certificates
Common Name First Seen Issuer Issuer Common Name Last Seen Md5 Not After Not Before Port Self Signed Sha1 Sha256 Subject Valid Days www.example.org 2024-05-30 CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US DigiCert Global G2 TLS RSA SHA256 2020 CA1 2024-06-21 testmd5 2025-03-01 2024-01-30 443 false testsha1 testsha256 CN=www.example.org, O=Internet Corporation for Assigned Names and Numbers. 397
scout-indicator-search
Return the summary information available for the given domain or IP address using Scout query language.
Base Command
scout-indicator-search
Input
| Argument Name | Description | Required |
|---|---|---|
| query | A simple or advanced Scout query which may contain the domain or IP address. For example: comms.ip=”0.0.0.1/24”. |
Required |
| start_date | The start date to filter indicators. Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd. For example: 01 June 2024, 2024-06-17. Default is 30 days. |
Optional |
| end_date | The end date to filter indicators. Supported formats: 2 days, 2 weeks, 2 months, yyyy-mm-dd. For example: 01 June 2024, 2024-06-17. Default is now. |
Optional |
| days | Relative offset in days from current time. It cannot exceed the maximum range of 30 days. Note: This will take priority over start_date and end_date if all three are passed. |
Optional |
| size | The maximum number of indicators to fetch. Note: The maximum allowed size is 5000. Default is 20. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| TeamCymruScout.IP.ip | String | The IP address. |
| TeamCymruScout.IP.country_codes | String | The country code(s). |
| TeamCymruScout.IP.as_info.asn | Number | The autonomous system number. |
| TeamCymruScout.IP.as_info.as_name | String | The autonomous system name. |
| TeamCymruScout.IP.tags.id | Number | The ID of the tag. |
| TeamCymruScout.IP.tags.name | String | The name of the tag. |
| TeamCymruScout.IP.tags.children.id | Number | The ID of the child tag. |
| TeamCymruScout.IP.tags.children.name | String | The name of the child tag. |
| TeamCymruScout.IP.tags.children.children | Unknown | The children of the child tag. |
| TeamCymruScout.IP.event_count | Number | The number of events related to the IP address. |
| TeamCymruScout.IP.summary.last_seen | Date | The last time the IP was seen. |
| TeamCymruScout.IP.summary.whois.asn | Number | The autonomous system number associated with the IP. |
| TeamCymruScout.IP.summary.whois.as_name | String | The name of the autonomous system associated with the IP. |
| TeamCymruScout.IP.summary.whois.net_name | String | The network name associated with the IP. |
| TeamCymruScout.IP.summary.whois.org_name | String | The organization name associated with the IP. |
| TeamCymruScout.IP.summary.open_ports.ip | String | The IP address associated with the open port. |
| TeamCymruScout.IP.summary.open_ports.port | Number | The port number associated with the open port. |
| TeamCymruScout.IP.summary.open_ports.protocol | Number | The protocol number associated with the open port. |
| TeamCymruScout.IP.summary.open_ports.protocol_text | String | The protocol name associated with the open port. |
| TeamCymruScout.IP.summary.open_ports.service | String | The service name associated with the open port. |
| TeamCymruScout.IP.summary.open_ports.event_count | Number | The number of events related to the open port. |
| TeamCymruScout.IP.summary.pdns.ip | String | The IP address associated with the domain. |
| TeamCymruScout.IP.summary.pdns.domain | String | The domain associated with the IP. |
| TeamCymruScout.IP.summary.pdns.event_count | Number | The number of events related to the domain. |
| TeamCymruScout.IP.summary.top_peers.ip | String | The IP address of the top peer. |
| TeamCymruScout.IP.summary.top_peers.event_count | Number | The number of events related to the top peer. |
| TeamCymruScout.IP.summary.comms_total | Number | The total number of communications related to the IP address. |
| TeamCymruScout.IP.summary.service_counts.proto | Number | The protocol number associated with the service count. |
| TeamCymruScout.IP.summary.service_counts.proto_text | String | The protocol name associated with the service count. |
| TeamCymruScout.IP.summary.service_counts.port | Number | The port number associated with the service count. |
| TeamCymruScout.IP.summary.service_counts.event_count | Number | The number of events related to the service count. |
| TeamCymruScout.IP.summary.service_counts.service.service_name | String | The service name associated with the service count. |
| TeamCymruScout.IP.summary.service_counts.service.port | Number | The port number associated with the service count. |
| TeamCymruScout.IP.summary.service_counts.service.proto_number | Number | The protocol number associated with the service count. |
| TeamCymruScout.IP.summary.service_counts.service.description | String | The description of the service associated with the service count. |
| TeamCymruScout.IP.summary.fingerprints.ip | String | The IP address associated with the fingerprint. |
| TeamCymruScout.IP.summary.fingerprints.type | String | The type of the fingerprint. |
| TeamCymruScout.IP.summary.fingerprints.signature | String | The signature of the fingerprint. |
| TeamCymruScout.IP.summary.fingerprints.event_count | Number | The number of events related to the fingerprint. |
| TeamCymruScout.IP.summary.certs.ip | String | The IP address associated with the certificate. |
| TeamCymruScout.IP.summary.certs.issuer | String | The issuer of the certificate. |
| TeamCymruScout.IP.summary.certs.issuer_common_name | String | The common name of the issuer of the certificate. |
| TeamCymruScout.IP.summary.certs.common_name | String | The common name of the certificate. |
| TeamCymruScout.IP.summary.certs.port | Number | The port number associated with the certificate. |
| TeamCymruScout.IP.summary.certs.event_count | Number | The number of events related to the certificate. |
| TeamCymruScout.QueryUsage.command_name | String | The name of the Cortex XSOAR command that triggered the Foundation API. |
| TeamCymruScout.QueryUsage.request_id | String | The unique request ID of the Foundation API response. |
| TeamCymruScout.QueryUsage.total | Number | The total number of records available for provided filters. |
| TeamCymruScout.QueryUsage.query | String | The query for which the search API was triggered. |
| TeamCymruScout.QueryUsage.size | Number | The number of records requested using parameters. |
| TeamCymruScout.QueryUsage.start_date | String | The start date from which the indicators are returned. |
| TeamCymruScout.QueryUsage.end_date | String | The end date from which the indicators are returned. |
| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. |
| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. |
| TeamCymruScout.QueryUsage.query_limit | Number | The total number of queries allowed. |
| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used for the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Number | The total number of queries allowed for the Foundation API. |
| IP.Address | String | IP address. |
| IP.Relationships.EntityA | String | The source of the relationship. |
| IP.Relationships.EntityB | String | The destination of the relationship. |
| IP.Relationships.Relationship | String | The name of the relationship. |
| IP.Relationships.EntityAType | String | The type of the source of the relationship. |
| IP.Relationships.EntityBType | String | The type of the destination of the relationship. |
| IP.ASN | String | The autonomous system name for the IP address, for example: “AS8948”. |
| IP.Hostname | String | The hostname that is mapped to this IP address. |
| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. |
| IP.Geo.Country | String | The country in which the IP address is located. |
| IP.Geo.Description | String | Additional information about the location. |
| IP.DetectionEngines | Number | The total number of engines that checked the indicator. |
| IP.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. |
| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. |
| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. |
| IP.Tags | Unknown | (List) Tags of the IP address. |
| IP.FeedRelatedIndicators.value | String | Indicators that are associated with the IP address. |
| IP.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the IP address. |
| IP.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the IP address. |
| IP.MalwareFamily | String | The malware family associated with the IP address. |
| IP.Organization.Name | String | The organization of the IP address. |
| IP.Organization.Type | String | The organization type of the IP address. |
| IP.ASOwner | String | The autonomous system owner of the IP address. |
| IP.Region | String | The region in which the IP address is located. |
| IP.Port | String | Ports that are associated with the IP address. |
| IP.Internal | Boolean | Whether the IP address is internal or external. |
| IP.UpdatedDate | Date | The date that the IP address was last updated. |
| IP.Registrar.Abuse.Name | String | The name of the contact for reporting abuse. |
| IP.Registrar.Abuse.Address | String | The address of the contact for reporting abuse. |
| IP.Registrar.Abuse.Country | String | The country of the contact for reporting abuse. |
| IP.Registrar.Abuse.Network | String | The network of the contact for reporting abuse. |
| IP.Registrar.Abuse.Phone | String | The phone number of the contact for reporting abuse. |
| IP.Registrar.Abuse.Email | String | The email address of the contact for reporting abuse. |
| IP.Campaign | String | The campaign associated with the IP address. |
| IP.TrafficLightProtocol | String | The Traffic Light Protocol (TLP) color that is suitable for the IP address. |
| IP.CommunityNotes.note | String | Notes on the IP address that were given by the community. |
| IP.CommunityNotes.timestamp | Date | The time in which the note was published. |
| IP.Publications.source | String | The source in which the article was published. |
| IP.Publications.title | String | The name of the article. |
| IP.Publications.link | String | A link to the original article. |
| IP.Publications.timestamp | Date | The time in which the article was published. |
| IP.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. |
| IP.ThreatTypes.threatcategoryconfidence | String | The confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The reputation score (0: Unknown, 1: Good, 2: Suspicious, 3: Bad). |
Command example
!scout-indicator-search query="0.0.0.1" size=1 start_date="30 days" end_date="now"
Context Example
{
"DBotScore": {
"Indicator": "0.0.0.1",
"Type": "ip",
"Vendor": "Team Cymru Scout",
"Score": 0,
"Reliability": "B - Usually reliable"
},
"IP": {
"Address": "0.0.0.1",
"ASN": 15169,
"ASOwner": "DUMMY",
"Region": "US",
"Port": "53,443",
"UpdatedDate": "2024-06-27",
"Hostname": "dns.dummy",
"Geo": {
"Country": "US"
},
"Organization": {
"Name": "Dummy LLC"
},
"Tags": "cdn: (cloudflare)",
"Relationships": [
{
"Relationship": "communicated-with",
"EntityA": "0.0.0.1",
"EntityAType": "IP",
"EntityB": "0.0.0.2",
"EntityBType": "IP"
},
{
"Relationship": "communicated-with",
"EntityA": "0.0.0.1",
"EntityAType": "IP",
"EntityB": "0.0.0.3",
"EntityBType": "IP"
},
{
"Relationship": "resolves-to",
"EntityA": "0.0.0.1",
"EntityAType": "IP",
"EntityB": "dns.dummy",
"EntityBType": "Domain"
},
{
"Relationship": "resolves-to",
"EntityA": "0.0.0.1",
"EntityAType": "IP",
"EntityB": "dns.dummy.com",
"EntityBType": "Domain"
}
]
},
"TeamCymruScout": {
"IP": {
"ip": "0.0.0.1",
"country_codes": [
"US"
],
"as_info": [
{
"asn": 15169,
"as_name": "DUMMY, US"
}
],
"tags": [
{
"id": 176,
"name": "cdn",
"children": [
{
"id": 210,
"name": "cloudflare"
}
]
}
],
"event_count": 164273621518,
"summary": {
"last_seen": "2024-06-27",
"whois": {
"asn": 15169,
"as_name": "DUMMY",
"net_name": "DUMMY",
"org_name": "Dummy LLC"
},
"open_ports": [
{
"ip": "0.0.0.1",
"port": 53,
"protocol": 17,
"protocol_text": "UDP",
"service": "domain",
"event_count": 296728
},
{
"ip": "0.0.0.1",
"port": 443,
"protocol": 6,
"protocol_text": "TCP",
"service": "https",
"event_count": 257
}
],
"pdns": [
{
"ip": "0.0.0.1",
"domain": "dns.dummy",
"event_count": 53408038
},
{
"ip": "0.0.0.1",
"domain": "dns.dummy.com",
"event_count": 2791811
}
],
"top_peers": [
{
"ip": "0.0.0.2",
"event_count": 2784287448
},
{
"ip": "0.0.0.3",
"event_count": 1469283767
}
],
"comms_total": 166356036813,
"service_counts": [
{
"proto": 17,
"proto_text": "",
"port": 53,
"event_count": 141248029324,
"service": {
"service_name": "domain",
"port": 53,
"proto_number": 17,
"description": "Domain Name Server"
}
},
{
"proto": 17,
"proto_text": "",
"port": 443,
"event_count": 7214447854,
"service": {
"service_name": "https",
"port": 443,
"proto_number": 17,
"description": "http protocol over TLS/SSL"
}
},
{
"proto": 6,
"proto_text": "",
"port": 443,
"event_count": 4130470538,
"service": {
"service_name": "https",
"port": 443,
"proto_number": 6,
"description": "http protocol over TLS/SSL"
}
}
],
"fingerprints": [
{
"ip": "0.0.0.1",
"type": "ja3s",
"signature": "00000000000000000000000000000001",
"event_count": 144337
},
{
"ip": "0.0.0.1",
"type": "ja3",
"signature": "00000000000000000000000000000001",
"event_count": 40708
}
],
"certs": [
{
"ip": "0.0.0.1",
"issuer": "CN=WR2, O=Dummy Trust Services, C=US",
"issuer_common_name": "WR2",
"common_name": "dns.dummy",
"port": 853,
"event_count": 418
},
{
"ip": "0.0.0.1",
"issuer": "CN=WR2, O=Dummy Trust Services, C=US",
"issuer_common_name": "WR2",
"common_name": "dns.dummy",
"port": 443,
"event_count": 372
}
]
}
},
"QueryUsage": {
"command_name": "scout-indicator-search",
"request_id": "00000000-0000-0000-0000-000000000001",
"total": 1,
"query": "0.0.0.1",
"size": 1,
"start_date": "2024-05-28",
"end_date": "2024-06-26",
"used_queries": 261,
"remaining_queries": 49739,
"query_limit": 50000,
"foundation_api_usage": {
"used_queries": 15,
"remaining_queries": 0,
"query_limit": 0
}
}
}
}
Human Readable Output
Summary Information for the given indicator: 0.0.0.1
Country Code(S) Whois Event Count Tags Last Seen US asn: 15169
as_name: DUMMY
net_name: DUMMY
org_name: Dummy LLC164273621518 - id: 176
name: cdn
children:
- id: 210
name: cloudflare2024-06-27 PDNS Information
Domain Event Count IP dns.dummy 53408038 0.0.0.1 dns.dummy.com 2791811 0.0.0.1 Open Ports Information
Event Count IP Port Protocol Protocol Text Service 296728 0.0.0.1 53 17 UDP domain 257 0.0.0.1 443 6 TCP https Top Peers Information
Source IP Event Count IP 0.0.0.1 2784287448 0.0.0.2 0.0.0.1 1469283767 0.0.0.3 Service Counts Information
Source IP Event Count Port Proto Service 0.0.0.1 141248029324 53 17 service_name: domain
port: 53
proto_number: 17
description: Domain Name Server0.0.0.1 7214447854 443 17 service_name: https
port: 443
proto_number: 17
description: http protocol over TLS/SSL0.0.0.1 4130470538 443 6 service_name: https
port: 443
proto_number: 6
description: http protocol over TLS/SSLFingerprints Information
Event Count IP Signature Type 144337 0.0.0.1 00000000000000000000000000000001 ja3s 40708 0.0.0.1 00000000000000000000000000000001 ja3 Certs Information
Common Name Event Count IP Issuer Issuer Common Name Port dns.dummy 418 0.0.0.1 CN=WR2, O=Dummy Trust Services, C=US WR2 853 dns.dummy 372 0.0.0.1 CN=WR2, O=Dummy Trust Services, C=US WR2 443 API Usage
Used Queries Remaining Queries Query Limit Foundation Used Queries Foundation Remaining Queries Foundation Query Limit 261 49739 50000 15 0 0
scout-ip-list
Returns the summary information available for the given list of IP addresses.
Base Command
scout-ip-list
Input
| Argument Name | Description | Required |
|---|---|---|
| ip_addresses | A comma-separated list of IP addresses to retrieve available IP details. Note: Maximum of 10 IP addresses are allowed. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| TeamCymruScout.IP.ip | String | The IP address. |
| TeamCymruScout.IP.country_code | String | The country code. |
| TeamCymruScout.IP.as_info.asn | Number | The autonomous system number. |
| TeamCymruScout.IP.as_info.as_name | String | The autonomous system name. |
| TeamCymruScout.IP.insights.overall_rating | String | The overall rating for the IP address. |
| TeamCymruScout.IP.insights.insights.rating | String | The individual insight rating for the IP address. |
| TeamCymruScout.IP.insights.insights.message | String | The individual insight message for the IP address. |
| TeamCymruScout.IP.tags.id | Number | The ID of the tag. |
| TeamCymruScout.IP.tags.name | String | The name of the tag. |
| TeamCymruScout.IP.tags.children.id | Number | The ID of the child tag. |
| TeamCymruScout.IP.tags.children.name | String | The name of the child tag. |
| TeamCymruScout.IP.tags.children.children | Unknown | The children of the child tag. |
| TeamCymruScout.QueryUsage.command_name | String | The name of the Cortex XSOAR command that triggered the Foundation API. |
| TeamCymruScout.QueryUsage.request_id | String | The unique request ID of the Foundation API response. |
| TeamCymruScout.QueryUsage.ips | Unknown | The list of IP addresses for which the Foundation API was triggered. |
| TeamCymruScout.QueryUsage.used_queries | Number | The number of queries used. |
| TeamCymruScout.QueryUsage.remaining_queries | Number | The number of remaining queries. |
| TeamCymruScout.QueryUsage.query_limit | Number | The total number of queries allowed. |
| TeamCymruScout.QueryUsage.foundation_api_usage.used_queries | Number | The number of queries used for the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.remaining_queries | Number | The number of remaining queries for the Foundation API. |
| TeamCymruScout.QueryUsage.foundation_api_usage.query_limit | Number | The total number of queries allowed for the Foundation API. |
| IP.Address | String | IP address. |
| IP.Relationships.EntityA | String | The source of the relationship. |
| IP.Relationships.EntityB | String | The destination of the relationship. |
| IP.Relationships.Relationship | String | The name of the relationship. |
| IP.Relationships.EntityAType | String | The type of the source of the relationship. |
| IP.Relationships.EntityBType | String | The type of the destination of the relationship. |
| IP.ASN | String | The autonomous system name for the IP address, for example: “AS8948”. |
| IP.Hostname | String | The hostname that is mapped to this IP address. |
| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. |
| IP.Geo.Country | String | The country in which the IP address is located. |
| IP.Geo.Description | String | Additional information about the location. |
| IP.DetectionEngines | Number | The total number of engines that checked the indicator. |
| IP.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. |
| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. |
| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. |
| IP.Tags | Unknown | (List) Tags of the IP address. |
| IP.FeedRelatedIndicators.value | String | Indicators that are associated with the IP address. |
| IP.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the IP address. |
| IP.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the IP address. |
| IP.MalwareFamily | String | The malware family associated with the IP address. |
| IP.Organization.Name | String | The organization of the IP address. |
| IP.Organization.Type | String | The organization type of the IP address. |
| IP.ASOwner | String | The autonomous system owner of the IP address. |
| IP.Region | String | The region in which the IP address is located. |
| IP.Port | String | Ports that are associated with the IP address. |
| IP.Internal | Boolean | Whether the IP address is internal or external. |
| IP.UpdatedDate | Date | The date that the IP address was last updated. |
| IP.Registrar.Abuse.Name | String | The name of the contact for reporting abuse. |
| IP.Registrar.Abuse.Address | String | The address of the contact for reporting abuse. |
| IP.Registrar.Abuse.Country | String | The country of the contact for reporting abuse. |
| IP.Registrar.Abuse.Network | String | The network of the contact for reporting abuse. |
| IP.Registrar.Abuse.Phone | String | The phone number of the contact for reporting abuse. |
| IP.Registrar.Abuse.Email | String | The email address of the contact for reporting abuse. |
| IP.Campaign | String | The campaign associated with the IP address. |
| IP.TrafficLightProtocol | String | The Traffic Light Protocol (TLP) color that is suitable for the IP address. |
| IP.CommunityNotes.note | String | Notes on the IP address that were given by the community. |
| IP.CommunityNotes.timestamp | Date | The time in which the note was published. |
| IP.Publications.source | String | The source in which the article was published. |
| IP.Publications.title | String | The name of the article. |
| IP.Publications.link | String | A link to the original article. |
| IP.Publications.timestamp | Date | The time in which the article was published. |
| IP.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. |
| IP.ThreatTypes.threatcategoryconfidence | String | The confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category ‘malware’ means that the vendor rates that this is 90% confidence of being a malware. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The reputation score (0: Unknown, 1: Good, 2: Suspicious, 3: Bad). |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
Command example
!scout-ip-list ip_addresses="0.0.0.1"
Context Example
{
"DBotScore": [
{
"Indicator": "0.0.0.1",
"Reliability": "B - Usually reliable",
"Score": 2,
"Type": "ip",
"Vendor": "Team Cymru Scout"
}
],
"IP": [
{
"Address": "0.0.0.1",
"ASN": 13335,
"ASOwner": "NET, US",
"Region": "US",
"Description": "0.0.0.1 has been identified as a \"cdn\", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority.",
"Geo": {
"Country": "US"
},
"Organization": {
"Name": "NET, US"
},
"Tags": "cdn: (cloudflare)"
}
],
"TeamCymruScout": {
"IP": [
{
"ip": "0.0.0.1",
"country_code": "US",
"as_info": [
{
"asn": 13335,
"as_name": "NET, US"
}
],
"insights": {
"overall_rating": "suspicious",
"insights": [
{
"rating": "suspicious",
"message": "0.0.0.1 has been identified as a \"cdn\", indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority."
}
]
},
"tags": [
{
"id": 81,
"name": "cdn",
"children": [
{
"id": 210,
"name": "cloudflare"
}
]
}
]
}
],
"QueryUsage": {
"command_name": "scout-ip-list",
"foundation_api_usage": {
"query_limit": 0,
"remaining_queries": 0,
"used_queries": 3
},
"ips": [
"0.0.0.1"
],
"query_limit": 50000,
"remaining_queries": 49840,
"request_id": "00000000-0000-0000-0000-000000000001",
"used_queries": 160
}
}
}
Human Readable Output
Summary Information for the given Suspicious IP: 0.0.0.1
Country Code AS Info Insights Tags US - asn: 13335
as_name: NET, USoverall_rating: suspicious
insights:
- rating: suspicious
message: 0.0.0.1 has been identified as a “cdn”, indicating private and reserved addresses defined by RFC 1918, RFC 5735, and RFC 6598, as well as net that have not been allocated to a Regional Internet Registry (RIR) by the Internet Assigned Numbers Authority.- id: 81
name: cdn
children:
- id: 210
name: cloudflareAPI Usage
Used Queries Remaining Queries Query Limit Foundation Used Queries Foundation Remaining Queries Foundation Query Limit 160 49840 50000 3 0 0
Configuration parameters
authentication_type— Authentication Type (required)api_key—basic_auth— UsernameintegrationReliability— Source Reliabilitycreate_relationships— Create relationshipsuse_foundation_api— Use Foundation API for IP enrichmentproxy— Use system proxy settingsinsecure— Trust any certificate (not secure)
Commands (4)
-
ipReturn all the detailed information available for the given IP address.
-
scout-api-usageReturns all the information on used queries and remaining queries with the query limit.
-
scout-indicator-searchReturn the summary information available for the given domain or IP address using Scout query language.
-
scout-ip-listReturns the summary information available for the given list of IP addresses.
"""IMPORTS""" from copy import deepcopy # noqa E402 from datetime import datetime # noqa E402 from typing import Any, Callable, Dict, List, Optional, Tuple # noqa E402 import urllib3 # noqa E402 import demistomock as demisto # noqa E402 from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa # Disable insecure warnings urllib3.disable_warnings() """ CONSTANTS """ DATE_FORMAT = "%Y-%m-%d" BASE_URL = "https://scout.cymru.com/api/scout" INDICATOR_SEARCH_URL = "https://scout.cymru.com/scout/details?query={}" MD_LINK = "[{}]({})" VENDOR_NAME = "Team Cymru Scout" TOTAL_RETRIES = 4 STATUS_CODE_TO_RETRY = [429, *(status_code for status_code in requests.status_codes._codes if status_code >= 500)] # type: ignore OK_CODES = [200, 201] BACKOFF_FACTOR = 7.5 # Sleep for [0s, 15s, 30s, 60s] between retries. DATE_FORMAT = "%Y-%m-%d" DEFAULT_START_DATE = "30 days" DEFAULT_END_DATE = "now" DEFAULT_PAGE_SIZE = 20 MINIMUM_PAGE_SIZE = 1 DEFAULT_PAGE_SIZE = 20 MINIMUM_DETAIL_IP_SIZE = 1 MAXIMUM_DETAIL_IP_SIZE = 1000 MINIMUM_DAY = 1 MAXIMUM_DAY = 30 MAXIMUM_START_DAY = 90 MAXIMUM_INDICATOR_SEARCH_SIZE = 5000 MAXIMUM_IP_LIST_SIZE = 10 DEFAULT_START_DATE = "30 days" START_DATE_LIMIT = "90 days" DEFAULT_END_DATE = "now" DBOT_SCORE_MAPPING = { "no_rating": 0, # Unknown "informational": 1, # Good "suspicious": 2, # Suspicious "malicious": 3, # Bad } SEVERITY_MAPPING = {"no_rating": "Unknown", "informational": "Good", "suspicious": "Suspicious", "malicious": "Bad"} KEYS_TO_REMOVE_FROM_AN_IP_AND_ADD_TO_USAGE_CONTEXT = ["request_id", "size", "start_date", "end_date"] API_KEY = "API Key" BASIC_AUTH = "Basic Auth" OUTPUT_PREFIX = {"IP": "TeamCymruScout.IP", "QUERY_USAGE": "TeamCymruScout.QueryUsage"} OUTPUT_KEY_FIELD = { "IP": "ip", "QUERY_USAGE": "command_name", } ENDPOINTS = { "LIST_IPS": "/ip/foundation", "IP_DETAILS": "/ip/{}/details", "QUERY_USAGE": "/usage", "SEARCH_INDICATORS": "/search", } ERROR_MESSAGES = { "NO_PARAM_PROVIDED": "Please provide the {}.", "INVALID_PAGE_SIZE": "{} is invalid value for size. Value of size should be between {} and {}.", "START_DATE_GREATER_THAN_END_DATE": "Please provide the start date less than the end date.", "END_DATE_GREATER_THAN_CURRENT_TIME": "Please provide the end date less than current time.", "REACHED_MAXIMUM_DIFF_DAYS": f"Please provide the start date less than {MAXIMUM_DAY} days from the end date.", "REACHED_MAXIMUM_START_DAYS": f"Please provide the start date less than {MAXIMUM_START_DAY} days.", "INVALID_DAY": "{} is invalid value for days." f"Value of days should be between {MINIMUM_DAY} and {MAXIMUM_DAY}.", # noqa: ISC001 "NO_INDICATORS_FOUND": "No indicators found for given query and filters.", "INVALID_IP_ADDRESSES": "The following IP Addresses were found invalid: {}", "INVALID_IP_ADDRESS_SIZE": ( "{} valid IP Addresses provided. Please provide the list of IP Addresses less than or equal to {}." ), } """ CLIENT CLASS """ class Client(BaseClient): """ Client class to interact with the Team Cymru Scout server API. This Client implements API calls, and does not contain any XSOAR logic. """ def __init__(self, server_url: str, verify: bool, proxy: bool, headers: dict, auth: tuple | None): """ Initializes the Client class with the provided parameters. :type server_url: ``str`` :param server_url: The URL of the Team Cymru Scout server. :type verify: ``bool`` :param verify: Whether to verify the server's SSL certificate. :type proxy: ``bool`` :param proxy: The proxy settings to be used. :type headers: ``Dict`` :param headers: Additional headers to be included in the requests. :type auth: ``Optional[Tuple]`` :param auth: The authentication tuple to be used. """ super().__init__(base_url=server_url, verify=verify, proxy=proxy, headers=headers, auth=auth) def http_request(self, *args, **kwargs): """ A wrapper for BaseClient.http_request method with the retries added. :type args: ``tuple`` :param args: The tuple to send in a request. :type kwargs: ``Dict`` :param kwargs: The dictionary to send in a request. :return: Depends on the resp_type parameter. :rtype: ``Dict`` or ``str`` or ``bytes`` or ``xml.etree.ElementTree.Element`` or ``requests.Response`` """ return self._http_request( retries=TOTAL_RETRIES, status_list_to_retry=STATUS_CODE_TO_RETRY, backoff_factor=BACKOFF_FACTOR, raise_on_redirect=False, ok_codes=OK_CODES, raise_on_status=True, *args, **kwargs, ) # type: ignore def scout_api_usage_request(self) -> dict: """ A function to request the information for the API usage. :return: The response containing the api usage. :rtype: ``Dict`` """ response = self.http_request("GET", ENDPOINTS["QUERY_USAGE"]) return response def ip_request(self, ip: str, start_date: str | None, end_date: str | None, days: int | None, size: int | None) -> dict: """ A function to request the information for the given IP. :type ip: ``str`` :param ip: The IP to search for. :type start_date: ``Optional[str]`` :param start_date: The start date for detailed information. :type end_date: ``Optional[str]`` :param end_date: The end date for detailed information. :type days: ``Optional[int]`` :param days: The number of days in past for detailed information. :type size: ``Optional[int]`` :param size: The number of results to return. :return: The response containing information for the given IP. :rtype: ``Dict`` """ params = assign_params(start_date=start_date, end_date=end_date, days=days, size=size) response = self.http_request("GET", ENDPOINTS["IP_DETAILS"].format(ip), params=params) return response def scout_indicator_search_request( self, query: str, start_date: str | None, end_date: str | None, days: int | None, size: int | None ) -> dict: """ A function to search the indicators based on specified parameters. :type query: str :param query: The query to search for. :type start_date: Optional[str] :param start_date: The start date to filter indicators. :type end_date: Optional[str] :param end_date: The end date to filter indicators. :type days: Optional[int] :param days: The number of days in past to filter indicators. :type size: Optional[int] :param size: The number of results to return. :rtype: Dict[str, str] :return: The response containing the details for the queried indicators. """ params = assign_params(query=query, start_date=start_date, end_date=end_date, days=days, size=size) response = self.http_request("GET", ENDPOINTS["SEARCH_INDICATORS"], params=params) return response def scout_ip_list(self, params) -> dict: """ A function to request the information for the IPs. :type params: Dict :param params: The parameters to send in the request. :rtype: Dict[str, str] :return: The response containing the ip's data. """ response = self.http_request("GET", ENDPOINTS["LIST_IPS"], params=params) return response """ HELPER FUNCTIONS """ def trim_spaces_from_args(args: dict): """Remove space from args.""" for key in args: if isinstance(args[key], str): args[key] = args[key].strip() return args def validate_params(params: dict): """ Validate the parameters. :type params: ``Dict`` :param params: Params to validate. """ authentication_type: str = params.get("authentication_type", "") if authentication_type == API_KEY: api_key = str(params.get("api_key", {}).get("password", "")).strip() if not api_key: raise DemistoException(ERROR_MESSAGES["NO_PARAM_PROVIDED"].format(API_KEY)) elif authentication_type == BASIC_AUTH: basic_auth = params.get("basic_auth", {}) username = str(basic_auth.get("identifier", "")).strip() if not username: raise DemistoException(ERROR_MESSAGES["NO_PARAM_PROVIDED"].format("Username")) password = str(basic_auth.get("password", "")).strip() if not password: raise DemistoException(ERROR_MESSAGES["NO_PARAM_PROVIDED"].format("Password")) def header_transformer_for_ip(header: str) -> str: """ To transform the header for the markdown table. :type header: ``str`` :param header: Header name. :return: The title cased header. :rtype: ``str`` """ return header.replace("_", " ").title().replace("Ip", "IP") def create_tag_list(tags: list) -> str: """ Create comma separated tag list. :type tags: ``list`` :param tags: List of tags from response. :return: Comma separated tag list. :rtype: ``str`` """ tag_list = [] for tag_dict in tags: tag = tag_dict.get("name", "") sub_tags = [] for child_tag in tag_dict.get("children", []): sub_tags.append(child_tag.get("name", "")) if sub_tags: tag += f': ({", ".join(sub_tags)})' tag_list.append(tag) return ", ".join(tag_list) def remove_empty_elements_for_hr(d): """ Recursively remove empty lists, empty dicts, or None elements from a dictionary. :type d: ``dict`` :param d: Input dictionary. :return: Dictionary with all empty lists, and empty dictionaries removed. :rtype: ``dict`` """ def empty(x): return x is None or x == {} or x == [] or x == "" if not isinstance(d, dict | list): return d elif isinstance(d, list): return [v for v in (remove_empty_elements_for_hr(v) for v in d) if not empty(v)] else: return {k: v for k, v in ((k, remove_empty_elements_for_hr(v)) for k, v in d.items()) if not empty(v)} def validate_common_search_command_args( args: dict[str, str], required_arg: str, maximum_page_size: int = MAXIMUM_DETAIL_IP_SIZE ) -> tuple: """ To validate common arguments of all command. :type args: ``dict`` :param args: Command arguments. :type required_arg: ``str`` :param required_arg: Required argument. :type maximum_page_size: ``int`` :param maximum_page_size: Maximum page size. :rtype: Tuple :return: The tuple containing the extracted arguments with pagination parameters. """ required_arg_val: str = args.get(required_arg, "") if not required_arg_val: raise DemistoException(ERROR_MESSAGES["NO_PARAM_PROVIDED"].format(required_arg)) start_date_str = args.get("start_date", DEFAULT_START_DATE) end_date_str = args.get("end_date", DEFAULT_END_DATE) start_date_obj = arg_to_datetime(start_date_str, "start_date") end_date_obj = arg_to_datetime(end_date_str, "end_date") current_date_obj = arg_to_datetime(DEFAULT_END_DATE) start_date = start_date_obj.strftime(DATE_FORMAT) if isinstance(start_date_obj, datetime) else start_date_obj start_date_obj = arg_to_datetime(start_date) end_date = end_date_obj.strftime(DATE_FORMAT) if isinstance(end_date_obj, datetime) else end_date_obj end_date_obj = arg_to_datetime(end_date) if start_date_obj > end_date_obj: # type: ignore raise DemistoException(ERROR_MESSAGES["START_DATE_GREATER_THAN_END_DATE"]) if end_date_obj > current_date_obj: # type: ignore raise DemistoException(ERROR_MESSAGES["END_DATE_GREATER_THAN_CURRENT_TIME"]) if start_date_obj <= current_date_obj - timedelta(days=MAXIMUM_START_DAY): # type: ignore raise DemistoException(ERROR_MESSAGES["REACHED_MAXIMUM_START_DAYS"]) if end_date_obj - start_date_obj >= timedelta(days=MAXIMUM_DAY): # type: ignore if start_date_str.lower() in DEFAULT_START_DATE: start_date_obj += timedelta(days=1) # type: ignore start_date = start_date_obj.strftime(DATE_FORMAT) # type: ignore else: raise DemistoException(ERROR_MESSAGES["REACHED_MAXIMUM_DIFF_DAYS"]) days = arg_to_number(args.get("days"), "days") if isinstance(days, int) and not (MINIMUM_DAY <= days <= MAXIMUM_DAY): raise DemistoException(ERROR_MESSAGES["INVALID_DAY"].format(days)) size = arg_to_number(args.get("size", DEFAULT_PAGE_SIZE), "size") if isinstance(size, int) and not (MINIMUM_PAGE_SIZE <= size <= maximum_page_size): raise DemistoException(ERROR_MESSAGES["INVALID_PAGE_SIZE"].format(size, MINIMUM_PAGE_SIZE, maximum_page_size)) return required_arg_val, start_date, end_date, days, size def validate_ip_addresses(ips_list: list[str]) -> tuple[list[str], list[str]]: """ Given a list of IP addresses, returns the invalid and valid ips. :type ips_list: ``List[str]`` :param ips_list: List of ip addresses. :return: invalid_ip_addresses and valid_ip_addresses. :rtype: ``Tuple[List[str], List[str]]`` """ invalid_ip_addresses = [] valid_ip_addresses = [] for ip in ips_list: ip = ip.strip().strip('"') if ip: if is_ip_valid(ip, accept_v6_ips=True): valid_ip_addresses.append(ip) else: invalid_ip_addresses.append(ip) return invalid_ip_addresses, valid_ip_addresses def validate_ip_list_args(args: dict) -> dict: """ Validate the ip list arguments. :param args: Arguments to validate. :type args: Dict :return: Validated arguments. :rtype: Dict """ ip_addresses = argToList(args.get("ip_addresses")) invalid_ips, valid_ips = validate_ip_addresses(ip_addresses) if invalid_ips: return_warning( ERROR_MESSAGES["INVALID_IP_ADDRESSES"].format(", ".join(invalid_ips)), exit=len(invalid_ips) == len(ip_addresses) ) if not valid_ips: raise DemistoException(ERROR_MESSAGES["NO_PARAM_PROVIDED"].format("ip_addresses")) if len(valid_ips) > 10: raise DemistoException(ERROR_MESSAGES["INVALID_IP_ADDRESS_SIZE"].format(len(valid_ips), MAXIMUM_IP_LIST_SIZE)) return {"ips": ",".join(valid_ips)} def remove_key_from_ip_and_add_to_usage(ip_response: dict, usage_response: dict) -> tuple[dict, dict]: """ Prepare context ip command. :type ip_response: ``dict`` :param ip_response: Response contain detailed information about ip. :type usage_response: ``dict`` :param usage_response: Response contain information about api usage. :return: Modified ip_response and usage_response. :rtype: ``Tuple[Dict, Dict]`` """ for key in KEYS_TO_REMOVE_FROM_AN_IP_AND_ADD_TO_USAGE_CONTEXT: usage_response[key] = ip_response.get(key) del ip_response[key] usage_response["command_name"] = "ip" del ip_response["usage"] return ip_response, usage_response def find_description(ip: str, insights: list) -> str: """ Finding the description for ip from insights response. :type ip: ``str`` :param ip: Used to find description. :type insights: ``list`` :param insights: Insights related to ip. :return: Description related to ip. :rtype: ``str`` """ description = "" for insight in insights: message = insight.get("message") if ip in message: return message description += message description += "\n" return description def prepare_hr_for_ip(response: dict) -> str: """ Prepare Human Readable output for ip command. :type response: ``Dict`` :param response: Response from API. :rtype: ``str`` :return: Human readable output. """ data = response summary_hr = [ { "Country Code": data.get("summary", {}).get("geo_ip_cc"), "Whois": remove_empty_elements_for_hr(data.get("summary", {}).get("whois")), "Tags": remove_empty_elements_for_hr(data.get("summary", {}).get("tags", [])), "Insights": remove_empty_elements_for_hr(data.get("summary", {}).get("insights", {}).get("insights")), } ] severity = SEVERITY_MAPPING.get((response.get("summary", {}).get("insights", {}).get("overall_rating")).lower()) ip_md_link = MD_LINK.format(data.get("ip"), INDICATOR_SEARCH_URL.format(data.get("ip"))) for pdns_data in data.get("summary", {}).get("pdns", {}).get("top_pdns", []): del pdns_data["css_color"] pdns_hr = data.get("summary", {}).get("pdns", {}).get("top_pdns", []) top_peers_hr = [ { "Proto": peer.get("proto_text"), "Event Count": peer.get("event_count"), "Server IP": peer.get("local", {}).get("ip"), "Server Country Code(s)": peer.get("local", {}).get("country_codes"), "Server Tag(s)": create_tag_list(tags=peer.get("local", {}).get("tags", [])), "Server Services": remove_empty_elements_for_hr(peer.get("local", {}).get("top_services", [])[:5]), "Server AS Name": [as_info.get("as_name") for as_info in peer.get("local", {}).get("as_info", [])], "Client IP": peer.get("peer", {}).get("ip"), "Client Country Code(s)": peer.get("peer", {}).get("country_codes"), "Client Tag(s)": create_tag_list(tags=peer.get("peer", {}).get("tags", [])), "Client Services": remove_empty_elements_for_hr(peer.get("peer", {}).get("top_services", [])[:5]), "Client AS Name": [as_info.get("as_name") for as_info in peer.get("peer", {}).get("as_info", [])], "First Seen": peer.get("first_seen"), "Last Seen": peer.get("last_seen"), } for peer in data.get("communications", {}).get("peers", [])[:5] ] open_port_hr = [ { "Event Count": port_data.get("event_count"), "Port": port_data.get("port"), "Protocol": port_data.get("protocol"), "Protocol Text": port_data.get("protocol_text"), "Service": port_data.get("service"), "First Seen": port_data.get("first_seen"), "Last Seen": port_data.get("last_seen"), } for port_data in data.get("summary", {}).get("open_ports", {}).get("top_open_ports", []) ] fingerprints_hr = data.get("summary", {}).get("fingerprints", {}).get("top_fingerprints", []) for certs_data in data.get("summary", {}).get("certs", {}).get("top_certs", []): del certs_data["css_color"] certs_hr = data.get("summary", {}).get("certs", {}).get("top_certs", []) hr_list = [summary_hr, pdns_hr, top_peers_hr, open_port_hr, fingerprints_hr, certs_hr] new_hr_list = [] for hr_data in hr_list: hr_data = remove_empty_elements_for_hr(hr_data) [remove_nulls_from_dictionary(data) for data in hr_data] new_hr_list.append(hr_data) (summary_hr, pdns_hr, top_peers_hr, open_port_hr, fingerprints_hr, certs_hr) = new_hr_list human_readable = ( tableToMarkdown( f"Summary Information For The Given {severity} IP: {ip_md_link}", summary_hr, json_transform_mapping={"Whois": JsonTransformer(), "Insights": JsonTransformer(), "Tags": JsonTransformer()}, removeNull=True, headers=["Country Code", "Whois", "Tags", "Insights"], ) + "\n" ) human_readable += ( tableToMarkdown("Top PDNS", pdns_hr, headerTransform=header_transformer_for_ip, removeNull=True) + "\n" if pdns_hr else "" ) human_readable += ( tableToMarkdown( "Top Peers", top_peers_hr, removeNull=True, json_transform_mapping={"Client Services": JsonTransformer(), "Server Services": JsonTransformer()}, headers=[ "Proto", "Client IP", "Client Country Code(s)", "Client Tag(s)", "Client Services", "Server IP", "Server Country Code(s)", "Server Tag(s)", "Server Services", "Event Count", "First Seen", "Last Seen", "Client AS Name", "Server AS Name", ], ) + "\n" if top_peers_hr else "" ) human_readable += ( tableToMarkdown( "Top Open Ports", open_port_hr, removeNull=True, headers=["Event Count", "Port", "Protocol", "Protocol Text", "Service", "First Seen", "Last Seen"], ) + "\n" if open_port_hr else "" ) human_readable += ( tableToMarkdown("Top Fingerprints", fingerprints_hr, removeNull=True, headerTransform=header_transformer_for_ip) + "\n" if fingerprints_hr else "" ) human_readable += ( tableToMarkdown("Top Certificates", certs_hr, removeNull=True, headerTransform=header_transformer_for_ip) + "\n" if certs_hr else "" ) return human_readable def create_relationship_for_indicator_search(response: dict) -> list: """ Create a list of relationships objects from the response. :type response: ``dict`` :param response: Response of API. :return: List of EntityRelationship objects containing all the relationships. :rtype: ``List`` """ relationships = [] source_ip = response.get("ip", "") integration_reliability = demisto.params().get("integrationReliability") for peer in response.get("summary", {}).get("top_peers", []): client_ip = peer.get("ip") fields = {key: value for key, value in peer.items() if key != "ip"} relationships.append( EntityRelationship( name=EntityRelationship.Relationships.COMMUNICATED_WITH, entity_a=source_ip, entity_a_type=FeedIndicatorType.IP, entity_b=client_ip, entity_b_type=FeedIndicatorType.IP, source_reliability=integration_reliability, brand=VENDOR_NAME, fields=fields, ) ) for pdns in response.get("summary", {}).get("pdns", []): ip = pdns.get("ip") domain = pdns.get("domain") fields = {key: value for key, value in pdns.items() if key not in ["ip", "domain"]} relationships.append( EntityRelationship( name=EntityRelationship.Relationships.RESOLVES_TO, entity_a=ip, entity_a_type=FeedIndicatorType.IP, entity_b=domain, entity_b_type=FeedIndicatorType.Domain, source_reliability=integration_reliability, brand=VENDOR_NAME, fields=fields, ) ) return relationships def prepare_hr_and_context_for_indicator_search(response: dict) -> tuple[str, dict, Common.IP, list]: """ A function to prepare the human readable and context output for the indicator search. :type response: Dict :param response: The response containing the list of indicators. :rtype: Tuple[str, Dict, Common.IP, List] :return: The human readable, context output, IP indicator and relationships. """ scout_ip_data = remove_empty_elements(response) remove_nulls_from_dictionary(scout_ip_data) ip_address = scout_ip_data.get("ip") dbot_score = Common.DBotScore( indicator=ip_address, indicator_type=DBotScoreType.IP, integration_name=VENDOR_NAME, score=Common.DBotScore.NONE, reliability=demisto.params().get("integrationReliability"), ) relationships = [] create_relationships = demisto.params().get("create_relationships") if create_relationships: relationships = create_relationship_for_indicator_search(response) country_codes = scout_ip_data.get("country_codes", []) scout_ip_hr = [ { "Country Code(s)": country_codes, "Whois": scout_ip_data.get("summary").get("whois"), "Event Count": scout_ip_data.get("event_count"), "Tags": scout_ip_data.get("tags", []), "Last Seen": scout_ip_data.get("summary", {}).get("last_seen"), } ] pdns_hr = list(scout_ip_data.get("summary", {}).get("pdns", [])) open_ports_hr = list(scout_ip_data.get("summary", {}).get("open_ports", [])) top_peers_hr = [{"Source IP": ip_address, **top_peer} for top_peer in scout_ip_data.get("summary", {}).get("top_peers", [])] service_counts_hr = [ {"Source IP": ip_address, **service_count} for service_count in scout_ip_data.get("summary", {}).get("service_counts", []) ] fingerprints_hr = list(scout_ip_data.get("summary", {}).get("fingerprints", [])) certs_hr = list(scout_ip_data.get("summary", {}).get("certs", [])) hr_list = [scout_ip_hr, pdns_hr, open_ports_hr, top_peers_hr, service_counts_hr, fingerprints_hr, certs_hr] new_hr_list = [] for hr_data in hr_list: hr_data = remove_empty_elements(hr_data) [remove_nulls_from_dictionary(data) for data in hr_data] new_hr_list.append(hr_data) (scout_ip_hr, pdns_hr, open_ports_hr, top_peers_hr, service_counts_hr, fingerprints_hr, certs_hr) = new_hr_list top_host_name = None top_host_event_count = 0 for pdn in pdns_hr: if pdn.get("event_count") > top_host_event_count: top_host_event_count = pdn.get("event_count") top_host_name = pdn.get("domain") ip_indicator = Common.IP( ip=ip_address, dbot_score=dbot_score, asn=response.get("summary", {}).get("whois", {}).get("asn"), as_owner=response.get("summary", {}).get("whois", {}).get("as_name"), region=", ".join(country_codes), port=",".join([str(open_port.get("port", "")) for open_port in response.get("summary", {}).get("open_ports", [])]), updated_date=response.get("summary", {}).get("last_seen"), organization_name=response.get("summary", {}).get("whois", {}).get("org_name"), hostname=top_host_name, geo_country=", ".join(country_codes), tags=create_tag_list(scout_ip_data.get("tags", [])), relationships=relationships, ) ip_md_link = MD_LINK.format(ip_address, INDICATOR_SEARCH_URL.format(ip_address)) human_readable = ( tableToMarkdown( f"Summary Information for the given indicator: {ip_md_link}", scout_ip_hr, json_transform_mapping={"Whois": JsonTransformer(), "Tags": JsonTransformer()}, removeNull=True, headerTransform=header_transformer_for_ip, headers=["IP", "Country Code(s)", "Whois", "Event Count", "Tags", "Last Seen"], ) + "\n" ) human_readable += ( tableToMarkdown("PDNS Information", pdns_hr, headerTransform=header_transformer_for_ip) + "\n" if pdns_hr else "" ) human_readable += ( tableToMarkdown("Open Ports Information", open_ports_hr, headerTransform=header_transformer_for_ip) + "\n" if open_ports_hr else "" ) human_readable += ( tableToMarkdown("Top Peers Information", top_peers_hr, headerTransform=header_transformer_for_ip) + "\n" if top_peers_hr else "" ) human_readable += ( tableToMarkdown("Service Counts Information", service_counts_hr, headerTransform=header_transformer_for_ip) + "\n" if service_counts_hr else "" ) human_readable += ( tableToMarkdown("Fingerprints Information", fingerprints_hr, headerTransform=header_transformer_for_ip) + "\n" if fingerprints_hr else "" ) human_readable += ( tableToMarkdown("Certs Information", certs_hr, headerTransform=header_transformer_for_ip) + "\n" if certs_hr else "" ) return human_readable, scout_ip_data, ip_indicator, relationships def prepare_hr_and_context_for_ip_list(response: dict) -> tuple[str, dict, Common.IP]: """ A function to prepare the human readable and context output for the ip list command. :type response: dict :param response: The response from the server. :rtype: Tuple[str, Dict, Common.IP] :return: The human readable, context output and the indicator for the ip. """ scout_ip_data = remove_empty_elements(response) ip_address = scout_ip_data.get("ip") score = DBOT_SCORE_MAPPING[scout_ip_data.get("insights", {}).get("overall_rating") or "no_rating"] country_code = scout_ip_data.get("country_code", "") as_info = scout_ip_data.get("as_info", []) as_name = "" asn = "" if isinstance(as_info, list) and len(as_info) > 0: as_info_dict = as_info[0] as_name = as_info_dict.get("as_name", "") asn = as_info_dict.get("asn", "") dbot_score = Common.DBotScore( indicator=ip_address, indicator_type=DBotScoreType.IP, integration_name=VENDOR_NAME, score=score, reliability=demisto.params().get("integrationReliability"), ) tags = create_tag_list(scout_ip_data.get("tags", [])) insight_message = find_description(ip_address, scout_ip_data.get("insights", {}).get("insights", [])) ip_ioc = Common.IP( ip=ip_address, dbot_score=dbot_score, asn=asn, as_owner=as_name, region=country_code, geo_country=country_code, tags=tags, description=insight_message, organization_name=as_name, ) ip_md_link = MD_LINK.format(ip_address, INDICATOR_SEARCH_URL.format(ip_address)) hr_list = [ { "Country Code": scout_ip_data.get("country_code", ""), "AS Info": scout_ip_data.get("as_info", ""), "Insights": scout_ip_data.get("insights", ""), "Tags": scout_ip_data.get("tags", ""), } ] table_title = f"Summary Information for the given {scoreToReputation(score)} IP: {ip_md_link}" table_headers = ["Country Code", "AS Info", "Insights", "Tags"] hr = tableToMarkdown( table_title, hr_list, removeNull=True, headers=table_headers, json_transform_mapping={"AS Info": JsonTransformer(), "Insights": JsonTransformer(), "Tags": JsonTransformer()}, ) return hr, scout_ip_data, ip_ioc def prepare_hr_and_context_for_api_usage(response: dict, command_name: str) -> tuple[str, dict]: """ A function to prepare the human readable and context output for the api usage. :type response: dict :param response: The response containing the api usage. :type command_name: str :param command_name: The name of the command. :rtype: Tuple[str, Dict] :return: The human readable and context output for the api usage. """ hr_list = [ { "Used Queries": response.get("used_queries"), "Remaining Queries": response.get("remaining_queries"), "Query Limit": response.get("query_limit"), "Foundation Used Queries": response.get("foundation_api_usage", {}).get("used_queries"), "Foundation Remaining Queries": response.get("foundation_api_usage", {}).get("remaining_queries"), "Foundation Query Limit": response.get("foundation_api_usage", {}).get("query_limit"), } ] context = {"command_name": command_name, **response} table_headers = [ "Used Queries", "Remaining Queries", "Query Limit", "Foundation Used Queries", "Foundation Remaining Queries", "Foundation Query Limit", ] hr = tableToMarkdown("API Usage", hr_list, removeNull=True, headers=table_headers) return hr, context def create_relationship(response: dict) -> list: """ Create a list of relationships objects from the response. :type response: ``dict`` :param response: Response of API. :return: List of EntityRelationship objects containing all the relationships. :rtype: ``List`` """ relationships = [] for peer in response.get("communications", {}).get("peers", []): server_ip = peer.get("local", {}).get("ip") client_ip = peer.get("peer", {}).get("ip") relationships.append( EntityRelationship( name=EntityRelationship.Relationships.COMMUNICATED_WITH, entity_a=server_ip, entity_a_type=FeedIndicatorType.IP, entity_b=client_ip, entity_b_type=FeedIndicatorType.IP, source_reliability=demisto.params().get("integrationReliability"), brand=VENDOR_NAME, ) ) for pdns in response.get("pdns", {}).get("pdns", []): ip = pdns.get("ip") domain = pdns.get("domain") relationships.append( EntityRelationship( name=EntityRelationship.Relationships.RESOLVES_TO, entity_a=ip, entity_a_type=FeedIndicatorType.IP, entity_b=domain, entity_b_type=FeedIndicatorType.Domain, source_reliability=demisto.params().get("integrationReliability"), brand=VENDOR_NAME, ) ) return relationships def ip_enrichment_using_foundation_api(response: dict, command_name: str) -> tuple[list[CommandResults], CommandResults]: """ Process IP enrichment response from Foundation API. Args: response: API response containing IP data and usage information Returns: Tuple of (IP command results list, usage command result) """ ip_command_results = [] ips_data = deepcopy(response.get("data", [])) if not ips_data: ip_command_results.append( CommandResults( readable_output=ERROR_MESSAGES["NO_INDICATORS_FOUND"], ) ) else: for ip_response in ips_data: ip_hr, ip_context, ip_indicator = prepare_hr_and_context_for_ip_list(ip_response) ip_command_results.append( CommandResults( outputs_prefix=OUTPUT_PREFIX["IP"], outputs_key_field=OUTPUT_KEY_FIELD["IP"], outputs=ip_context, raw_response=ip_response, readable_output=ip_hr, indicator=ip_indicator, ) ) # Extract usage data (everything except 'data' field) usage_response = {key: value for key, value in response.items() if key != "data"} usage_data = usage_response.get("usage", {}) # Prepare usage context and human readable output usage_hr, usage_context = prepare_hr_and_context_for_api_usage(usage_data, command_name) usage_context.update(usage_response) remove_empty_elements(usage_context) usage_context.pop("usage", None) usage_command_result = CommandResults( outputs_prefix=OUTPUT_PREFIX["QUERY_USAGE"], outputs_key_field=OUTPUT_KEY_FIELD["QUERY_USAGE"], outputs=usage_context, raw_response=usage_response, readable_output=usage_hr, ) return ip_command_results, usage_command_result """ COMMAND FUNCTIONS """ def ip_command(client: Client, args: dict[str, Any]) -> list[CommandResults]: """ Retrieve the detail information of ip that meet the specified filter criteria. :type client: ``Client`` :param client: Object of Client class. :type args: ``Dict[str, Any]`` :param args: Arguments provided by user. :rtype: ``List[CommandResults]`` :return: List of standard command result. """ use_foundation_api = demisto.params().get("use_foundation_api", False) force_use_scout_details_api = argToBoolean(args.get("force_use_scout_details_api", "No")) ips, start_date, end_date, days, size = validate_common_search_command_args(args=args, required_arg="ip") size = arg_to_number(args.get("size"), "size") ips = argToList(args.get("ip")) invalid_ips, valid_ips = validate_ip_addresses(ips) if invalid_ips: return_warning( "The following IP Addresses were found invalid: {}".format(", ".join(invalid_ips)), exit=len(invalid_ips) == len(ips) ) command_results = [] # if force_use_scout_details_api is false and use_foundation_api is true than use founddation api. if not force_use_scout_details_api and use_foundation_api: for batch_ips in batch(valid_ips, batch_size=MAXIMUM_IP_LIST_SIZE): response = client.scout_ip_list(params={"ips": ",".join(batch_ips)}) ip_results, usage_result = ip_enrichment_using_foundation_api(response, "ip") command_results.extend(ip_results) # Add only last API usage command result command_results.append(usage_result) return command_results for ip in valid_ips: response = client.ip_request(ip, start_date, end_date, days, size) response = remove_empty_elements(response) ip_response, hr_response = deepcopy(response), deepcopy(response) usage_response = deepcopy(response.get("usage", {})) ip_response, usage_response = remove_key_from_ip_and_add_to_usage(ip_response, usage_response) ip_hr_output = prepare_hr_for_ip(response=hr_response) hr, context = prepare_hr_and_context_for_api_usage(usage_response, "ip") dbot_score = Common.DBotScore( indicator=ip, indicator_type=DBotScoreType.IP, integration_name=VENDOR_NAME, score=DBOT_SCORE_MAPPING.get(response.get("summary", {}).get("insights", {}).get("overall_rating") or "no_rating"), malicious_description=find_description(ip, response.get("summary", {}).get("insights", {}).get("insights", [])), reliability=demisto.params().get("integrationReliability"), ) relationships = [] create_relationships = demisto.params().get("create_relationships") if create_relationships: relationships = create_relationship(response) ip_indicator = Common.IP( ip=ip, asn=response.get("whois", {}).get("asn"), as_owner=response.get("whois", {}).get("as_name"), region=response.get("whois", {}).get("cc"), organization_name=response.get("whois", {}).get("org_name"), updated_date=response.get("whois", {}).get("modified"), description=find_description(ip, response.get("summary", {}).get("insights", {}).get("insights", [])), port=", ".join([str(data.get("port", "")) for data in response.get("open_ports", {}).get("open_ports", [])]), tags=create_tag_list(response.get("summary", {}).get("tags", [])), dbot_score=dbot_score, relationships=relationships, ) command_result = [ CommandResults( outputs_prefix=OUTPUT_PREFIX["IP"], outputs_key_field=OUTPUT_KEY_FIELD["IP"], outputs=ip_response, raw_response=response, readable_output=ip_hr_output, indicator=ip_indicator, relationships=relationships, ), CommandResults( outputs_prefix=OUTPUT_PREFIX["QUERY_USAGE"], outputs_key_field=OUTPUT_KEY_FIELD["QUERY_USAGE"], outputs=context, raw_response=response, readable_output=hr, ), ] command_results.extend(command_result) return command_results def scout_api_usage_command(client: Client, *_) -> CommandResults: """ The command function to request the information for the API usage. :type client: Client :param client: The client object. :rtype: CommandResults :return: The command results containing the human readable and context output for the api usage. """ response = client.scout_api_usage_request() hr, context = prepare_hr_and_context_for_api_usage(response, "scout-api-usage") command_results = CommandResults( outputs_prefix=OUTPUT_PREFIX["QUERY_USAGE"], outputs_key_field="command_name", outputs=context, raw_response=response, readable_output=hr, ) return command_results def scout_indicator_search_command(client: Client, args: dict[str, Any]) -> list[CommandResults]: """ The command function to request the information for the API usage. :type client: Client :param client: The client object. :type args: Dict :param args: The arguments passed to the command. :rtype: CommandResults :return: The command results containing the human readable and context output for the api usage. """ validated_args = validate_common_search_command_args(args, "query", MAXIMUM_INDICATOR_SEARCH_SIZE) response = client.scout_indicator_search_request(*validated_args) # type: ignore ips_response = response.get("ips", []) ip_command_results = [] if not ips_response: ip_command_results.append( CommandResults( readable_output=ERROR_MESSAGES["NO_INDICATORS_FOUND"], ) ) else: for ip_response in ips_response: raw_ip_response = deepcopy(ip_response) ip_response = remove_empty_elements(ip_response) ip_hr, ip_context, ip_indicator, relationships = prepare_hr_and_context_for_indicator_search(ip_response) ip_command_results.append( CommandResults( outputs_prefix=OUTPUT_PREFIX["IP"], outputs_key_field="ip", outputs=ip_context, raw_response=raw_ip_response, readable_output=ip_hr, indicator=ip_indicator, relationships=relationships, ) ) usage_response = {key: value for key, value in response.items() if key != "ips"} usage_hr, usage_context = prepare_hr_and_context_for_api_usage(usage_response.get("usage", {}), "scout-indicator-search") usage_context.update(usage_response) remove_empty_elements(usage_context) usage_context.pop("usage", None) usage_command_result = CommandResults( outputs_prefix=OUTPUT_PREFIX["QUERY_USAGE"], outputs_key_field="command_name", outputs=usage_context, raw_response=usage_response, readable_output=usage_hr, ) return [*ip_command_results, usage_command_result] def scout_ip_list_command(client: Client, args: dict) -> list[CommandResults]: """ A function to get the ip list from the Team Cymru Scout server. :type client: Client :param client: The client object. :type args: Dict :param args: The arguments passed to the command. :rtype: List[CommandResults] :return: The command results containing the human readable and context output for the ip list and api usage. """ validated_args = validate_ip_list_args(args) response = client.scout_ip_list(params=validated_args) # Using the Foundation API, it returns ip list ip_command_results and usage_command_result. ip_command_results, usage_command_result = ip_enrichment_using_foundation_api(response, "scout-ip-list") return [*ip_command_results, usage_command_result] def test_module(client: Client) -> str: """ Test the Team Cymru Scout instance configuration. :type client: ``Client`` :param: client: Object of Client class. :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ client.scout_api_usage_request() return "ok" def main() -> None: """main function, parses params and runs command functions.""" params = trim_spaces_from_args(demisto.params()) remove_nulls_from_dictionary(params) args = trim_spaces_from_args(demisto.args()) remove_nulls_from_dictionary(args) verify_certificate: bool = not argToBoolean(params.get("insecure", False)) proxy: bool = argToBoolean(params.get("proxy", False)) headers = {} authentication_type = params.get("authentication_type", "") auth_tuple = None if authentication_type == API_KEY: api_key = str(params.get("api_key", {}).get("password", "")).strip() headers["Authorization"] = f"Token {api_key}" elif authentication_type == BASIC_AUTH: basic_auth = params.get("basic_auth", {}) username = str(basic_auth.get("identifier", "")).strip() password = str(basic_auth.get("password", "")).strip() auth_tuple = (username, password) command = demisto.command() demisto.debug(f"Command being called is {command}.") try: urllib3.disable_warnings() validate_params(params) client: Client = Client(BASE_URL, verify_certificate, proxy, headers=headers, auth=auth_tuple) commands: dict[str, Callable] = { "ip": ip_command, "scout-api-usage": scout_api_usage_command, "scout-indicator-search": scout_indicator_search_command, "scout-ip-list": scout_ip_list_command, } if command == "test-module": return_results(test_module(client)) elif command in commands: return_results(commands[command](client, args)) else: raise NotImplementedError(f"{command} command is not implemented.") except Exception as e: return_error(str(e)) if __name__ in ["__main__", "builtin", "builtins"]: main()