SOCRadarRapidReputation
Enrich indicators (IP, Domain, URL, Hash) by obtaining reputation information via SOCRadar Rapid Reputation API.
Data Enrichment & Threat Intelligence · SOCRadar
Details
| ID | SOCRadarRapidReputation |
|---|---|
| Provider | SOCRadar |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
SOCRadar Rapid Reputation
Enrich indicators (IP, Domain, URL, Hash) by obtaining reputation information via SOCRadar’s Rapid Reputation API.
This integration was integrated and tested with the latest version of SOCRadar Rapid Reputation API.
Configure SOCRadarRapidReputation on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for SOCRadarRapidReputation.
-
Click Add instance to create and configure a new integration instance.
Parameter Description Required API Key The API Key to use for connection to SOCRadar Rapid Reputation API. True Trust any certificate (not secure) Trust any certificate (not secure). False Use system proxy settings Whether to use XSOAR’s system proxy settings to connect to the API. False Source Reliability Reliability of the source providing the intelligence data. False - Click Test to validate API key and connection to SOCRadar Rapid Reputation API.
Commands
You can execute these commands from the Cortex XSOAR 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.
How to obtain SOCRadar API key?
SOCRadar Rapid Reputation is an Advanced Intelligence API optimized for high-volume and fast reputation queries.
- Licensing Model: The features of this module are licensed separately from the standard SOCRadar platform package. To use the integration, your API key must be activated with “Rapid Reputation” privileges.
- Standalone Purchase: This service can be added to your existing SOCRadar subscription, or it can be purchased as a standalone key completely independent of a platform membership.
- Purchase & Activation: For API authorization, pricing information, or to purchase a new key, please contact our support team at support@socradar.io.
socradar-bulk-check
🎯 NEW FEATURE - Bulk check reputation for mixed list of indicators with automatic entity type detection.
This powerful command allows you to check reputation for a mixed list of IPs, domains, URLs, and hashes in a single command. The integration automatically detects the type of each indicator and processes it accordingly.
Base Command
socradar-bulk-check
Input
| Argument Name | Description | Required |
|---|---|---|
| indicators | Mixed list of indicators to check (IPs, domains, URLs, hashes). Automatically detects entity types. Supports comma-separated values. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| SOCRadarRapidReputation.BulkCheck.Entity | String | The queried entity value. |
| SOCRadarRapidReputation.BulkCheck.EntityType | String | Detected type of the entity. |
| SOCRadarRapidReputation.BulkCheck.DetectedType | String | Auto-detected entity type. |
| SOCRadarRapidReputation.BulkCheck.Score | Number | Reputation score of the entity. |
| SOCRadarRapidReputation.BulkCheck.IsWhitelisted | Boolean | Whether the entity is whitelisted. |
| SOCRadarRapidReputation.BulkCheck.FindingSources | Unknown | List of threat sources that detected this entity. |
| SOCRadarRapidReputation.BulkCheckSummary.total | Number | Total number of indicators checked. |
| SOCRadarRapidReputation.BulkCheckSummary.processed | Number | Number of successfully processed indicators. |
| SOCRadarRapidReputation.BulkCheckSummary.failed | Number | Number of failed indicators. |
| SOCRadarRapidReputation.BulkCheckSummary.by_type | Unknown | Breakdown by entity type (ip, hostname, url, hash). |
| SOCRadarRapidReputation.BulkCheckSummary.by_score | Unknown | Breakdown by score classification (malicious, suspicious, good, unknown, whitelisted). |
Command Example
!socradar-bulk-check indicators="1.1.1.1,malicious.example.com"
Use Cases for Bulk Check
-
Incident Response: Quickly check all IOCs extracted from a security incident
!socradar-bulk-check indicators="192.168.1.100,malware.example.com,3b7b359ea17ac76341957573e332a2d6bcac363401ac71c8df94dac93df6d792" -
Threat Intel Feed Processing: Validate a list of indicators from threat intelligence feeds
!socradar-bulk-check indicators="${File.Name}" -
Automated Playbooks: Use in playbooks to process multiple indicators in one step
!socradar-bulk-check indicators="${inputs.indicators}" -
Daily Security Monitoring: Check a list of suspicious entities identified during monitoring
!socradar-bulk-check indicators="suspicious_ip1,suspicious_domain1,suspicious_url1"
Output Features
The bulk check command provides:
- Summary Statistics:
- Total indicators processed
- Success/failure counts
- Breakdown by entity type (IPs, domains, URLs, hashes)
- Breakdown by threat level (malicious, suspicious, good, unknown, whitelisted)
- Individual Results:
- Each indicator gets its own detailed result card
- Includes reputation score, whitelisting status, and threat sources
- Clear classification (Malicious/Suspicious/Good/Unknown)
- Automatic Type Detection:
- IPs: Automatically detected (IPv4 and IPv6)
- Domains: Detected based on domain validation
- URLs: Detected by http:// or https:// prefix
- Hashes: Detected (MD5, SHA1, SHA256)
- Error Handling:
- Invalid indicators are reported with clear error messages
- Processing continues even if some indicators fail
- Failed indicators don’t stop the entire batch
Human Readable Output Example
📊 Bulk Check Summary
┌─────────────────────────┬───────┐
│ Metric │ Count │
├─────────────────────────┼───────┤
│ Total Indicators │ 10 │
│ Successfully Processed │ 9 │
│ Failed │ 1 │
│ IPs │ 3 │
│ Domains │ 4 │
│ URLs │ 2 │
│ Hashes │ 1 │
│ Malicious │ 2 │
│ Suspicious │ 3 │
│ Good │ 3 │
│ Unknown │ 1 │
│ Whitelisted │ 0 │
└─────────────────────────┴───────┘
[Followed by detailed results for each indicator]
Commands Overview
ip
Checks reputation of provided IP entities using SOCRadar Rapid Reputation API.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | IP entities to check reputation. (IPv4 or IPv6). Supports comma-separated values. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| SOCRadarRapidReputation.IP.Entity | String | The queried IP address. |
| SOCRadarRapidReputation.IP.EntityType | String | Type of the entity (ip). |
| SOCRadarRapidReputation.IP.Score | Number | Reputation score of the IP address. |
| SOCRadarRapidReputation.IP.IsWhitelisted | Boolean | Whether the IP is whitelisted. |
| SOCRadarRapidReputation.IP.FindingSources | Unknown | List of threat sources that detected this IP. |
| SOCRadarRapidReputation.IP.FindingSources.SourceName | String | Name of the threat intelligence source. |
| SOCRadarRapidReputation.IP.FindingSources.MainCategory | String | Primary threat category. |
| SOCRadarRapidReputation.IP.FindingSources.MaintainerName | String | Organization maintaining the threat list. |
| SOCRadarRapidReputation.IP.FindingSources.FirstSeenDate | Date | First time the IP was seen on this source. |
| SOCRadarRapidReputation.IP.FindingSources.LastSeenDate | Date | Last time the IP was seen on this source. |
| SOCRadarRapidReputation.IP.FindingSources.SeenCount | Number | Number of times the IP was observed on this source. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| IP.Address | String | IP address |
Command Example
!ip ip="1.1.1.1"
Human Readable Output
Example output showing reputation score, whitelisting status, and threat sources that have detected the IP.
domain
Checks reputation of provided domain entities using SOCRadar Rapid Reputation API.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | Domain entities to check reputation. Supports comma-separated values. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| SOCRadarRapidReputation.Domain.Entity | String | The queried domain. |
| SOCRadarRapidReputation.Domain.EntityType | String | Type of the entity (hostname). |
| SOCRadarRapidReputation.Domain.Score | Number | Reputation score of the domain. |
| SOCRadarRapidReputation.Domain.IsWhitelisted | Boolean | Whether the domain is whitelisted. |
| SOCRadarRapidReputation.Domain.FindingSources | Unknown | List of threat sources that detected this domain. |
| SOCRadarRapidReputation.Domain.FindingSources.SourceName | String | Name of the threat intelligence source. |
| SOCRadarRapidReputation.Domain.FindingSources.MainCategory | String | Primary threat category. |
| SOCRadarRapidReputation.Domain.FindingSources.MaintainerName | String | Organization maintaining the threat list. |
| SOCRadarRapidReputation.Domain.FindingSources.FirstSeenDate | Date | First time the domain was seen on this source. |
| SOCRadarRapidReputation.Domain.FindingSources.LastSeenDate | Date | Last time the domain was seen on this source. |
| SOCRadarRapidReputation.Domain.FindingSources.SeenCount | Number | Number of times the domain was observed on this source. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| Domain.Name | String | Domain name |
Command Example
!domain domain="example.com"
url
Checks reputation of provided URL entities using SOCRadar Rapid Reputation API.
Base Command
url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | URL entities to check reputation. Supports comma-separated values. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| SOCRadarRapidReputation.URL.Entity | String | The queried URL. |
| SOCRadarRapidReputation.URL.EntityType | String | Type of the entity (url). |
| SOCRadarRapidReputation.URL.Score | Number | Reputation score of the URL. |
| SOCRadarRapidReputation.URL.IsWhitelisted | Boolean | Whether the URL is whitelisted. |
| SOCRadarRapidReputation.URL.FindingSources | Unknown | List of threat sources that detected this URL. |
| SOCRadarRapidReputation.URL.FindingSources.SourceName | String | Name of the threat intelligence source. |
| SOCRadarRapidReputation.URL.FindingSources.MainCategory | String | Primary threat category. |
| SOCRadarRapidReputation.URL.FindingSources.MaintainerName | String | Organization maintaining the threat list. |
| SOCRadarRapidReputation.URL.FindingSources.FirstSeenDate | Date | First time the URL was seen on this source. |
| SOCRadarRapidReputation.URL.FindingSources.LastSeenDate | Date | Last time the URL was seen on this source. |
| SOCRadarRapidReputation.URL.FindingSources.SeenCount | Number | Number of times the URL was observed on this source. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| URL.Data | String | URL |
Command Example
!url url="https://malicious.example.com/file.exe"
file
Checks reputation of provided file hash entities using SOCRadar Rapid Reputation API.
Base Command
file
Input
| Argument Name | Description | Required |
|---|---|---|
| file | File hash entities to check reputation. (MD5, SHA1, or SHA256). Supports comma-separated values. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| SOCRadarRapidReputation.File.Entity | String | The queried file hash. |
| SOCRadarRapidReputation.File.EntityType | String | Type of the entity (hash). |
| SOCRadarRapidReputation.File.Score | Number | Reputation score of the hash. |
| SOCRadarRapidReputation.File.IsWhitelisted | Boolean | Whether the hash is whitelisted. |
| SOCRadarRapidReputation.File.FindingSources | Unknown | List of threat sources that detected this hash. |
| SOCRadarRapidReputation.File.FindingSources.SourceName | String | Name of the threat intelligence source. |
| SOCRadarRapidReputation.File.FindingSources.MainCategory | String | Primary threat category. |
| SOCRadarRapidReputation.File.FindingSources.MaintainerName | String | Organization maintaining the threat list. |
| SOCRadarRapidReputation.File.FindingSources.FirstSeenDate | Date | First time the hash was seen on this source. |
| SOCRadarRapidReputation.File.FindingSources.LastSeenDate | Date | Last time the hash was seen on this source. |
| SOCRadarRapidReputation.File.FindingSources.SeenCount | Number | Number of times the hash was observed on this source. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| File.MD5 | String | MD5 hash of the file |
| File.SHA1 | String | SHA1 hash of the file |
| File.SHA256 | String | SHA256 hash of the file |
Command Example
!file file="3b7b359ea17ac76341957573e332a2d6bcac363401ac71c8df94dac93df6d792"
socradar-reputation
Checks reputation of any entity type using SOCRadar Rapid Reputation API. This is a generic command that can handle any supported entity type.
Base Command
socradar-reputation
Input
| Argument Name | Description | Required |
|---|---|---|
| entity_value | Entity value to check (IP, domain, URL, or hash). | Required |
| entity_type | Type of entity to check. Possible values are: ip, hostname, url, hash. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| SOCRadarRapidReputation.Reputation.Entity | String | The queried entity value. |
| SOCRadarRapidReputation.Reputation.EntityType | String | Type of the entity. |
| SOCRadarRapidReputation.Reputation.Score | Number | Reputation score of the entity. |
| SOCRadarRapidReputation.Reputation.IsWhitelisted | Boolean | Whether the entity is whitelisted. |
| SOCRadarRapidReputation.Reputation.FindingSources | Unknown | List of threat sources that detected this entity. |
| SOCRadarRapidReputation.Reputation.FindingSources.SourceName | String | Name of the threat intelligence source. |
| SOCRadarRapidReputation.Reputation.FindingSources.MainCategory | String | Primary threat category. |
| SOCRadarRapidReputation.Reputation.FindingSources.MaintainerName | String | Organization maintaining the threat list. |
| SOCRadarRapidReputation.Reputation.FindingSources.FirstSeenDate | Date | First time the entity was seen on this source. |
| SOCRadarRapidReputation.Reputation.FindingSources.LastSeenDate | Date | Last time the entity was seen on this source. |
| SOCRadarRapidReputation.Reputation.FindingSources.SeenCount | Number | Number of times the entity was observed on this source. |
Command Example
!socradar-reputation entity_value="37.46.210.230" entity_type="ip"
!socradar-reputation entity_value="malicious.example.com" entity_type="hostname"
!socradar-reputation entity_value="3b7b359ea17ac76341957573e332a2d6bcac363401ac71c8df94dac93df6d792" entity_type="hash"
DBot Score Interpretation
The integration converts SOCRadar reputation scores to DBot scores as follows:
| SOCRadar Score | DBot Score | Classification |
|---|---|---|
| > 80 | 3 | Malicious |
| 40 - 80 | 2 | Suspicious |
| 0 - 40 | 1 | Good |
| None/0 | 0 | Unknown |
Whitelisted entities are always assigned a DBot score of 1 (Good), regardless of their reputation score.
Additional Information
Threat Intelligence Sources
The Rapid Reputation API aggregates data from multiple threat intelligence sources, including:
- CTU AIPP Blacklist
- Abuse.ch URLhaus
- Malware feeds
- Botnet C&C lists
- And many more
Each finding source provides detailed information about when and how many times the entity was observed.
Use Cases
- Incident Response: Quickly check if an IP, domain, or URL involved in an incident is known to be malicious
- Threat Hunting: Proactively search for indicators of compromise in your environment
- Automated Playbooks: Integrate reputation checks into your security automation workflows
- Alert Enrichment: Enhance security alerts with threat intelligence context
Best Practices
- Use the generic
socradar-reputationcommand when you need flexibility in entity type - Use specific commands (
ip,domain,url,file) when you know the entity type for better context integration - Monitor the FindingSources field to understand which threat intelligence feeds detected the entity
- Pay attention to the FirstSeenDate and LastSeenDate to understand the timeline of malicious activity
Configuration parameters
apikey— (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsintegrationReliability— Source ReliabilityfeedExpirationPolicy—feedExpirationInterval—
Commands (6)
-
domainChecks reputation of provided domain entities using SOCRadar Rapid Reputation API.
-
fileChecks reputation of provided file hash entities using SOCRadar Rapid Reputation API.
-
ipChecks reputation of provided IP entities using SOCRadar Rapid Reputation API.
-
socradar-bulk-checkBulk check reputation for mixed list of indicators. Automatically detects and processes IPs, domains, URLs, and hashes. Maximum 100 indicators per batch. Rate limit - 1 req/sec (100 indicators = ~100 seconds).
-
socradar-reputationChecks reputation of any entity type using SOCRadar Rapid Reputation API.
-
urlChecks reputation of provided URL entities using SOCRadar Rapid Reputation API.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 from CommonServerUserPython import * # noqa import urllib3 import traceback from typing import Any import re from json.decoder import JSONDecodeError # Disable insecure warnings urllib3.disable_warnings() # pylint: disable=no-member """ CONSTANTS """ SOCRADAR_API_ENDPOINT = "https://platform.socradar.com/api" MESSAGES: dict[str, str] = { "BAD_REQUEST_ERROR": "An error occurred while fetching the data.", "AUTHORIZATION_ERROR": "Authorization Error: make sure API Key is correctly set.", "RATE_LIMIT_EXCEED_ERROR": "Rate limit has been exceeded. Please make sure your API key's rate limit is adequate.", } INTEGRATION_NAME = "SOCRadar Rapid Reputation" MAX_BULK_CHECK_INDICATORS = 100 # Maximum indicators per bulk check to avoid XSOAR limits """ CLIENT CLASS """ class Client(BaseClient): """ Client class to interact with the SOCRadar Rapid Reputation API """ def __init__(self, base_url, api_key, verify, proxy): super().__init__(base_url, verify=verify, proxy=proxy) self.api_key = api_key def get_entity_reputation(self, entity_value: str, entity_type: str): """Get entity reputation from SOCRadar Rapid Reputation API Args: entity_value: The value of the entity (IP, domain, URL, or hash) entity_type: The type of entity (ip, hostname, url, hash) Returns: API response with reputation data """ suffix = "/threatfeed/rapid/reputation" api_params = {"entity_value": entity_value, "entity_type": entity_type} headers = {"Api-Key": self.api_key} response = self._http_request( method="GET", url_suffix=suffix, params=api_params, headers=headers, timeout=60, error_handler=self.handle_error_response, resp_type="json", retries=3, status_list_to_retry=[429], backoff_factor=1, ) return response def check_auth(self): """Check API authentication by making a test request""" try: demisto.debug("Testing API authentication...") response = self.get_entity_reputation("8.8.8.8", "ip") demisto.debug(f"Auth test response: {response}") return response except Exception as e: demisto.error(f"Authentication test failed: {str(e)}") raise DemistoException(f"Authentication failed: {str(e)}") @staticmethod def handle_error_response(response) -> None: """Handles API response to display descriptive error messages based on status code""" error_reason = "" try: json_resp = response.json() error_reason = json_resp.get("exception") or json_resp.get("message") except JSONDecodeError: pass status_code_messages = { 400: f"{MESSAGES['BAD_REQUEST_ERROR']} Reason: {error_reason}", 401: MESSAGES["AUTHORIZATION_ERROR"], 404: f"{MESSAGES['BAD_REQUEST_ERROR']} Reason: {error_reason}", 429: MESSAGES["RATE_LIMIT_EXCEED_ERROR"], } if response.status_code in status_code_messages: demisto.debug(f"Response Code: {response.status_code}, Reason: {status_code_messages[response.status_code]}") raise DemistoException(status_code_messages[response.status_code]) else: try: response.raise_for_status() except Exception as e: raise DemistoException(f"Error in API call [{response.status_code}] - {response.text}\n{e}") """ HELPER FUNCTIONS """ def calculate_dbot_score(score: float) -> int: """Transforms reputation score from SOCRadar API to DBot Score. SOCRadar score ranges: 0 → Unknown (0) 1–49 → Suspicious (2) 50–100 → Malicious (3) Returns: DBot score (0=Unknown, 2=Suspicious, 3=Malicious) """ if score is None or score == 0: return 0 # Unknown elif score > 49: return 3 # Malicious else: return 2 # Suspicious class Validator: @staticmethod def validate_domain(domain_to_validate): if not isinstance(domain_to_validate, str) or len(domain_to_validate) > 255: return False if domain_to_validate.endswith("."): domain_to_validate = domain_to_validate[:-1] domain_regex = re.compile(r"(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE) return all(domain_regex.match(x) for x in domain_to_validate.split(".")) @staticmethod def validate_ipv4(ip_to_validate): return is_ip_valid(ip_to_validate) @staticmethod def validate_ipv6(ip_to_validate): return is_ipv6_valid(ip_to_validate) @staticmethod def validate_hash(hash_to_validate): return get_hash_type(hash_to_validate) != "Unknown" @staticmethod def validate_url(url_to_validate): """Validate URL format""" url_regex = re.compile( r"^https?://" # http:// or https:// r"(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|" # domain r"localhost|" # localhost r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" # or IP r"(?::\d+)?" # optional port r"(?:/?|[/?]\S+)$", re.IGNORECASE, ) return url_regex.match(url_to_validate) is not None @staticmethod def raise_if_ip_not_valid(ip: str): """Raises an error if ip is not valid""" if not Validator.validate_ipv4(ip) and not Validator.validate_ipv6(ip): raise ValueError(f'IP "{ip}" is not a type of IPv4 or IPv6') @staticmethod def raise_if_domain_not_valid(domain: str): """Raises an error if domain is not valid""" if not Validator.validate_domain(domain): raise ValueError(f'Domain "{domain}" is not a valid domain address') @staticmethod def raise_if_hash_not_valid(file_hash: str): """Raises an error if file_hash is not valid""" if not Validator.validate_hash(file_hash): raise ValueError(f'Hash "{file_hash}" is not a valid hash') @staticmethod def raise_if_url_not_valid(url: str): """Raises an error if URL is not valid""" if not Validator.validate_url(url): raise ValueError(f'URL "{url}" is not a valid URL') def build_entry_context(raw_response: dict, entity_value: str, entity_type: str) -> dict: """Build context entry from API response""" data = raw_response.get("data", {}) # Get and round score to 2 decimal places score = data.get("score") if score is not None: score = round(float(score), 2) context_entry = { "Entity": entity_value, "EntityType": entity_type, "Score": score, "IsWhitelisted": data.get("is_whitelisted", False), "FindingSources": [], } # Process finding sources finding_sources = data.get("finding_sources", []) for source in finding_sources: source_entry = { "SourceName": source.get("source_name"), "MainCategory": source.get("main_category"), "MaintainerName": source.get("maintainer_name"), "FirstSeenDate": source.get("first_seen_date"), "LastSeenDate": source.get("last_seen_date"), "SeenCount": source.get("seen_count"), } context_entry["FindingSources"].append(source_entry) return context_entry def detect_entity_type(entity: str) -> str: """Automatically detect the type of an entity""" entity = entity.strip() # Check if it's a URL (starts with http:// or https://) if entity.startswith(("http://", "https://")): return "url" # Check if it's an IP address if Validator.validate_ipv4(entity) or Validator.validate_ipv6(entity): return "ip" # Check if it's a hash if Validator.validate_hash(entity): return "hash" # Check if it's a domain if Validator.validate_domain(entity): return "hostname" # If nothing matches, raise an error raise ValueError(f"Unable to determine entity type for: {entity}") def process_entity_by_type(client: Client, entity: str, entity_type: str) -> dict: """Process a single entity based on its type""" raw_response = client.get_entity_reputation(entity, entity_type) if raw_response.get("is_success"): data = raw_response.get("data", {}) if data.get("is_whitelisted"): score = 1 elif (api_score := data.get("score")) is not None: score = calculate_dbot_score(api_score) else: score = 0 context_entry = build_entry_context(raw_response, entity, entity_type) context_entry["DetectedType"] = entity_type return { "entity": entity, "entity_type": entity_type, "success": True, "context": context_entry, "raw_response": raw_response, "dbot_score": score, } else: return { "entity": entity, "entity_type": entity_type, "success": False, "error": raw_response.get("message", "Unknown error"), "raw_response": raw_response, } """ COMMAND FUNCTIONS """ def test_module(client: Client) -> str: """Tests API connectivity and authentication""" try: demisto.debug("Starting test_module...") response = client.check_auth() demisto.debug(f"Test response received: {response}") if response and response.get("is_success"): demisto.debug("Test successful") return "ok" else: error_msg = response.get("message", "Unknown error") if response else "No response from API" demisto.error(f"Test failed: {error_msg}") raise DemistoException(f"API test failed: {error_msg}") except DemistoException: raise except Exception as e: demisto.error(f"Test module exception: {str(e)}") error_details = f"Connection failed: {str(e)}\n\n" error_details += "Please check:\n" error_details += "1. API Key is correct\n" error_details += "2. Network connectivity to platform.socradar.com\n" error_details += "3. Firewall allows HTTPS outbound connections" raise DemistoException(error_details) def ip_command(client: Client, args: dict[str, Any], reliability: str = None) -> list[CommandResults]: """Returns SOCRadar reputation details for the given IP entity.""" ips = args.get("ip", "") ip_list: list = argToList(ips) command_results_list: list[CommandResults] = [] for ip_to_score in ip_list: try: Validator.raise_if_ip_not_valid(ip_to_score) raw_response = client.get_entity_reputation(ip_to_score, "ip") if raw_response.get("is_success"): data = raw_response.get("data", {}) if data.get("is_whitelisted"): score = 1 elif (api_score := data.get("score")) is not None: score = calculate_dbot_score(api_score) else: score = 0 title = f"SOCRadar Rapid Reputation - Analysis results for IP: {ip_to_score}" context_entry = build_entry_context(raw_response, ip_to_score, "ip") human_readable = tableToMarkdown(title, context_entry) dbot_score = Common.DBotScore( indicator=ip_to_score, indicator_type=DBotScoreType.IP, integration_name=INTEGRATION_NAME, score=score, reliability=reliability, ) ip_object = Common.IP(ip=ip_to_score, dbot_score=dbot_score) command_results_list.append( CommandResults( outputs_prefix="SOCRadarRapidReputation.IP", outputs_key_field="Entity", readable_output=human_readable, raw_response=raw_response, outputs=context_entry, indicator=ip_object, ) ) else: message = f"Error at scoring IP {ip_to_score}: {raw_response.get('message', 'Unknown error')}" command_results_list.append(CommandResults(readable_output=message)) except ValueError as e: command_results_list.append(CommandResults(readable_output=str(e))) except Exception as e: command_results_list.append(CommandResults(readable_output=f"Error processing IP {ip_to_score}: {str(e)}")) if not command_results_list: command_results_list = [ CommandResults(readable_output="SOCRadar Rapid Reputation could not find any results for the given IP(s).") ] return command_results_list def domain_command(client: Client, args: dict[str, Any], reliability: str = None) -> list[CommandResults]: """Returns SOCRadar reputation details for the given domain entity.""" domains = args.get("domain", "") domain_list: list = argToList(domains) command_results_list: list[CommandResults] = [] for domain_to_score in domain_list: try: Validator.raise_if_domain_not_valid(domain_to_score) raw_response = client.get_entity_reputation(domain_to_score, "hostname") if raw_response.get("is_success"): data = raw_response.get("data", {}) if data.get("is_whitelisted"): score = 1 elif (api_score := data.get("score")) is not None: score = calculate_dbot_score(api_score) else: score = 0 title = f"SOCRadar Rapid Reputation - Analysis results for Domain: {domain_to_score}" context_entry = build_entry_context(raw_response, domain_to_score, "hostname") human_readable = tableToMarkdown(title, context_entry) dbot_score = Common.DBotScore( indicator=domain_to_score, indicator_type=DBotScoreType.DOMAIN, integration_name=INTEGRATION_NAME, score=score, reliability=reliability, ) domain_object = Common.Domain(domain=domain_to_score, dbot_score=dbot_score) command_results_list.append( CommandResults( outputs_prefix="SOCRadarRapidReputation.Domain", outputs_key_field="Entity", readable_output=human_readable, raw_response=raw_response, outputs=context_entry, indicator=domain_object, ) ) else: message = f"Error at scoring domain {domain_to_score}: {raw_response.get('message', 'Unknown error')}" command_results_list.append(CommandResults(readable_output=message)) except ValueError as e: command_results_list.append(CommandResults(readable_output=str(e))) except Exception as e: command_results_list.append(CommandResults(readable_output=f"Error processing domain {domain_to_score}: {str(e)}")) if not command_results_list: command_results_list = [ CommandResults(readable_output="SOCRadar Rapid Reputation could not find any results for the given domain(s).") ] return command_results_list def url_command(client: Client, args: dict[str, Any], reliability: str = None) -> list[CommandResults]: """Returns SOCRadar reputation details for the given URL entity.""" urls = args.get("url", "") url_list: list = argToList(urls) command_results_list: list[CommandResults] = [] for url_to_score in url_list: try: Validator.raise_if_url_not_valid(url_to_score) raw_response = client.get_entity_reputation(url_to_score, "url") if raw_response.get("is_success"): data = raw_response.get("data", {}) if data.get("is_whitelisted"): score = 1 elif (api_score := data.get("score")) is not None: score = calculate_dbot_score(api_score) else: score = 0 title = f"SOCRadar Rapid Reputation - Analysis results for URL: {url_to_score}" context_entry = build_entry_context(raw_response, url_to_score, "url") human_readable = tableToMarkdown(title, context_entry) dbot_score = Common.DBotScore( indicator=url_to_score, indicator_type=DBotScoreType.URL, integration_name=INTEGRATION_NAME, score=score, reliability=reliability, ) url_object = Common.URL(url=url_to_score, dbot_score=dbot_score) command_results_list.append( CommandResults( outputs_prefix="SOCRadarRapidReputation.URL", outputs_key_field="Entity", readable_output=human_readable, raw_response=raw_response, outputs=context_entry, indicator=url_object, ) ) else: message = f"Error at scoring URL {url_to_score}: {raw_response.get('message', 'Unknown error')}" command_results_list.append(CommandResults(readable_output=message)) except ValueError as e: command_results_list.append(CommandResults(readable_output=str(e))) except Exception as e: command_results_list.append(CommandResults(readable_output=f"Error processing URL {url_to_score}: {str(e)}")) if not command_results_list: command_results_list = [ CommandResults(readable_output="SOCRadar Rapid Reputation could not find any results for the given URL(s).") ] return command_results_list def file_command(client: Client, args: dict[str, Any], reliability: str = None) -> list[CommandResults]: """Returns SOCRadar reputation details for the given file hash entity.""" file_hashes = args.get("file", "") file_hash_list: list = argToList(file_hashes) command_results_list: list[CommandResults] = [] for hash_to_score in file_hash_list: try: Validator.raise_if_hash_not_valid(hash_to_score) hash_type = get_hash_type(hash_to_score) raw_response = client.get_entity_reputation(hash_to_score, "hash") if raw_response.get("is_success"): data = raw_response.get("data", {}) if data.get("is_whitelisted"): score = 1 elif (api_score := data.get("score")) is not None: score = calculate_dbot_score(api_score) else: score = 0 title = f"SOCRadar Rapid Reputation - Analysis results for Hash: {hash_to_score}" context_entry = build_entry_context(raw_response, hash_to_score, "hash") human_readable = tableToMarkdown(title, context_entry) dbot_score = Common.DBotScore( indicator=hash_to_score, indicator_type=DBotScoreType.FILE, integration_name=INTEGRATION_NAME, score=score, reliability=reliability, ) file_object = Common.File(dbot_score=dbot_score) # Set hash based on type if hash_type == "sha256": file_object.sha256 = hash_to_score elif hash_type == "sha1": file_object.sha1 = hash_to_score elif hash_type == "md5": file_object.md5 = hash_to_score command_results_list.append( CommandResults( outputs_prefix="SOCRadarRapidReputation.File", outputs_key_field="Entity", readable_output=human_readable, raw_response=raw_response, outputs=context_entry, indicator=file_object, ) ) else: message = f"Error at scoring file hash {hash_to_score}: {raw_response.get('message', 'Unknown error')}" command_results_list.append(CommandResults(readable_output=message)) except ValueError as e: command_results_list.append(CommandResults(readable_output=str(e))) except Exception as e: command_results_list.append(CommandResults(readable_output=f"Error processing hash {hash_to_score}: {str(e)}")) if not command_results_list: command_results_list = [ CommandResults(readable_output="SOCRadar Rapid Reputation could not find any results for the given file hash(es).") ] return command_results_list def socradar_bulk_check_command(client: Client, args: dict[str, Any]) -> list[CommandResults]: """Check reputation for a mixed list of indicators with automatic type detection.""" indicators = args.get("indicators", "") indicator_list: list = argToList(indicators) if not indicator_list: return [CommandResults(readable_output="No indicators provided.")] # Check maximum limit to avoid XSOAR argument/output size limits if len(indicator_list) > MAX_BULK_CHECK_INDICATORS: error_msg = ( f"⚠️ **Too Many Indicators!**\n\n" f"**Maximum allowed:** {MAX_BULK_CHECK_INDICATORS} indicators\n" f"**You provided:** {len(indicator_list)} indicators\n\n" f"**Why this limit?**\n" f"- XSOAR has command argument size limits (~10KB)\n" f"- War Room output size limits (~500KB)\n" f"- Context data size limits (~1MB)\n" f"- Rate limit: 1 req/sec = {MAX_BULK_CHECK_INDICATORS} sec (~{MAX_BULK_CHECK_INDICATORS / 60:.1f} min)\n\n" f"**Solution:** Split into batches of {MAX_BULK_CHECK_INDICATORS} or less\n\n" f"**Example:**\n" f"```\n" f'Batch 1: !socradar-bulk-check indicators="[first {MAX_BULK_CHECK_INDICATORS} indicators]"\n' f'Batch 2: !socradar-bulk-check indicators="[next {MAX_BULK_CHECK_INDICATORS} indicators]"\n' f"```\n\n" f"**Recommended:** Use 10-20 indicators per batch for best performance." ) return [CommandResults(readable_output=error_msg)] command_results_list: list[CommandResults] = [] # Warning for large batches (over 50 indicators) if len(indicator_list) > 50: warning_msg = ( f"⚠️ **Large Batch Detected**\n\n" f"Indicators: {len(indicator_list)}\n" f"Estimated time: ~{len(indicator_list)} seconds ({len(indicator_list) / 60:.1f} minutes)\n" f"Rate limit: 1 request/second\n\n" f"💡 **Tip:** For faster results, use smaller batches (10-20 indicators)." ) command_results_list.append(CommandResults(readable_output=warning_msg)) summary_data: dict[str, Any] = { "total": len(indicator_list), "processed": 0, "failed": 0, "failed_details": [], "by_type": {"ip": 0, "hostname": 0, "url": 0, "hash": 0}, "by_score_range": {"0-25": 0, "26-50": 0, "51-75": 0, "76-100": 0, "whitelisted": 0}, } for indicator in indicator_list: try: # Detect entity type entity_type = detect_entity_type(indicator) summary_data["by_type"][entity_type] += 1 # Process the entity result = process_entity_by_type(client, indicator, entity_type) if result["success"]: summary_data["processed"] += 1 context = result["context"] score = context.get("Score", 0) or 0 # Score range classification if context.get("IsWhitelisted"): summary_data["by_score_range"]["whitelisted"] += 1 score_range = "Whitelisted" elif score >= 76: summary_data["by_score_range"]["76-100"] += 1 score_range = "76-100" elif score >= 51: summary_data["by_score_range"]["51-75"] += 1 score_range = "51-75" elif score >= 26: summary_data["by_score_range"]["26-50"] += 1 score_range = "26-50" else: summary_data["by_score_range"]["0-25"] += 1 score_range = "0-25" title = f"SOCRadar - {entity_type.upper()}: {indicator}" summary_dict = { "Entity": indicator, "Type": entity_type, "Score": score, "ScoreRange": score_range, "IsWhitelisted": context.get("IsWhitelisted", False), "Sources": len(context.get("FindingSources", [])), } human_readable = tableToMarkdown(title, summary_dict) command_results_list.append( CommandResults( outputs_prefix="SOCRadarRapidReputation.BulkCheck", outputs_key_field="Entity", readable_output=human_readable, raw_response=result["raw_response"], outputs=context, ) ) else: summary_data["failed"] += 1 error_reason = result.get("error", "Unknown error") summary_data["failed_details"].append({"Entity": indicator, "Reason": error_reason}) error_msg = f"❌ Failed: {indicator} - {error_reason}" command_results_list.append(CommandResults(readable_output=error_msg)) except Exception as e: summary_data["failed"] += 1 error_reason = str(e) summary_data["failed_details"].append({"Entity": indicator, "Reason": error_reason}) error_msg = f"❌ Error: {indicator} - {error_reason}" command_results_list.append(CommandResults(readable_output=error_msg)) # Build summary with score ranges summary_table_data = [ {"Metric": "Total Indicators", "Count": summary_data["total"]}, {"Metric": "Successfully Processed", "Count": summary_data["processed"]}, {"Metric": "Failed", "Count": summary_data["failed"]}, {"Metric": "─" * 20, "Count": "─" * 5}, {"Metric": "Score 76-100", "Count": summary_data["by_score_range"]["76-100"]}, {"Metric": "Score 51-75", "Count": summary_data["by_score_range"]["51-75"]}, {"Metric": "Score 26-50", "Count": summary_data["by_score_range"]["26-50"]}, {"Metric": "Score 0-25", "Count": summary_data["by_score_range"]["0-25"]}, {"Metric": "Whitelisted", "Count": summary_data["by_score_range"]["whitelisted"]}, ] summary_table = tableToMarkdown("📊 Bulk Check Summary", summary_table_data) # Add failed details if any if summary_data["failed_details"]: failed_table = tableToMarkdown("❌ Failed Indicators", summary_data["failed_details"], headers=["Entity", "Reason"]) summary_table += "\n\n" + failed_table command_results_list.insert( 0, CommandResults( outputs_prefix="SOCRadarRapidReputation.BulkCheckSummary", readable_output=summary_table, outputs=summary_data ), ) return command_results_list def socradar_reputation_command(client: Client, args: dict[str, Any], reliability: str = None) -> list[CommandResults]: """Generic reputation check for any entity type.""" entity_value = args.get("entity_value") entity_type = args.get("entity_type") if not entity_value or not entity_type: return [CommandResults(readable_output="Both entity_value and entity_type are required.")] command_results_list: list[CommandResults] = [] try: raw_response = client.get_entity_reputation(entity_value, entity_type) if raw_response.get("is_success"): data = raw_response.get("data", {}) if data.get("is_whitelisted"): score = 1 elif (api_score := data.get("score")) is not None: score = calculate_dbot_score(api_score) else: score = 0 title = f"SOCRadar Rapid Reputation - Analysis for {entity_type.upper()}: {entity_value}" context_entry = build_entry_context(raw_response, entity_value, entity_type) human_readable = tableToMarkdown(title, context_entry) # Determine DBot type based on entity_type if entity_type == "ip": dbot_type = DBotScoreType.IP elif entity_type == "hostname": dbot_type = DBotScoreType.DOMAIN elif entity_type == "url": dbot_type = DBotScoreType.URL elif entity_type == "hash": dbot_type = DBotScoreType.FILE else: dbot_type = DBotScoreType.IP # default dbot_score = Common.DBotScore( indicator=entity_value, indicator_type=dbot_type, integration_name=INTEGRATION_NAME, score=score, reliability=reliability, ) # Initialize indicator_object with Union type indicator_object: Common.IP | Common.Domain | Common.URL | Common.File | None = None # Create appropriate indicator object based on entity type if entity_type == "ip": indicator_object = Common.IP(ip=entity_value, dbot_score=dbot_score) elif entity_type == "hostname": indicator_object = Common.Domain(domain=entity_value, dbot_score=dbot_score) elif entity_type == "url": indicator_object = Common.URL(url=entity_value, dbot_score=dbot_score) elif entity_type == "hash": indicator_object = Common.File(dbot_score=dbot_score) hash_type = get_hash_type(entity_value) if hash_type == "sha256": indicator_object.sha256 = entity_value elif hash_type == "sha1": indicator_object.sha1 = entity_value elif hash_type == "md5": indicator_object.md5 = entity_value else: indicator_object = None command_results_list.append( CommandResults( outputs_prefix="SOCRadarRapidReputation.Reputation", outputs_key_field="Entity", readable_output=human_readable, raw_response=raw_response, outputs=context_entry, indicator=indicator_object, ) ) else: message = f"Error checking {entity_type} {entity_value}: {raw_response.get('message', 'Unknown error')}" command_results_list.append(CommandResults(readable_output=message)) except Exception as e: command_results_list.append(CommandResults(readable_output=f"Error: {str(e)}")) return command_results_list """ MAIN FUNCTION """ def main() -> None: """main function, parses params and runs command functions""" params = demisto.params() api_key = params.get("apikey", {}).get("password") base_url = SOCRADAR_API_ENDPOINT verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) reliability = params.get("integrationReliability") demisto.debug(f"Command being called is {demisto.command()}") try: client = Client(base_url=base_url, api_key=api_key, verify=verify_certificate, proxy=proxy) command = demisto.command() if command == "test-module": demisto.debug("Executing test-module command") result = test_module(client) demisto.debug(f"Test module result: {result}") return_results(result) elif command == "ip": demisto.debug("Executing ip command") return_results(ip_command(client, demisto.args(), reliability)) elif command == "domain": demisto.debug("Executing domain command") return_results(domain_command(client, demisto.args(), reliability)) elif command == "url": demisto.debug("Executing url command") return_results(url_command(client, demisto.args(), reliability)) elif command == "file": demisto.debug("Executing file command") return_results(file_command(client, demisto.args(), reliability)) elif command == "socradar-reputation": demisto.debug("Executing socradar-reputation command") return_results(socradar_reputation_command(client, demisto.args(), reliability)) elif command == "socradar-bulk-check": demisto.debug("Executing socradar-bulk-check command") return_results(socradar_bulk_check_command(client, demisto.args())) else: demisto.debug(f"Unknown command: {command}") return_error(f"Command {command} is not supported") except Exception as e: demisto.error(traceback.format_exc()) return_error(f"Failed to execute {demisto.command()} command.\nError:\n{str(e)}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()