IntSights Deprecated
Deprecated. Use Rapid7 Threat Command instead.
Data Enrichment & Threat Intelligence · Rapid7 - Threat Command (IntSights)
Details
| ID | IntSights |
|---|---|
| Provider | Rapid7 |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.10.10.51930 |
| Supported Modules | Agentix XSIAM |
README
Use IntSights to manage and mitigate threats.
This integration was tested with Intsights API version 3.
Configure IntSights in Cortex
| Parameter | Required |
|---|---|
| Server URL (e.g. https://192.168.0.1) | True |
| Credentials | True |
| Password | True |
| Alert type to fetch as incidents, allowed: “AttackIndication”, “DataLeakage”, “Phishing”, “BrandSecurity”, “ExploitableData”, “VIP” | False |
| Minimum Alert severity level to fetch incidents incidents from, allowed values are: ‘All’, ‘Low’, ‘Medium’,’High’(Setting to All will fetch all incidents) | False |
| Trust any certificate (not secure) | False |
| Use system proxy settings | False |
| Fetch incidents | False |
| First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days) | False |
| Max fetch | False |
| Incident type | False |
| Sub Account ID (MSSP accounts only) | 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.
intsights-get-alert-image
Returns an image of an alert by ID.
Base Command
intsights-get-alert-image
Input
| Argument Name | Description | Required |
|---|---|---|
| image-id | The ID of the image to return. | Required |
Context Output
There is no context output for this command.
intsights-get-alert-activities
Returns alert activities.
Base Command
intsights-get-alert-activities
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The ID of the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Activities.Type | string | The type of the activity. |
| IntSights.Alerts.Activities.Initiator | string | The initiator of the alert. |
| IntSights.Alerts.Activities.CreatedDate | date | The date the alert was created. |
| IntSights.Alerts.Activities.UpdateDate | date | The date the alert was updated. |
| IntSights.Alerts.Activities.RemediationBlocklistUpdate | string | The remediation blocked list update. |
| IntSights.Alerts.Activities.AskTheAnalyst.Replies | string | The replies to questions of the analyst. |
| IntSights.Alerts.Activities.Mail.Replies | string | The replies to an email. |
| IntSights.Alerts.Activities.ReadBy | string | The alert that was read by. |
intsights-assign-alert
Assigns an alert.
Base Command
intsights-assign-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the Alert. | Required |
| assignee-email | The user email of the assignee. | Required |
| is-mssp-optional | Whether the assigned user is an MSSP user. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Assignees.AssigneeID | string | The ID of the assignee. |
intsights-unassign-alert
Unassigns an alert from a user.
Base Command
intsights-unassign-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
intsights-send-mail
Sends an email containing a question and details of the alert.
Base Command
intsights-send-mail
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the alert. | Required |
| emails | The destination email addresses array (comma-separated). | Required |
| content | The content added to the alert details. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the Alert. |
| IntSights.Alerts.Mail.EmailID | string | The ID of the email. |
| IntSights.Alerts.Question | string | Details of the question. |
intsights-ask-the-analyst
Sends a question to the IntSights analyst about the requested alert.
Base Command
intsights-ask-the-analyst
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the alert. | Required |
| question | Question to ask the Intsights analyst about the requested alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the Alert. |
| IntSights.Alerts.Question | string | Details of the question. |
intsights-add-tag-to-alert
Adds a tag to the alert.
Base Command
intsights-add-tag-to-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The ID of the unique alert. | Required |
| tag-name | The new tag string. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Tags.TagName | string | The name of the tag. |
| IntSights.Alerts.Tags.ID | string | The ID of the Tag. |
intsights-remove-tag-from-alert
Removes a tag from the specified alert.
Base Command
intsights-remove-tag-from-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the alert. | Required |
| tag-id | The unique ID of the tag to remove. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Tags.ID | string | The ID of the tag. |
intsights-add-comment-to-alert
Adds a comment to a specified alert.
Base Command
intsights-add-comment-to-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the alert. | Required |
| comment | The comment to add to the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Comment | string | The comment in the alert. |
intsights-update-alert-severity
Changes the severity of a specified alert.
Base Command
intsights-update-alert-severity
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the alert. | Required |
| severity | The severity of the alert. Can be: “High”, “Medium”, or “Low”. Possible values are: High, Medium, Low. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Severity | string | The severity of the alert. |
intsights-get-alert-by-id
Returns the alert object by alert ID.
Base Command
intsights-get-alert-by-id
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The unique ID of the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Severity | string | The severity of the alert. |
| IntSights.Alerts.Type | string | The type of the alert. |
| IntSights.Alerts.FoundDate | date | The date that the alert was found. |
| IntSights.Alerts.SourceType | string | The source type of the alert. |
| IntSights.Alerts.SourceURL | string | The source URL of the alert. |
| IntSights.Alerts.SourceEmail | string | The source email of the alert. |
| IntSights.Alerts.SourceNetworkType | string | The network type of the alert. |
| IntSights.Alerts.IsClosed | boolean | Whether or not the alert is closed. |
| IntSights.Alerts.IsFlagged | boolean | Whether or not the alert is flagged. |
| IntSights.Alerts.Tags.CreatedBy | string | Name of the service for which the tag was created. |
| IntSights.Alerts.Tag.Name | string | Name of the tag. |
| IntSights.Alerts.Tag.ID | string | The ID of the tag. |
| IntSights.Alerts.Images | string | The ID of the images. |
| IntSights.Alerts.Description | string | The description of the alert. |
| IntSights.Alerts.Title | string | The title of the alert. |
| IntSights.Alerts.TakedownStatus | string | The TakedownStatus of the alert. |
| IntSights.Alerts.SubType | string | The sub type of the alert. |
intsights-get-ioc-by-value
Searches for an exact IOC value.
Base Command
intsights-get-ioc-by-value
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The IOC value for which to search. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Iocs.Value | string | The value of the IOC. |
| IntSights.Iocs.Type | string | The type of the IOC. |
| IntSights.Iocs.FirstSeen | date | The date the IOC was first seen. |
| IntSights.Iocs.LastSeen | date | The date the IOC was last seen. |
| IntSights.Iocs.LastUpdatedDate | date | The date the IOC was last updated. |
| IntSights.Iocs.SourceID | string | The source ID of the IOC. |
| IntSights.Iocs.SourceName | string | The source name of the IOC. |
| IntSights.Iocs.SourceConfidenceLevel | string | The confidence level of the IOC source. |
| IntSights.Iocs.Severity | string | The severity of the IOC. |
| IntSights.Iocs.Status | string | The status of the IOC. |
| IntSights.Iocs.Sources.name | string | The source name of the IOC. |
| IntSights.Iocs.Sources.confidenceLevel | string | The confidence level of the IOC source. |
| IntSights.Iocs.Sources.id | string | The source id of the IOC. |
| IntSights.Iocs.tags | Array | The tags of the IOC. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The type of the indicator. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| File.Name | String | The full file name (including file extension). |
| File.Malicious.Vendor | String | The vendor that reported the file as malicious. |
| File.Malicious.Description | String | A description explaining why the file was determined to be malicious. |
| File.MD5 | String | The MD5 hash of the file. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| URL.Data | String | The URL. |
| URL.Malicious.Vendor | String | The vendor reporting the URL as malicious. |
| URL.Malicious.Description | String | A description of the malicious URL. |
| 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.Address | String | IP address. |
| Domain.Name | String | The domain name. For example, “google.com”. |
| Domain.Malicious.Vendor | String | The vendor reporting the domain as malicious. |
| Domain.Malicious.Description | String | A description explaining why the domain was reported as malicious. |
intsights-get-iocs
Returns count totals of the available IOCs.
Base Command
intsights-get-iocs
Input
| Argument Name | Description | Required |
|---|---|---|
| type | The type of the IOC. Can be: “Urls”, “Hashes”, “IpAddresses”, or “domains”. Possible values are: Urls, Hashes, IpAddresses, Domains. | Optional |
| limit | The maximum number of results from 1-1000. Default is 1000. | Optional |
| severity | The severity level of the IOC. Can be: “High”, “Medium”, or “Low”. Possible values are: High, Medium, Low. | Optional |
| source-ID | The source of the IOC. | Optional |
| first-seen-from | Beginning of the date range when the IOC was first seen (MM/DD/YYYY). Default is 0. | Optional |
| first-seen-to | End of the date range when the IOC was first seen (MM/DD/YYYY). Default is 0. | Optional |
| last-seen-from | Beginning of the date range when the IOC was last seen (MM/DD/YYYY). Default is 0. | Optional |
| last-updated-from | Beginning of the date range when the IOC was last updated (YYYY-MM-DD). | Optional |
| last-seen-to | End of the date range when the IOC was last seen (MM/DD/YYYY). Default is 0. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Iocs.Value | string | The value of the IOC. |
| IntSights.Iocs.Type | string | The type of the IOC. |
| IntSights.Iocs.FirstSeen | date | The date the IOC was first seen. |
| IntSights.Iocs.LastSeen | date | The date the IOC was last seen. |
| IntSights.Iocs.LastUpdatedDate | date | The date the IOC was last updated. |
| IntSights.Iocs.SourceID | string | The source ID of the IOC. |
| IntSights.Iocs.SourceName | string | The source name of the IOC. |
| IntSights.Iocs.SourceConfidenceLevel | string | The confidence level of the IOC source. |
| IntSights.Iocs.Severity | string | The severity of the IOC. |
| IntSights.Iocs.Status | string | The status of the IOC. |
| IntSights.Iocs.Sources.name | string | The source name of the IOC. |
| IntSights.Iocs.Sources.confidenceLevel | string | The confidence level of the IOC source. |
| IntSights.Iocs.Sources.id | string | The source id of the IOC. |
| IntSights.Iocs.tags | Array | The tags of the IOC. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The type of the indicator. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| File.Name | String | The full file name (including file extension). |
| File.Malicious.Vendor | String | The vendor that reported the file as malicious. |
| File.Malicious.Description | String | A description explaining why the file was determined to be malicious. |
| File.MD5 | String | The MD5 hash of the file. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| URL.Data | String | The URL. |
| URL.Malicious.Vendor | String | The vendor reporting the URL as malicious. |
| URL.Malicious.Description | String | A description of the malicious URL. |
| 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.Address | String | IP address. |
| Domain.Name | String | The domain name. For example, “google.com”. |
| Domain.Malicious.Vendor | String | The vendor reporting the domain as malicious. |
| Domain.Malicious.Description | String | A description explaining why the domain was reported as malicious. |
intsights-get-alerts
Returns alerts.
Base Command
intsights-get-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-type | The type of the alert. Can be: “AttackIndication”, “DataLeakage”, “Phishing”, “BrandSecurity”, “ExploitableData”, “VIP”. Possible values are: AttackIndication, DataLeakage, Phishing, BrandSecurity, ExploitableData, VIP. | Optional |
| severity | The severity of the alert. Can be: “High”, “Medium”, or “Low”. Possible values are: High, Medium, Low. | Optional |
| source-type | The source type of the alert. Can be: “ApplicationStores”, “BlackMarkets”, “HackingForums”, “SocialMedia”, “PasteSites”, or “Others”. Possible values are: ApplicationStores, BlackMarkets, HackingForums, SocialMedia, PasteSites, Others. | Optional |
| network-type | The network type of the alert. Can be: “ClearWeb”, or “DarkWeb”. Possible values are: ClearWeb, DarkWeb. | Optional |
| source-date-from | The start date for which to fetch in Millisecond Timestamp in UNIX. | Optional |
| source-date-to | The end date for which to fetch in Millisecond Timestamp in UNIX. | Optional |
| found-date-from | The start date for which fetch in Millisecond Timestamp in UNIX. | Optional |
| found-date-to | The end date for which fetch in Millisecond Timestamp in UNIX. | Optional |
| assigned | Whether to show assigned or unassigned alerts. | Optional |
| is-flagged | Whether to show flagged or unflagged alerts. | Optional |
| is-closed | Whether to show closed/open alerts. | Optional |
| time-delta | Shows alerts within a specified time delta, given in days. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Severity | string | The severity of the alert. |
| IntSights.Alerts.Type | string | The type of the alert. |
| IntSights.Alerts.FoundDate | date | The date that the alert was found. |
| IntSights.Alerts.SourceType | string | The source type of the alert. |
| IntSights.Alerts.SourceURL | string | The source URL of the alert. |
| IntSights.Alerts.SourceEmail | string | The source email of the alert. |
| IntSights.Alerts.SourceNetworkType | string | The network type of the alert. |
| IntSights.Alerts.IsClosed | boolean | Whether or not the alert is closed. |
| IntSights.Alerts.IsFlagged | boolean | Whether or not the alert is flagged. |
| IntSights.Alerts.Tags.CreatedBy | string | Name of the service that the tag was created. |
| IntSights.Alerts.Tag.Name | string | Name of the tag. |
| IntSights.Alerts.Tag.ID | string | The ID of the tag. |
| IntSights.Alerts.Images | string | The ID of each image. |
| IntSights.Alerts.Description | string | The description of the alert. |
| IntSights.Alerts.Title | string | The title of the alert. |
| IntSights.Alerts.TakedownStatus | string | The TakedownStatus of the alert. |
| IntSights.Alerts.SubType | string | The sub type of the alert. |
intsights-alert-takedown-request
Requests an alert takedown.
Base Command
intsights-alert-takedown-request
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The ID of the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
intsights-get-alert-takedown-status
Returns the alert takedown status.
Base Command
intsights-get-alert-takedown-status
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The ID of the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.TakedownStatus | string | The status of the takedown. |
intsights-update-ioc-blocklist-status
Updates the IOC block list status.
Base Command
intsights-update-ioc-blocklist-status
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The ID of the alert. | Required |
| type | A comma separated list of each type of IOC. Options: Domains, IPs, URLs. | Required |
| value | A comma separated list of the value of the IOCs. | Required |
| blocklist-status | A comma separated list of the IOCs block list status. Options: Sent, NotSent. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Status | string | The status of the block list. |
intsights-get-ioc-blocklist-status
Returns the status of the IOC block list.
Base Command
intsights-get-ioc-blocklist-status
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The ID of the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Status | string | The status of the block list. |
intsights-close-alert
Closes an alert
Base Command
intsights-close-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert-id | The ID of the alert. | Required |
| reason | The reason to close the alert. Can be: “ProblemSolved”, “InformationalOnly”, “ProblemWeAreAlreadyAwareOf”, “CompanyOwnedDomain”, “LegitimateApplication/Profile”, “NotRelatedToMyCompany”, “FalsePositive”, or “Other”. Possible values are: ProblemSolved, InformationalOnly, ProblemWeAreAlreadyAwareOf, CompanyOwnedDomain, LegitimateApplication/Profile, NotRelatedToMyCompany, FalsePositive, Other. | Required |
| free-text | The comments in the alert. | Optional |
| is-hidden | The hidden status of the alert. Deletes an alert from the account instance - only when reason is a FalsePositive). Possible values are: True, False. Default is False. | Optional |
| rate | The rate of the alert. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.Alerts.ID | string | The ID of the alert. |
| IntSights.Alerts.Closed.Reason | string | The closed reason of the alert. |
intsights-mssp-get-sub-accounts
Returns all Managed Security Service Provider’s (MSSP) sub accounts.
Base Command
intsights-mssp-get-sub-accounts
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| IntSights.MsspAccount.ID | String | The ID of IntSights MSSP sub account. |
| IntSights.MsspAccount.Status | String | The enabled status of IntSights MSSP sub account |
| IntSights.MsspAccount.AssetsCount | Number | The assets count of IntSights MSSP sub account. |
| IntSights.MsspAccount.AssetLimit | Number | The asset limit of IntSights MSSP sub account. |
| IntSights.MsspAccount.CompanyName | String | The company name of IntSights MSSP sub account. |
intsights-request-ioc-enrichment
Request and receive enrichment of an IOC.
Base Command
intsights-request-ioc-enrichment
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The IOC value for which to enrich. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Domain.Name | String | domain name |
| Domain.DNS | String | domain dns |
| Domain.Resolutions | String | domain resolutions |
| Domain.Subdomains | String | domain subdomains |
| Domain.WHOIS/History | String | domain whois |
| Domain.Malicious | String | domain malicious |
| IP.Address | String | ip address |
| IP.IpDetails | String | ip details |
| IP.RelatedHashes | String | ip related hashes |
| IP.WHOIS | String | ip whois |
| IP.Malicious | String | ip malicious |
| URL.Data | String | URL Data |
| URL.AntivirusDetectedEngines | String | URL Antivirus Detected Engines |
| URL.AntivirusDetectionRatio | String | URL Antivirus Detection Ratio |
| URL.AntivirusDetections | String | URL Antivirus Detections |
| URL.AntivirusScanDate | String | URL Antivirus Scan Date |
| URL.RelatedHashes | String | URL Related Hashes |
| URL.Malicious | String | URL Malicious |
| File.Name | String | File Name |
| File.AntivirusDetectedEngines | String | File Antivirus Detected Engines |
| File.AntivirusDetectionRatio | String | File Antivirus Detection Ratio |
| File.AntivirusDetections | String | File Antivirus Detections |
| File.AntivirusScanDate | String | File Antivirus Scan Date |
| File.Malicious | String | File Malicious |
| IntSights.Iocs.Type | String | IntSights Iocs Type |
| IntSights.Iocs.Value | String | IntSights Iocs Value |
| IntSights.Iocs.FirstSeen | String | IntSights Iocs First Seen |
| IntSights.Iocs.LastSeen | String | IntSights Iocs Last Seen |
| IntSights.Iocs.Status | String | IntSights Iocs Status |
| IntSights.Iocs.Severity | String | IntSights Iocs Severity |
| IntSights.Iocs.RelatedMalwares | String | IntSights Iocs Related Malwares |
| IntSights.Iocs.Sources | String | IntSights Iocs Sources |
| IntSights.Iocs.IsKnownIoc | String | IntSights Iocs Is Known Ioc |
| IntSightsIocs.RelatedThreatActors | String | IntSights Iocs Related Threat Actors |
| IntSights.Iocs.SystemTags | String | IntSights Iocs SystemTags |
| IntSights.Iocs.Tags | String | IntSights Iocs Tags |
| IntSights.Iocs.Whitelisted | String | IntSights Iocs Whitelisted |
| IntSights.Iocs.OriginalValue | String | IntSights Iocs Original Value |
| Domain.WHOIS | String | Domain WHOIS |
Configuration parameters
server— Server URL (e.g. https://192.168.0.1) (required)credentials— Credentials (required)type— Alert type to fetch as incidents, allowed: "AttackIndication", "DataLeakage", "Phishing", "BrandSecurity", "ExploitableData", "VIP"severity_level— Minimum Alert severity level to fetch incidents incidents from, allowed values are: 'All', 'Low', 'Medium','High'(Setting to All will fetch all incidents)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsisFetch— Fetch incidentsfirst_fetch— First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)max_fetch— Max fetchincidentType— Incident typemssp_sub_account_id— Sub Account ID (MSSP accounts only)
Commands (21)
-
intsights-add-comment-to-alertAdds a comment to a specified alert.
-
intsights-add-tag-to-alertAdds a tag to the alert.
-
intsights-alert-takedown-requestRequests an alert takedown.
-
intsights-ask-the-analystSends a question to the IntSights analyst about the requested alert.
-
intsights-assign-alertAssigns an alert.
-
intsights-close-alertCloses an alert
-
intsights-get-alert-activitiesReturns alert activities.
-
intsights-get-alert-by-idReturns the alert object by alert ID.
-
intsights-get-alert-imageReturns an image of an alert by ID.
-
intsights-get-alert-takedown-statusReturns the alert takedown status.
-
intsights-get-alertsReturns alerts.
-
intsights-get-ioc-blocklist-statusReturns the status of the IOC block list.
-
intsights-get-ioc-by-valueSearches for an exact IOC value.
-
intsights-get-iocsReturns count totals of the available IOCs.
-
intsights-mssp-get-sub-accountsReturns all Managed Security Service Provider's (MSSP) sub accounts.
-
intsights-remove-tag-from-alertRemoves a tag from the specified alert.
-
intsights-request-ioc-enrichmentRequest and receive enrichment of an IOC.
-
intsights-send-mailSends an email containing a question and details of the alert.
-
intsights-unassign-alertUnassigns an alert from a user.
-
intsights-update-alert-severityChanges the severity of a specified alert.
-
intsights-update-ioc-blocklist-statusUpdates the IOC block list status.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import os URL = demisto.getParam('server') if URL[-1] != '/': URL += '/' if not demisto.getParam('proxy'): del os.environ['HTTP_PROXY'] del os.environ['HTTPS_PROXY'] del os.environ['http_proxy'] del os.environ['https_proxy'] VALIDATE_CERT = not demisto.params().get('insecure', True) USER_ID = demisto.getParam('credentials')['identifier'] PASSWORD = demisto.getParam('credentials')['password'] MSSP_ACCOUNT_ID = demisto.getParam('mssp_sub_account_id') if USER_ID == '_api_token_key': authorization_header = PASSWORD else: id_and_api_key = USER_ID + ':' + PASSWORD authorization_header = base64.b64encode(id_and_api_key.encode("utf-8")).decode() HEADERS = {'Authorization': 'Basic {}'.format(authorization_header), 'Content-Type': 'application/json', 'Account-Id': demisto.getParam('credentials')['identifier']} # Change the Account-Id to the sub account id, so all actions will be on the sub account. if MSSP_ACCOUNT_ID: HEADERS['Account-Id'] = MSSP_ACCOUNT_ID IOC_TYPE_TO_DBOT_TYPE = { 'IpAddresses': 'ip', 'Urls': 'url', 'Domains': 'domain', 'Hashes': 'hash' } DEFAULT_TIME_RANGE = '1 day' SEVERITY_LEVEL = { 'All': 0, 'Low': 1, 'Medium': 2, 'High': 3 } def http_request(method, path, json_data=None, params=None, json_response=False): """ Send the request to IntSights and return the JSON response """ try: response = requests.request(method, URL + path, headers=HEADERS, json=json_data, params=params, verify=VALIDATE_CERT) except requests.exceptions.SSLError: raise Exception('Connection error in the API call to IntSights.\nCheck your not secure parameter.') except requests.ConnectionError: raise Exception('Connection error in the API call to IntSights.\nCheck your Server URL parameter.') if response.status_code < 200 or response.status_code > 299: if not (response.text == 'SeverityNotChanged' or response.text == 'TagExist' or response.text == 'IocBlocklistStatusNotChanged'): return_error('Error in API call to IntSights service %s - [%d] %s' % (path, response.status_code, response.text)) if response.status_code == 204: return [] # type: ignore if json_response: try: return response.json() except ValueError: raise Exception('Error in API call to IntSights service - check your configured URL address') return response def convert_iso_string_to_python_date(date_in_iso_format): iso_format = "%Y-%m-%dT%H:%M:%S" date_in_python_format = datetime.strptime(date_in_iso_format, iso_format) return date_in_python_format def convert_python_date_to_unix_millisecond(python_date_object): timestamp_in_unix_millisecond = date_to_timestamp(python_date_object, 'datetime.datetime') return timestamp_in_unix_millisecond def increase_iso_by_x_days(date_in_iso_format, num_of_days): date_in_python_format = convert_iso_string_to_python_date(date_in_iso_format) new_date_in_python_format = date_in_python_format + timedelta(days=int(num_of_days)) new_date_in_iso_format = new_date_in_python_format.isoformat() return new_date_in_iso_format def remove_milliseconds_from_iso(date_in_iso_format): date_parts_arr = date_in_iso_format.split('.') date_in_iso_without_milliseconds = date_parts_arr[0] return date_in_iso_without_milliseconds def increase_timestamp_by_x_days(date_in_unix_ms_timestamp, num_of_days): date_in_iso = timestamp_to_datestring(date_in_unix_ms_timestamp) date_in_iso_without_ms = remove_milliseconds_from_iso(date_in_iso) date_in_iso_plus_x_days = increase_iso_by_x_days(date_in_iso_without_ms, num_of_days) timestamp_in_unix_ms_plus_x_days = date_to_timestamp(date_in_iso_plus_x_days) return timestamp_in_unix_ms_plus_x_days def update_params_with_end_and_start_date(params, oldest_day_to_search_in_unix_timestamp, now_date_in_unix_timestamp): params['foundDateFrom'] = oldest_day_to_search_in_unix_timestamp params['foundDateTo'] = now_date_in_unix_timestamp params['sourceDateFrom'] = oldest_day_to_search_in_unix_timestamp params['sourceDateTo'] = now_date_in_unix_timestamp def update_params_with_delta_arg(params, time_delta_in_days_int): now_date_in_iso = datetime.utcnow().isoformat() now_date_in_iso_without_ms = remove_milliseconds_from_iso(now_date_in_iso) now_date_in_unix_timestamp = date_to_timestamp(now_date_in_iso_without_ms) oldest_day_to_search_in_unix_timestamp = increase_timestamp_by_x_days(now_date_in_unix_timestamp, -1 * time_delta_in_days_int) update_params_with_end_and_start_date(params, oldest_day_to_search_in_unix_timestamp, now_date_in_unix_timestamp) del params['time-delta'] def update_params_dict_according_to_delta_arg(params, time_delta_in_days_int): if 'foundDateFrom' in params or 'foundDateTo' in params: demisto.debug( "ERROR in get_alerts() - can't use found-date-to or found-date-from arguments with time-delta argument") return_error("Error: can't assign delta when assigned both found-date-to or found-date-from") else: update_params_with_delta_arg(params, time_delta_in_days_int) return params def handle_filters(found_date_from=None): """ Apply filters to alert list """ args_camel_case = { 'alert-type': 'alertType', 'source-type': 'sourceType', 'network-type': 'networkType', 'source-date-from': 'sourceDateFrom', 'source-date-to': 'sourceDateTo', 'found-date-from': 'foundDateFrom', 'found-date-to': 'foundDateTo', 'is-flagged': 'isFlagged', 'is-closed': 'isClosed', 'source-ID': 'sourceId', 'first-seen-from': 'firstSeenFrom', 'first-seen-to': 'firstSeenTo', 'last-seen-from': 'lastSeenFrom', 'last-updated-from': 'lastUpdatedFrom', 'last-seen-to': 'lastSeenTo', 'value': 'iocValue', } params = {} for key in demisto.args(): if demisto.getArg(key): params[args_camel_case.get(key) or key] = demisto.getArg(key) if demisto.getArg('time-delta'): time_delta_in_days = demisto.getArg('time-delta') update_params_dict_according_to_delta_arg(params, int(time_delta_in_days)) elif found_date_from: params['foundDateFrom'] = found_date_from return params def get_alerts_helper(params): demisto.info("Executing get_alerts with params: {}".format(params)) response = http_request('GET', 'public/v1/data/alerts/alerts-list', params=params, json_response=True) alerts_human_readable = [] alerts_context = [] for alert_id in response: alert_human_readable, alert_context = get_alert_by_id_helper(alert_id) alerts_human_readable.append(alert_human_readable) alerts_context.append(alert_context) demisto.debug(f'{len(alerts_context)=} before filtering') return alerts_human_readable, alerts_context def extract_mail(replies): if not replies: return '' mails = [] for reply in replies: mails.append(reply.get('Email')) return '\n'.join(mails) def extract_remediation(remidiations): if not remidiations: return '' remedies = [] string_format = "{0} - Status: {1}" for remedy in remidiations: remedies.append(string_format.format(remedy.get('Value'), remedy.get('Status'))) return '\n'.join(remedies) def hash_identifier(hash_val): if md5Regex.match(hash_val): return 'MD5' if sha1Regex.match(hash_val): return 'SHA1' if sha256Regex.match(hash_val): return 'SHA256' return 'Unknown' def extract_tags(tags): pretty_tags = [] string_format = "ID: {0} - Name: {1}" for tag in tags: pretty_tags.append(string_format.format(tag.get('_id'), tag.get('Name'))) return pretty_tags def get_alerts(): """ Gets all alerts and returns as a list. """ alerts_human_readable, alerts_context = get_alerts_helper(handle_filters()) headers = ['ID', 'Severity', 'Type', 'FoundDate', 'SourceType', 'SourceURL', 'SourceEmail', 'SourceNetworkType', 'IsClosed', 'Closed', 'IsFlagged', 'Images', 'Tags', 'Description', 'Title', 'TakedownStatus', 'SubType'] demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': alerts_context}, 'Contents': alerts_context, 'HumanReadable': tableToMarkdown('IntSights Alerts', alerts_human_readable, headers=headers, removeNull=False), 'ContentsFormat': formats['json'] }) def alert_to_readable(alert, parse_tags): """ Convert alert to readable format """ is_closed = demisto.get(alert, 'IsClosed') if is_closed is None: is_closed = demisto.get(alert, 'Closed.IsClosed') readable = { 'ID': demisto.get(alert, '_id'), 'Severity': demisto.get(alert, 'Details.Severity'), 'Type': demisto.get(alert, 'Details.Type'), 'FoundDate': demisto.get(alert, 'FoundDate'), 'SourceType': demisto.get(alert, 'Details.Source.Type'), 'SourceURL': demisto.get(alert, 'Details.Source.URL'), 'SourceEmail': demisto.get(alert, 'Details.Source.Email'), 'SourceNetworkType': demisto.get(alert, 'Details.Source.NetworkType'), 'IsClosed': is_closed, 'IsFlagged': demisto.get(alert, 'IsFlagged'), 'Assets': demisto.get(alert, 'Assets'), 'Images': demisto.get(alert, 'Details.Images'), 'Description': demisto.get(alert, 'Details.Description'), 'Title': demisto.get(alert, 'Details.Title'), 'TakedownStatus': demisto.get(alert, 'TakedownStatus'), 'SubType': demisto.get(alert, 'Details.SubType'), } tags = demisto.get(alert, 'Details.Tags') if parse_tags: readable['Tags'] = extract_tags(tags) else: readable['Tag'] = [] for tag in tags: readable['Tag'].append({'ID': tag.get('_id'), 'Name': tag.get('Name')}) return readable def get_alert_by_id_helper(alert_id): """ Helper for getting details by ID """ response = http_request('GET', 'public/v1/data/alerts/get-complete-alert/' + alert_id, json_response=True) return alert_to_readable(response, True), alert_to_readable(response, False) def get_alert_by_id(): """ Get alert details by id """ alert_id = demisto.getArg('alert-id') activity_hr, activity_ctx = get_alert_by_id_helper(alert_id) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': activity_ctx}, 'Contents': activity_hr, 'HumanReadable': tableToMarkdown('IntSights Alert Details', [activity_hr], ['ID', 'Severity', 'Type', 'FoundDate', 'SourceType', 'SourceURL', 'SourceEmail', 'SourceNetworkType', 'IsClosed', 'IsFlagged', 'Images', 'Tags', 'Description', 'Title', 'TakedownStatus', 'SubType']), 'ContentsFormat': formats['json'] }) def get_alert_image(): """ Retrieves the alert image by image_id """ image_id = demisto.getArg('image-id') response = http_request('GET', 'public/v1/data/alerts/alert-image/' + image_id) demisto.results(fileResult(image_id + '-image.jpeg', response.content)) def ask_analyst(): """ Send question to an analyst about the requested alert """ alert_id = demisto.getArg('alert-id') question = demisto.getArg('question') http_request('POST', 'public/v1/data/alerts/ask-the-analyst/' + alert_id, json_data={'Question': question}) question_details = {'ID': alert_id, 'Question': question} title = 'IntSights Ask the Analyst: ' \ 'Your question has been successfully sent to an analyst about the requested alert' demisto.results( { 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': question_details}, 'Contents': question_details, 'HumanReadable': tableToMarkdown(title, [question_details], ['ID', 'Question']), 'ContentsFormat': formats['json'] } ) def get_alert_activity(): """ Retrieves the alert activity by alert-id """ alert_id = demisto.getArg('alert-id') response = http_request('GET', 'public/v1/data/alerts/activity-log/' + alert_id, json_response=True) alert = {'ID': alert_id, 'Activities': []} if not response: demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': alert}, 'Contents': response, 'HumanReadable': 'Alert {} does not have activities.'.format(alert_id), 'ContentsFormat': formats['json'] }) else: human_readable_arr = [] for activity in response: alert['Activities'].append({ 'ID': demisto.get(activity, '_id'), 'Type': demisto.get(activity, 'Type'), 'Initiator': demisto.get(activity, 'Initiator'), 'CreatedDate': demisto.get(activity, 'CreatedDate'), 'UpdateDate': demisto.get(activity, 'UpdateDate'), 'RemediationBlocklistUpdate': demisto.get(activity, 'AdditionalInformation.RemediationBlocklistUpdate'), 'AskTheAnalyst': {'Replies': demisto.get(activity, 'AdditionalInformation.AskTheAnalyst.Replies')}, 'Mail': {'Replies': demisto.get(activity, 'AdditionalInformation.Mail.Replies')}, 'ReadBy': demisto.get(activity, 'ReadBy') }) human_readable_arr.append({ 'ID': demisto.get(activity, '_id'), 'Type': demisto.get(activity, 'Type'), 'Initiator': demisto.get(activity, 'Initiator'), 'CreatedDate': demisto.get(activity, 'CreatedDate'), 'UpdateDate': demisto.get(activity, 'UpdateDate'), 'RemediationBlocklistUpdate': extract_remediation( demisto.get(activity, 'AdditionalInformation.RemediationBlocklistUpdate')) if demisto.get(activity, 'AdditionalInformation') else '', 'AskTheAnalyst': {'Replies': demisto.get(activity, 'AdditionalInformation.AskTheAnalyst.Replies')}, 'Mail': extract_mail( demisto.get(activity, 'AdditionalInformation.Mail.Replies')) if demisto.get(activity, 'AdditionalInformation.Mail') else '', 'ReadBy': demisto.get(activity, 'ReadBy') }) headers = ['ID', 'Type', 'Initiator', 'CreatedDate', 'UpdateDate', 'RemediationBlocklistUpdate', 'AskTheAnalyst', 'Mail', 'ReadBy'] human_readable = tableToMarkdown('IntSights Alert {} Activity Log'.format(alert_id), t=human_readable_arr, headers=headers), demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': alert}, 'Contents': response, 'HumanReadable': human_readable, 'ContentsFormat': formats['json'] }) def change_severity(): """ Change severity of an alert """ alert_id = demisto.getArg('alert-id') severity = demisto.getArg('severity') http_request('PATCH', 'public/v1/data/alerts/change-severity/' + alert_id, json_data={'Severity': severity}) severity_details = {'ID': alert_id, 'Severity': severity} demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': severity_details}, 'Contents': severity_details, 'HumanReadable': tableToMarkdown( 'IntSights Update Alert Severity: The Alert severity has been successfully updated.', [severity_details], ['ID', 'Severity']), 'ContentsFormat': formats['json'] }) def get_assignee_id(assignee_email): response = http_request('GET', 'public/v1/account/users-details', json_response=True) for user in response: if assignee_email == user.get('Email', ''): return user.get('_id') raise Exception('user not found') def assign_alert(): """ Assign alert to an Assignee ID """ alert_id = demisto.getArg('alert-id') assignee_email = demisto.getArg('assignee-email') is_mssp = demisto.getArg('is-mssp-optional') assignee_id = get_assignee_id(assignee_email) assign_details = {'ID': alert_id, 'Assignees.AssigneeID': assignee_id} url = 'public/v1/data/alerts/assign-alert/' + alert_id if is_mssp: url += '?IsMssp=' + is_mssp http_request('PATCH', url, json_data={'AssigneeID': assignee_id}) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': assign_details}, 'Contents': assign_details, 'HumanReadable': tableToMarkdown( 'IntSights Assign Alert: The Alert has been successfully assigned to assigneeID', [assign_details], ['ID', 'Assignees.AssigneeID']), 'ContentsFormat': formats['json'] }) def unassign_alert(): """ Unassign an alert """ alert_id = demisto.getArg('alert-id') http_request('PATCH', 'public/v1/data/alerts/unassign-alert/' + alert_id) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': {'ID': alert_id}}, 'Contents': {'ID': alert_id}, 'HumanReadable': 'Alert id: ' + alert_id + ' successfully unassigned', 'ContentsFormat': formats['json'] }) def close_alert(): """ Close an alert """ alert_id = demisto.getArg('alert-id') reason = demisto.getArg('reason') free_text = demisto.getArg('free-text') is_hidden = demisto.getArg('is-hidden') == 'True' rate = demisto.getArg('rate') close_details = {'ID': alert_id, 'Close Reason': reason, 'Closed FreeText': free_text, 'Closed Rate': rate, 'IsHidden': is_hidden} close_details_context = {'ID': alert_id, 'Closed': {'Reason': reason, 'FreeText': free_text, 'Rate': rate}, 'IsHidden': is_hidden} url = 'public/v1/data/alerts/close-alert/' + alert_id json_data = {'Reason': reason} if free_text: json_data['FreeText'] = free_text if is_hidden: json_data['IsHidden'] = is_hidden if rate: json_data['Rate'] = rate http_request('PATCH', url, json_data) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': close_details}, 'Contents': close_details_context, 'HumanReadable': tableToMarkdown('IntSights Close Alert: The Alert has successfully been closed.', [close_details], ['ID', 'Close Reason', 'Closed FreeText', 'Closed Rate', 'IsHidden']), 'ContentsFormat': formats['json'] }) def send_mail(): """ Send email with the alert details and a question """ alert_id = demisto.getArg('alert-id') emails = argToList(demisto.getArg('emails')) content = demisto.getArg('content') http_request('POST', 'public/v1/data/alerts/send-mail/' + alert_id, {'Emails': emails, 'Content': content}) context = { 'ID': alert_id, 'EmailID': emails, 'Question': content } demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': context}, 'Contents': context, 'HumanReadable': 'Email with content (' + content + ') sent to emails', 'ContentsFormat': formats['json'] }) def get_tag_id(alert_id, tag_name): response = http_request('GET', 'public/v1/data/alerts/get-complete-alert/' + alert_id, json_response=True) details = response.get('Details', {}) tags = details.get('Tags', []) for tag in tags: if tag.get('Name', '') == tag_name: return tag.get('_id', '') return 'Not found' def add_tag(): """ Adds a tag to the alert """ alert_id = demisto.getArg('alert-id') tag_name = demisto.getArg('tag-name') http_request('PATCH', 'public/v1/data/alerts/add-tag/' + alert_id, json_data={'TagName': tag_name}) tag_info = { 'TagName': tag_name, 'ID': get_tag_id(alert_id, tag_name) } context = { 'ID': alert_id, 'Tags': tag_info } demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': context}, 'Contents': context, 'HumanReadable': 'Tag (' + tag_name + ') added to alert id: ' + alert_id, 'ContentsFormat': formats['json'] }) def remove_tag(): """ Removes a tag from an alert """ alert_id = demisto.getArg('alert-id') tag_id = demisto.getArg('tag-id') http_request('PATCH', 'public/v1/data/alerts/remove-tag/' + alert_id, json_data={'TagID': tag_id}) context = { 'ID': alert_id, 'Tags': {'ID': tag_id} } demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': context}, 'Contents': context, 'HumanReadable': 'Tag id: ' + tag_id + ' removed from alert id: ' + alert_id, 'ContentsFormat': formats['json'] }) def add_comment(): """ Adds a comment to an alert """ alert_id = demisto.getArg('alert-id') comment = demisto.getArg('comment') http_request('PATCH', 'public/v1/data/alerts/add-comment/' + alert_id, json_data={'Comment': comment}) context = { 'ID': alert_id, 'Comment': comment } demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': context}, 'Contents': context, 'HumanReadable': 'Succesfully added comment "' + comment + '" to alert id: ' + alert_id, 'ContentsFormat': formats['json'] }) def ioc_to_readable(ioc_data): """ Convert IOC to readable format """ reported_feeds = demisto.get(ioc_data, 'reportedFeeds', demisto.get(ioc_data, 'sources', [{}])) single_reported_feed = reported_feeds[0] if isinstance(reported_feeds, list) else reported_feeds ioc_context = { 'ID': demisto.get(ioc_data, '_id'), 'Type': demisto.get(ioc_data, 'type'), 'Value': demisto.get(ioc_data, 'value'), 'FirstSeen': demisto.get(ioc_data, 'firstSeen'), 'LastSeen': demisto.get(ioc_data, 'lastSeen'), 'LastUpdateDate': demisto.get(ioc_data, 'lastUpdateDate'), 'Status': demisto.get(ioc_data, 'status'), 'Severity': demisto.get(ioc_data, 'severity'), 'RelatedMalware': demisto.get(ioc_data, 'relatedMalware'), 'RelatedCampaigns': demisto.get(ioc_data, 'relatedCampaigns'), 'Geolocation': demisto.get(ioc_data, 'geolocation', demisto.get(ioc_data, 'Geolocation')), 'RelatedThreatActors': demisto.get(ioc_data, 'relatedThreatActors'), 'Sources': reported_feeds, 'SourceName': single_reported_feed.get('name'), # bw compatibility 'SourceConfidence': single_reported_feed.get('confidenceLevel'), 'SourceID': single_reported_feed.get('id'), 'Tags': demisto.get(ioc_data, 'tags'), 'Whitelisted': demisto.get(ioc_data, 'Whitelisted', demisto.get(ioc_data, 'whitelisted')), } ioc_readable = { 'ID': demisto.get(ioc_data, '_id'), 'AccountID': demisto.get(ioc_context, 'AccountID'), 'Type': demisto.get(ioc_context, 'Type'), 'Value': demisto.get(ioc_context, 'Value'), 'FirstSeen': demisto.get(ioc_context, 'FirstSeen'), 'LastSeen': demisto.get(ioc_context, 'LastSeen'), 'Status': demisto.get(ioc_context, 'Status'), 'Severity': demisto.get(ioc_context, 'Severity'), 'Geolocation': demisto.get(ioc_context, 'Geolocation'), 'SourceName': demisto.get(ioc_context, 'SourceName'), 'SourceID': demisto.get(ioc_context, 'SourceID'), 'SourceConfidence': demisto.get(ioc_context, 'SourceConfidence') } dbot_score = { 'Indicator': ioc_context['Value'], 'Type': IOC_TYPE_TO_DBOT_TYPE[ioc_context['Type']], 'Vendor': 'IntSights', 'Score': translate_severity(ioc_readable['Severity']) } malicious_dict = { 'Vendor': 'IntSights', 'Description': 'IntSights severity level is High' } domain = {} if ioc_context['Type'] == 'Domains': domain['Name'] = ioc_context['Value'] ioc_context['Domain'] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: domain['Malicious'] = malicious_dict ip_info = {} if ioc_context['Type'] == 'IpAddresses': ip_info['Address'] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: ip_info['Malicious'] = malicious_dict url_info = {} if ioc_context['Type'] == 'Urls': url_info['Data'] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: url_info['Malicious'] = malicious_dict hash_info = {} if ioc_context['Type'] == 'Hashes': hash_info['Name'] = ioc_context['Value'] hash_info[hash_identifier(ioc_context['Value'])] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: hash_info['Malicious'] = malicious_dict return ioc_context, ioc_readable, dbot_score, domain, ip_info, url_info, hash_info def search_for_ioc(): """ Search for IOC by value """ response = http_request('GET', 'public/v3/iocs/ioc-by-value', params=handle_filters(), json_response=True) if response: ioc_context, ioc_readable, dbot_score, domain, ip_info, url_info, hash_info = ioc_to_readable(response) demisto.results( { 'Type': entryTypes['note'], 'EntryContext': { 'IntSights.Iocs(val.Value === obj.Value)': ioc_context, 'DBotScore': dbot_score, 'Domain': domain, 'IP': ip_info, 'URL': url_info, 'File': hash_info }, 'Contents': response, 'HumanReadable': tableToMarkdown('IOC Information', [ioc_readable], ['Type', 'Value', 'FirstSeen', 'LastSeen', 'Status', 'Severity', 'SourceID', 'SourceName', 'SourceConfidence', 'GeoLocation']), 'ContentsFormat': formats['json'] } ) else: results_for_no_content('IOC Information', 'Could not get any results.') def results_for_no_content(cmd_name, additional_information): demisto.results( { 'Type': entryTypes['note'], 'EntryContext': {'IntSights': {}}, 'Contents': {}, 'HumanReadable': '### {} \n\n {}'.format(cmd_name, additional_information), 'ContentsFormat': formats['json'] } ) def ioc_enrichment_to_readable(ioc_data): """ Convert IOC to readable format """ ioc_context = { 'Type': demisto.get(ioc_data, 'Data.Type'), 'Value': demisto.get(ioc_data, 'Data.Value'), 'FirstSeen': demisto.get(ioc_data, 'Data.FirstSeen'), 'LastSeen': demisto.get(ioc_data, 'Data.LastSeen'), 'Status': demisto.get(ioc_data, 'Status'), 'Severity': demisto.get(ioc_data, 'Data.Severity.Value'), 'RelatedMalwares': demisto.get(ioc_data, 'Data.RelatedMalwares'), 'Sources': demisto.get(ioc_data, 'Data.Sources'), 'IsKnownIoc': demisto.get(ioc_data, 'Data.IsKnownIoc'), 'RelatedThreatActors': demisto.get(ioc_data, 'Data.RelatedThreatActors'), 'SystemTags': demisto.get(ioc_data, 'Data.SystemTags'), 'Tags': demisto.get(ioc_data, 'Data.Tags'), 'Whitelisted': demisto.get(ioc_data, 'Data.Whitelisted'), 'OriginalValue': demisto.get(ioc_data, 'Data.OriginalValue'), } ioc_readable = { 'Type': demisto.get(ioc_data, 'Data.Type'), 'Value': demisto.get(ioc_data, 'Data.Value'), 'FirstSeen': demisto.get(ioc_data, 'Data.FirstSeen'), 'LastSeen': demisto.get(ioc_data, 'Data.LastSeen'), 'Status': demisto.get(ioc_data, 'Status'), 'Severity': demisto.get(ioc_data, 'Data.Severity.Value'), 'RelatedMalwares': demisto.get(ioc_data, 'Data.RelatedMalwares'), 'Sources': demisto.get(ioc_data, 'Data.Sources'), 'IsKnownIoc': demisto.get(ioc_data, 'Data.IsKnownIoc'), 'RelatedThreatActors': demisto.get(ioc_data, 'Data.RelatedThreatActors'), 'SystemTags': demisto.get(ioc_data, 'Data.SystemTags'), 'Tags': demisto.get(ioc_data, 'Data.Tags'), 'Whitelisted': demisto.get(ioc_data, 'Data.Whitelisted'), 'OriginalValue': demisto.get(ioc_data, 'OriginalValue'), } dbot_score = { 'Indicator': ioc_context['Value'], 'Type': IOC_TYPE_TO_DBOT_TYPE[ioc_context['Type']], 'Vendor': 'IntSights', 'Score': translate_severity(ioc_readable['Severity']) } malicious_dict = { 'Vendor': 'IntSights', 'Description': 'IntSights severity level is High' } domain = {} if ioc_context['Type'] == 'Domains': domain['Name'] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: domain['Malicious'] = malicious_dict domain['DNS'] = demisto.get(ioc_data, 'Data.DnsRecords') domain['Resolutions'] = demisto.get(ioc_data, 'Data.Resolutions') domain['Subdomains'] = demisto.get(ioc_data, 'Data.Subdomains') domain['WHOIS/History'] = demisto.get(ioc_data, 'Data.Whois.History') domain['WHOIS'] = { 'Registrant': { 'Name': demisto.get(ioc_data, 'Data.Whois.Current.RegistrantDetails.Name'), 'Email': demisto.get(ioc_data, 'Data.Whois.Current.RegistrantDetails.Email'), 'Phone': demisto.get(ioc_data, 'Data.Whois.Current.RegistrantDetails.Telephone'), }, 'DomainStatus': ', '.join(demisto.get(ioc_data, 'Data.Whois.Current.RegistrationDetails.Statuses')), 'NameServers': ', '.join(demisto.get(ioc_data, 'Data.Whois.Current.RegistrationDetails.NameServers')), 'CreationDate': demisto.get(ioc_data, 'Data.Whois.Current.RegistrationDetails.CreatedDate'), 'UpdatedDate': demisto.get(ioc_data, 'Data.Whois.Current.RegistrationDetails.UpdatedDate'), 'ExpirationDate': demisto.get(ioc_data, 'Data.Whois.Current.RegistrationDetails.ExpiresDate') } ip_info = {} if ioc_context['Type'] == 'IpAddresses': ip_info['Address'] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: ip_info['Malicious'] = malicious_dict ip_info['IpDetails'] = demisto.get(ioc_data, 'Data.IpDetails') ip_info['RelatedHashes'] = demisto.get(ioc_data, 'Data.RelatedHashes') ip_info['WHOIS'] = { 'NetworkDetails': demisto.get(ioc_data, 'Data.Whois.NetworkDetails'), 'RegistrantDetails': demisto.get(ioc_data, 'Data.Whois.RegistrantDetails') } url_info = {} if ioc_context['Type'] == 'Urls': url_info['Data'] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: url_info['Malicious'] = malicious_dict url_info['AntivirusDetectedEngines'] = demisto.get(ioc_data, 'Data.AntivirusDetectedEngines') url_info['AntivirusDetectionRatio'] = demisto.get(ioc_data, 'Data.AntivirusDetectionRatio') url_info['AntivirusDetections'] = demisto.get(ioc_data, 'Data.AntivirusDetections') url_info['AntivirusScanDate'] = demisto.get(ioc_data, 'Data.AntivirusScanDate') url_info['RelatedHashes'] = { 'communicating': demisto.get(ioc_data, 'Data.RelatedHashes.communicating'), 'downloaded': demisto.get(ioc_data, 'Data.RelatedHashes.downloaded'), 'referencing': demisto.get(ioc_data, 'Data.RelatedHashes.referencing'), } hash_info = {} if ioc_context['Type'] == 'Hashes': hash_info['Name'] = ioc_context['Value'] hash_info[hash_identifier(ioc_context['Value'])] = ioc_context['Value'] if translate_severity(ioc_readable['Severity']) == 3: hash_info['Malicious'] = malicious_dict hash_info['AntivirusDetectedEngines'] = demisto.get(ioc_data, 'Data.AntivirusDetectedEngines') hash_info['AntivirusDetectionRatio'] = demisto.get(ioc_data, 'Data.AntivirusDetectionRatio') hash_info['AntivirusDetections'] = demisto.get(ioc_data, 'Data.AntivirusDetections') hash_info['AntivirusScanDate'] = demisto.get(ioc_data, 'Data.AntivirusScanDate') return ioc_context, ioc_readable, dbot_score, domain, ip_info, url_info, hash_info def request_for_ioc_enrichment(): """ Request for IOC enrichment """ ioc_value = demisto.getArg('value') request_url = 'public/v1/iocs/enrich/{}'.format(ioc_value) response = http_request('GET', request_url, json_response=True) status = response.get('Status') if status == 'Done': ioc_context, ioc_readable, dbot_score, domain, ip_info, url_info, hash_info = ioc_enrichment_to_readable( response) demisto.results( { 'Type': entryTypes['note'], 'EntryContext': { 'IntSights.Iocs(val.ID === obj.ID)': ioc_context, 'DBotScore': dbot_score, 'Domain': domain, 'IP': ip_info, 'URL': url_info, 'File': hash_info }, 'Contents': response, 'HumanReadable': tableToMarkdown('IOC Enrichment', ioc_readable), 'ContentsFormat': formats['json'] } ) elif status == 'Queued' or status == 'InProgress': demisto.results( { 'Type': entryTypes['note'], 'EntryContext': { 'IntSights.Iocs(val.ID === obj.ID)': { 'Value': demisto.get(response, 'OriginalValue'), 'Status': demisto.get(response, 'Status') }, }, 'Contents': response, 'ContentsFormat': formats['json'] } ) elif status == 'QuotaExceeded': raise Exception('Could not get any results. Reason: Quota exceded.') else: reason = response.get('FailedReason', '') raise Exception('Could not get any results. Reason: {}.'.format(reason)) def translate_severity(sev): """ Translate alert severity to demisto """ if sev in ['Medium', 'High']: return 3 if sev == 'Low': return 2 return 0 def fetch_incidents(): """ Fetch incidents for Demisto """ last_run = demisto.getLastRun() demisto.info("IntSight fetch last run time is: {}".format(str(last_run))) if not last_run or 'time' not in last_run: first_fetch_param = demisto.params().get('first_fetch', DEFAULT_TIME_RANGE) first_fetch_date = arg_to_datetime(first_fetch_param, 'first_fetch') fetch_delta = int(first_fetch_date.timestamp() * 1000) # type:ignore demisto.debug(f'First fetch, using {fetch_delta=}') else: fetch_delta = last_run.get('time') current_fetch = fetch_delta alert_type = demisto.getParam('type') min_severity_level = demisto.params().get('severity_level', 'All') if min_severity_level not in SEVERITY_LEVEL: raise Exception("Minimum Alert severity level to fetch incidents incidents from, allowed values are: All," " Low, Medium, High. (Setting to All will fetch all incidents)") demisto.debug(f'{min_severity_level=}') _, alerts_context = get_alerts_helper(handle_filters(fetch_delta)) incidents = [] for alert in alerts_context: if SEVERITY_LEVEL[min_severity_level] <= SEVERITY_LEVEL[alert.get('Severity', 'Low')]: if not alert_type or alert_type.lower() == alert.get('Type', '').lower(): incidents.append({ 'name': '{type} - {id}'.format(type=alert.get('Type', 'Type not found'), id=alert.get('ID')), 'occurred': alert.get('FoundDate'), 'severity': translate_severity(alert.get('Severity')), 'rawJSON': json.dumps(alert) }) alert_timestamp = date_to_timestamp(alert.get('FoundDate'), date_format='%Y-%m-%dT%H:%M:%S.%fZ') if alert_timestamp > current_fetch: current_fetch = alert_timestamp else: demisto.debug(f'dropping incident with id {alert.get("ID")} because of alert_type filter') else: demisto.debug(f'dropping incident with id {alert.get("ID")} because of severity filter') demisto.debug(f'returning {len(incidents)} incidents') demisto.incidents(incidents) demisto.setLastRun({'time': current_fetch + 1000}) def get_iocs(): """ Gets all IOCs with the given filters """ response = http_request('GET', 'public/v3/iocs', params=handle_filters(), json_response=True) content = response.get('content') domains = [] ip_infos = [] url_infos = [] hash_infos = [] dbot_scores = [] iocs_context = [] iocs_readable = [] for indicator in content: ioc_context, ioc_readable, dbot_score, domain, ip_info, url_info, hash_info = ioc_to_readable(indicator) iocs_context.append(ioc_context) iocs_readable.append(ioc_readable) dbot_scores.append(dbot_score) domains.append(domain) ip_infos.append(ip_info) url_infos.append(url_info) hash_infos.append(hash_info) headers = ['Type', 'Value', 'FirstSeen', 'LastSeen', 'Status', 'Severity', 'SourceID', 'SourceName', 'SourceConfidence', 'Geolocation'] demisto.results( { 'Type': entryTypes['note'], 'EntryContext': { 'IntSights.Iocs(val.Value && val.Value === obj.Value)': iocs_context, 'DBotScore': dbot_scores, 'Domain': domains, 'IP': ip_infos, 'URL': url_infos, 'File': hash_infos }, 'Contents': response, 'HumanReadable': tableToMarkdown('IOC Information', t=iocs_readable, headers=headers), 'ContentsFormat': formats['json'] } ) def takedown_request(): """ Request alert takedown """ alert_id = demisto.getArg('alert-id') http_request('PATCH', 'public/v1/data/alerts/takedown-request/' + alert_id) context = { 'ID': alert_id, } human_readable = '### IntSights Alert Takedown\n' \ 'The Alert Takedown request has been sent successfully for {}'.format(str(alert_id)) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': context}, 'Contents': context, 'HumanReadable': human_readable, 'ContentsFormat': formats['json'] }) def get_alert_takedown_status(): """ Get an alert's takedown status """ alert_id = demisto.getArg('alert-id') response = http_request('GET', 'public/v1/data/alerts/takedown-status/' + alert_id) context = { 'ID': alert_id, 'TakedownStatus': response.text } demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': context}, 'Contents': context, 'HumanReadable': tableToMarkdown('IntSights Alert Takedown Status', [context], ['ID', 'TakedownStatus']), 'ContentsFormat': formats['json'] }) def update_ioc_blocklist_status(): alert_id = demisto.getArg('alert-id') types = argToList(demisto.getArg('type')) values = argToList(demisto.getArg('value')) statuses = argToList(demisto.getArg('blocklist-status')) if len(types) != len(values) or len(types) != len(statuses): return_error('The lists must be of equal length. For each IOC, provide an entry in each list.') data = [] for count, type_ in enumerate(types): data.append({ 'Type': type_, 'Value': values[count], 'BlocklistStatus': statuses[count] }) http_request('PATCH', 'public/v1/data/alerts/change-iocs-blocklist-status/' + alert_id, json_data={'Iocs': data}) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.Alerts(val.ID === obj.ID)': {'ID': alert_id, 'Status': statuses}}, 'Contents': {'ID': alert_id, 'Status': statuses}, 'HumanReadable': tableToMarkdown('IntSights Update IOC BlockList Status for ' + alert_id, data, ['BlocklistStatus']), 'ContentsFormat': formats['json'] }) def get_ioc_blocklist_status(): alert_id = demisto.getArg('alert-id') response = http_request('GET', 'public/v1/data/alerts/blocklist-status/' + alert_id, json_response=True) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': { 'IntSights.Alerts(val.ID === obj.ID)': {'ID': alert_id, 'Status': [ioc.get('Status') for ioc in response]}}, 'Contents': response, 'HumanReadable': tableToMarkdown('IntSights Blocklist Status for ' + alert_id, response, ['Status']), 'ContentsFormat': formats['json'] }) def get_mssp_sub_accounts(): account_id = demisto.getParam('credentials')['identifier'] MSSP_ACCOUNT_ID = demisto.getParam('mssp_sub_account_id') accounts = http_request('GET', 'public/v1/mssp/customers', json_response=True) if not accounts: return_error("intsights-mssp-get-sub-accounts failed to return data.") # Fix accounts _id keys for account in accounts: account["ID"] = account["_id"] del account["_id"] if len(accounts) < 1: return_error('Current MSSP Account has no sub accounts.') account_ids = [i["ID"] for i in accounts] if MSSP_ACCOUNT_ID not in account_ids: demisto.debug("[DEBUG] - MSSP sub accounts:" + str(accounts)) return_error('Entered sub account id ({}) is not part of this mssp account'.format(MSSP_ACCOUNT_ID)) for i, account in enumerate(account_ids): # Call account HEADERS['Account-Id'] = account account_ua = http_request('GET', 'public/v1/account/used-assets', json_response=True) if not account_ua: continue accounts[i].update(account_ua) demisto.results({ 'Type': entryTypes['note'], 'EntryContext': {'IntSights.MsspAccount(val.ID === obj.ID)': accounts}, 'HumanReadable': tableToMarkdown('IntSights MSSP accounts used assets ' + account_id, accounts, ["ID", 'CompanyName', "Status", "AssetsLimit", "AssetsCount"]), 'Contents': accounts, 'ContentsFormat': formats['json'] }) # Restore the header HEADERS['Account-Id'] = MSSP_ACCOUNT_ID def test_module(): http_request('GET', 'public/v1/api/version') if demisto.params().get('isFetch'): min_severity_level = demisto.params().get('severity_level', 'All') if min_severity_level not in SEVERITY_LEVEL: return_error("Minimum Alert severity level to fetch incidents incidents from, allowed values are: " "All, Low, Medium, High. (Setting to All will fetch all incidents)") demisto.results('ok') def main(): # pragma: no cover try: if demisto.command() == 'test-module': test_module() elif demisto.command() == 'fetch-incidents': fetch_incidents() elif demisto.command() == 'intsights-mssp-get-sub-accounts': get_mssp_sub_accounts() elif demisto.command() == 'intsights-get-alerts': get_alerts() elif demisto.command() == 'intsights-get-alert-image': get_alert_image() elif demisto.command() == 'intsights-get-alert-activities': get_alert_activity() elif demisto.command() == 'intsights-assign-alert': assign_alert() elif demisto.command() == 'intsights-unassign-alert': unassign_alert() elif demisto.command() == 'intsights-send-mail': send_mail() elif demisto.command() == 'intsights-ask-the-analyst': ask_analyst() elif demisto.command() == 'intsights-add-tag-to-alert': add_tag() elif demisto.command() == 'intsights-remove-tag-from-alert': remove_tag() elif demisto.command() == 'intsights-add-comment-to-alert': add_comment() elif demisto.command() == 'intsights-update-alert-severity': change_severity() elif demisto.command() == 'intsights-get-alert-by-id': get_alert_by_id() elif demisto.command() == 'intsights-get-ioc-by-value': search_for_ioc() elif demisto.command() == 'intsights-request-ioc-enrichment': request_for_ioc_enrichment() elif demisto.command() == 'intsights-get-iocs': get_iocs() elif demisto.command() == 'intsights-alert-takedown-request': takedown_request() elif demisto.command() == 'intsights-get-alert-takedown-status': get_alert_takedown_status() elif demisto.command() == 'intsights-get-ioc-blocklist-status': get_ioc_blocklist_status() elif demisto.command() == 'intsights-update-ioc-blocklist-status': update_ioc_blocklist_status() elif demisto.command() == 'intsights-close-alert': close_alert() elif demisto.command() == 'intsights-test-action': pass else: raise Exception('Unrecognized command: ' + demisto.command()) except Exception as err: return_error(str(err)) if __name__ in ('__main__', 'builtin', 'builtins'): main()