From 68d4580785b1d87106f5d43fe6eb4b4033c4e5ae Mon Sep 17 00:00:00 2001 From: crestdatasystems Date: Thu, 21 Nov 2024 18:01:41 +0530 Subject: [PATCH] Rubrik Release 1.4.0 --- Packs/RubrikPolaris/.pack-ignore | 8 +- Packs/RubrikPolaris/.secrets-ignore | 3 +- .../Integrations/RubrikPolaris/README.md | 451 ++++++++++++ .../RubrikPolaris/RubrikPolaris.py | 259 ++++++- .../RubrikPolaris/RubrikPolaris.yml | 607 ++++++++++++++- .../RubrikPolaris/RubrikPolaris_test.py | 100 +++ .../test_data/domain_command_success_hr.md | 24 + .../domain_command_success_output.json | 59 ++ .../domain_command_success_response.json | 58 ++ .../test_data/domain_indicator.json | 16 + .../test_data/ip_command_success_hr.md | 24 + .../test_data/ip_command_success_output.json | 59 ++ .../ip_command_success_response.json | 58 ++ .../RubrikPolaris/test_data/ip_indicator.json | 13 + ...kload_Analysis_-_Rubrik_Security_Cloud.yml | 697 ++++++++++++++++++ ...Analysis_-_Rubrik_Security_Cloud_README.md | 45 ++ Packs/RubrikPolaris/ReleaseNotes/1_4_0.md | 21 + .../README.md | 27 + ...tIncidentSeverityUsingWorkLoadRiskLevel.py | 101 +++ ...IncidentSeverityUsingWorkLoadRiskLevel.yml | 53 ++ ...dentSeverityUsingWorkLoadRiskLevel_test.py | 146 ++++ ...kload_Analysis_-_Rubrik_Security_Cloud.png | Bin 0 -> 148582 bytes Packs/RubrikPolaris/pack_metadata.json | 2 +- 23 files changed, 2826 insertions(+), 5 deletions(-) create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_hr.md create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_output.json create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_response.json create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_indicator.json create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_hr.md create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_output.json create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_response.json create mode 100644 Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_indicator.json create mode 100644 Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.yml create mode 100644 Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud_README.md create mode 100644 Packs/RubrikPolaris/ReleaseNotes/1_4_0.md create mode 100644 Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/README.md create mode 100644 Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.py create mode 100644 Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.yml create mode 100644 Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel_test.py create mode 100644 Packs/RubrikPolaris/doc_files/Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.png diff --git a/Packs/RubrikPolaris/.pack-ignore b/Packs/RubrikPolaris/.pack-ignore index c448418ec611..3258bb1e3ed0 100644 --- a/Packs/RubrikPolaris/.pack-ignore +++ b/Packs/RubrikPolaris/.pack-ignore @@ -144,4 +144,10 @@ std graphql mappings validations -typename \ No newline at end of file +typename +TLP +registrant +internationalized +IDN +B +Bool \ No newline at end of file diff --git a/Packs/RubrikPolaris/.secrets-ignore b/Packs/RubrikPolaris/.secrets-ignore index 7c6432818b49..093cfdd4c8f4 100644 --- a/Packs/RubrikPolaris/.secrets-ignore +++ b/Packs/RubrikPolaris/.secrets-ignore @@ -63,4 +63,5 @@ arg_name="historical_delta_days", demo@rubrik.com demo2@rubrik.com :: -https://rubrik-test.my.rubrik.com \ No newline at end of file +https://rubrik-test.my.rubrik.com +0.0.0.1 \ No newline at end of file diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/README.md b/Packs/RubrikPolaris/Integrations/RubrikPolaris/README.md index 77f7af1a0623..29005f5585fc 100644 --- a/Packs/RubrikPolaris/Integrations/RubrikPolaris/README.md +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/README.md @@ -19,6 +19,7 @@ This integration was integrated and tested with version 1.0.0 of Rubrik Security | Fetch Limit (Maximum of 1000) | Maximum number of incidents to fetch every time. The maximum value is 1000. | False | | Anomaly Event Critical Severity Level Mapping | When a Anomaly event of Critical severity is detected and fetched, this setting indicates what severity will get assigned within XSOAR. | False | | Anomaly Event Warning Severity Level Mapping | When a Anomaly event of Warning severity is detected and fetched, this setting indicates what severity will get assigned within XSOAR. | False | + | Source Reliability | Reliability of the source providing the intelligence data. | False | | Use system proxy settings | Whether to use XSOAR's system proxy settings to connect to the API. | False | | Trust any certificate (not secure) | Whether to allow connections without verifying SSL certificates validity. | False | @@ -2721,3 +2722,453 @@ Retrieve the suspicious list of files for a snapshot ID with detected file anoma >|---|---|---|---| >| /C:/Shares/Restore-My-Files.txt.lockbit | Ransomware Encryption | 2512 | 2024-02-05T16:00:44.000Z | >| /C:/Users/Public/Desktop/Restore-My-Files.txt | Ransomware Note | 2484 | 2024-02-08T02:00:03.000Z | + + +### ip + +*** +Retrieve the sensitive information available for the given IP address(es). + +#### Base Command + +`ip` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| ip | The IP address\(es\) for which to retrieve sensitive information. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| DBotScore.Indicator | String | The indicator that was tested. | +| DBotScore.Type | String | The indicator type. | +| DBotScore.Vendor | String | The vendor used to calculate the score. | +| DBotScore.Score | Number | The actual score. | +| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. | +| IP.Address | String | IP address. | +| IP.Relationships.EntityA | String | The source of the relationship. | +| IP.Relationships.EntityB | String | The destination of the relationship. | +| IP.Relationships.Relationship | String | The name of the relationship. | +| IP.Relationships.EntityAType | String | The type of the source of the relationship. | +| IP.Relationships.EntityBType | String | The type of the destination of the relationship. | +| IP.ASN | String | The autonomous system name for the IP address, for example: "AS8948". | +| IP.Hostname | String | The hostname that is mapped to this IP address. | +| IP.Geo.Location | String | The geolocation where the IP address is located, in the format: latitude:longitude. | +| IP.Geo.Country | String | The country in which the IP address is located. | +| IP.Geo.Description | String | Additional information about the location. | +| IP.DetectionEngines | Number | The total number of engines that checked the indicator. | +| IP.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. | +| IP.Malicious.Vendor | String | The vendor reporting the IP address as malicious. | +| IP.Malicious.Description | String | A description explaining why the IP address was reported as malicious. | +| IP.Tags | Unknown | Tags of the IP address. | +| IP.FeedRelatedIndicators.value | String | Indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the IP address. | +| IP.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the IP address. | +| IP.MalwareFamily | String | The malware family associated with the IP address. | +| IP.Organization.Name | String | The organization of the IP address. | +| IP.Organization.Type | String | The organization type of the IP address. | +| IP.ASOwner | String | The autonomous system owner of the IP address. | +| IP.Region | String | The region in which the IP address is located. | +| IP.Port | String | Ports that are associated with the IP address. | +| IP.Internal | Boolean | Whether the IP address is internal or external. | +| IP.UpdatedDate | Date | The date that the IP address was last updated. | +| IP.Registrar.Abuse.Name | String | The name of the contact for reporting abuse. | +| IP.Registrar.Abuse.Address | String | The address of the contact for reporting abuse. | +| IP.Registrar.Abuse.Country | String | The country of the contact for reporting abuse. | +| IP.Registrar.Abuse.Network | String | The network of the contact for reporting abuse. | +| IP.Registrar.Abuse.Phone | String | The phone number of the contact for reporting abuse. | +| IP.Registrar.Abuse.Email | String | The email address of the contact for reporting abuse. | +| IP.Campaign | String | The campaign associated with the IP address. | +| IP.TrafficLightProtocol | String | The Traffic Light Protocol \(TLP\) color that is suitable for the IP address. | +| IP.CommunityNotes.note | String | Notes on the IP address that were given by the community. | +| IP.CommunityNotes.timestamp | Date | The time in which the note was published. | +| IP.Publications.source | String | The source in which the article was published. | +| IP.Publications.title | String | The name of the article. | +| IP.Publications.link | String | A link to the original article. | +| IP.Publications.timestamp | Date | The time in which the article was published. | +| IP.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. | +| IP.ThreatTypes.threatcategoryconfidence | String | The confidence level provided by the vendor for the threat type category For example, a confidence of 90 for the threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. | +| RubrikPolaris.IP.ip | String | IP address of the object. | +| RubrikPolaris.IP.generalInfo.fid | String | The foreign ID of the object. | +| RubrikPolaris.IP.generalInfo.name | String | The name of the object. | +| RubrikPolaris.IP.generalInfo.objectType | String | The type of the object. | +| RubrikPolaris.IP.generalInfo.protectionStatus | String | The protection status of the object. | +| RubrikPolaris.IP.generalInfo.lastSnapshot | Date | The timestamp of the last snapshot of the object. | +| RubrikPolaris.IP.generalInfo.redirectLink | String | The link to the object in the Rubrik UI. | +| RubrikPolaris.IP.sensitiveInfo.riskLevel | String | The risk level of the object. | +| RubrikPolaris.IP.sensitiveInfo.sensitiveFiles.mediumCount | String | The number of sensitive files of medium risk level. | +| RubrikPolaris.IP.sensitiveInfo.sensitiveHits | Number | The number of sensitive files. | +| RubrikPolaris.IP.sensitiveInfo.openAccessFiles | Number | The number of open access files. | +| RubrikPolaris.IP.sensitiveInfo.staleFiles | Number | The number of stale files. | +| RubrikPolaris.IP.sensitiveInfo.redirectLink | String | The link to the sensitive information in the Rubrik UI. | +| RubrikPolaris.IP.sensitiveInfo.policyNames | String | The names of the policies associated with the object. | +| RubrikPolaris.IP.anomalyInfo.severity | String | The severity of the anomaly. | +| RubrikPolaris.IP.anomalyInfo.detectionTime | Date | The timestamp of the anomaly detection. | +| RubrikPolaris.IP.anomalyInfo.createdFileCount | String | The number of created files. | +| RubrikPolaris.IP.anomalyInfo.deletedFileCount | String | The number of deleted files. | +| RubrikPolaris.IP.anomalyInfo.modifiedFileCount | String | The number of modified files. | +| RubrikPolaris.IP.anomalyInfo.suspiciousFileCount | String | The number of suspicious files. | +| RubrikPolaris.IP.anomalyInfo.redirectLink | String | The link to the anomaly information in the Rubrik UI. | +| RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.huntId | String | The ID of the latest threat hunt. | +| RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.huntStartTime | Date | The timestamp of the latest threat hunt. | +| RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.isMalicious | String | Whether the latest threat hunt is malicious. | +| RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.huntId | String | The ID of the latest malicious threat hunt. | +| RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.huntStartTime | Date | The timestamp of the latest malicious threat hunt. | +| RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.isMalicious | String | Whether the latest malicious threat hunt is malicious. | +| RubrikPolaris.IP.threatHuntInfo.redirectLink | String | The link to the threat hunt information in the Rubrik UI. | +| RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.snapshotFid | String | The foreign ID of the latest threat monitoring snapshot. | +| RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.monitoringScanTime | Date | The timestamp of the latest threat monitoring scan. | +| RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.isMalicious | String | Whether the latest threat monitoring snapshot is malicious. | +| RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.snapshotFid | String | The foreign ID of the latest malicious threat monitoring snapshot. | +| RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.monitoringScanTime | Date | The timestamp of the latest malicious threat monitoring scan. | +| RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious | String | Whether the latest malicious threat monitoring snapshot is malicious. | +| RubrikPolaris.IP.threatMonitoringInfo.redirectLink | String | The link to the threat monitoring information in the Rubrik UI. | + +#### Command example +```!ip ip="0.0.0.1"``` +#### Context Example +```json +{ + "DBotScore": { + "Indicator": "0.0.0.1", + "Reliability": "A - Completely reliable", + "Score": 2, + "Type": "ip", + "Vendor": "Rubrik Security Cloud" + }, + "IP": { + "Address": "0.0.0.1", + "UpdatedDate": "2024-10-21T08:51:52Z" + }, + "RubrikPolaris": { + "IP": { + "ip": "0.0.0.1", + "generalInfo": { + "fid": "12345678-1234-1234-1234-123456789012", + "name": "DEMO-RADAR", + "objectType": "Vsphere Virtual Machine", + "protectionStatus": "Protected", + "lastSnapshot": "2024-10-18T06:02:25Z", + "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview" + }, + "sensitiveInfo": { + "riskLevel": "Medium", + "sensitiveFiles": { + "mediumCount": "11" + }, + "sensitiveHits": 2910, + "openAccessFiles": 6, + "staleFiles": 11, + "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse", + "policyNames": [ + "U.S. PII" + ] + }, + "anomalyInfo": { + "severity": "Critical", + "detectionTime": "2024-10-14T17:57:06Z", + "createdFileCount": "4487", + "deletedFileCount": "4477", + "modifiedFileCount": "32", + "suspiciousFileCount": "4476", + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary" + }, + "threatHuntInfo": { + "latestThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "latestMaliciousThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details" + }, + "threatMonitoringInfo": { + "latestThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-18T05:51:31Z", + "isMalicious": "No Matches" + }, + "latestMaliciousThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-14T04:41:15Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90" + } + } + } +} +``` + +#### Human Readable Output + +>### General Information for the given medium risk IP: 0.0.0.1 +>|Fid|Last Snapshot|Name|Object Type|Protection Status|Redirect Link| +>|---|---|---|---|---|---| +>| 12345678-1234-1234-1234-123456789012 | 2024-10-18T06:02:25Z | DEMO-RADAR | Vsphere Virtual Machine | Protected | [https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview](https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview) | +> +>### Sensitive Information +>|Open Access Files|Policy Names|Redirect Link|Risk Level|Sensitive Files|Sensitive Hits|Stale Files| +>|---|---|---|---|---|---|---| +>| 6 | U.S. PII | [https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse](https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse) | Medium | mediumCount: 11 | 2910 | 11 | +> +>### Anomaly Information +>|Created File Count|Deleted File Count|Detection Time|Modified File Count|Redirect Link|Severity|Suspicious File Count| +>|---|---|---|---|---|---|---| +>| 4487 | 4477 | 2024-10-14T17:57:06Z | 32 | [https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary](https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary) | Critical | 4476 | +> +>### Threat Hunt Information +>|Latest Malicious Threat Hunt|Latest Threat Hunt|Redirect Link| +>|---|---|---| +>| huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | [https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details](https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details) | +> +>### Threat Monitoring Information +>|Latest Malicious Threat Monitoring|Latest Threat Monitoring|Redirect Link| +>|---|---|---| +>| snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-14T04:41:15Z
isMalicious: Matches Found | snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matches | [https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90](https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90) | + + +### domain + +*** +Retrieve the sensitive information available for the given domain(s). + +#### Base Command + +`domain` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| domain | The domain(s) for which to retrieve sensitive information. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| DBotScore.Indicator | String | The indicator that was tested. | +| DBotScore.Type | String | The indicator type. | +| DBotScore.Vendor | String | The vendor used to calculate the score. | +| DBotScore.Score | Number | The actual score. | +| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. | +| Domain.Name | String | The domain name, for example: "google.com". | +| Domain.Relationships.EntityA | string | The source of the relationship. | +| Domain.Relationships.EntityB | string | The destination of the relationship. | +| Domain.Relationships.Relationship | string | The name of the relationship. | +| Domain.Relationships.EntityAType | string | The type of the source of the relationship. | +| Domain.Relationships.EntityBType | string | The type of the destination of the relationship. | +| Domain.DNS | String | A list of IP objects resolved by DNS. | +| Domain.DetectionEngines | Number | The total number of engines that checked the indicator. | +| Domain.PositiveDetections | Number | The number of engines that positively detected the indicator as malicious. | +| Domain.CreationDate | Date | The date that the domain was created. | +| Domain.UpdatedDate | String | The date that the domain was last updated. | +| Domain.ExpirationDate | Date | The expiration date of the domain. | +| Domain.DomainStatus | Datte | The status of the domain. | +| Domain.NameServers | Unknown | \(List<String>\) Name servers of the domain. | +| Domain.Organization | String | The organization of the domain. | +| Domain.Subdomains | Unknown | \(List<String>\) Subdomains of the domain. | +| Domain.Admin.Country | String | The country of the domain administrator. | +| Domain.Admin.Email | String | The email address of the domain administrator. | +| Domain.Admin.Name | String | The name of the domain administrator. | +| Domain.Admin.Phone | String | The phone number of the domain administrator. | +| Domain.Registrant.Country | String | The country of the registrant. | +| Domain.Registrant.Email | String | The email address of the registrant. | +| Domain.Registrant.Name | String | The name of the registrant. | +| Domain.Registrant.Phone | String | The phone number for receiving abuse reports. | +| Domain.Tags | Unknown | Tags of the domain. | +| Domain.FeedRelatedIndicators.value | String | Indicators that are associated with the domain. | +| Domain.FeedRelatedIndicators.type | String | The type of the indicators that are associated with the domain. | +| Domain.FeedRelatedIndicators.description | String | The description of the indicators that are associated with the domain. | +| Domain.MalwareFamily | String | The malware family associated with the domain. | +| Domain.WHOIS.DomainStatus | String | The status of the domain. | +| Domain.WHOIS.NameServers | String | \(List<String>\) Name servers of the domain. | +| Domain.WHOIS.CreationDate | Date | The date that the domain was created. | +| Domain.WHOIS.UpdatedDate | Date | The date that the domain was last updated. | +| Domain.WHOIS.ExpirationDate | Date | The expiration date of the domain. | +| Domain.WHOIS.Registrant.Name | String | The name of the registrant. | +| Domain.WHOIS.Registrant.Email | String | The email address of the registrant. | +| Domain.WHOIS.Registrant.Phone | String | The phone number of the registrant. | +| Domain.WHOIS.Registrar.Name | String | The name of the registrar, for example: "GoDaddy". | +| Domain.WHOIS.Registrar.AbuseEmail | String | The email address of the contact for reporting abuse. | +| Domain.WHOIS.Registrar.AbusePhone | String | The phone number of contact for reporting abuse. | +| Domain.WHOIS.Admin.Name | String | The name of the domain administrator. | +| Domain.WHOIS.Admin.Email | String | The email address of the domain administrator. | +| Domain.WHOIS.Admin.Phone | String | The phone number of the domain administrator. | +| Domain.WHOIS/History | String | List of Whois objects. | +| 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. | +| Domain.DomainIDNName | String | The internationalized domain name \(IDN\) of the domain. | +| Domain.Port | String | Ports that are associated with the domain. | +| Domain.Internal | Bool | Whether or not the domain is internal or external. | +| Domain.Category | String | The category associated with the indicator. | +| Domain.Campaign | String | The campaign associated with the domain. | +| Domain.TrafficLightProtocol | String | The Traffic Light Protocol \(TLP\) color that is suitable for the domain. | +| Domain.ThreatTypes.threatcategory | String | The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. | +| Domain.ThreatTypes.threatcategoryconfidence | String | Threat Category Confidence is the confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. | +| Domain.Geo.Location | String | The geolocation where the domain address is located, in the format: latitude:longitude. | +| Domain.Geo.Country | String | The country in which the domain address is located. | +| Domain.Geo.Description | String | Additional information about the location. | +| Domain.Tech.Country | String | The country of the domain technical contact. | +| Domain.Tech.Name | String | The name of the domain technical contact. | +| Domain.Tech.Organization | String | The organization of the domain technical contact. | +| Domain.Tech.Email | String | The email address of the domain technical contact. | +| Domain.CommunityNotes.note | String | Notes on the domain that were given by the community. | +| Domain.CommunityNotes.timestamp | Date | The time in which the note was published. | +| Domain.Publications.source | String | The source in which the article was published. | +| Domain.Publications.title | String | The name of the article. | +| Domain.Publications.link | String | A link to the original article. | +| Domain.Publications.timestamp | Date | The time in which the article was published. | +| Domain.Billing | String | The billing address of the domain. | +| RubrikPolaris.Domain.domain | String | The domain of the object. | +| RubrikPolaris.Domain.generalInfo.fid | String | The foreign ID of the object. | +| RubrikPolaris.Domain.generalInfo.name | String | The name of the object. | +| RubrikPolaris.Domain.generalInfo.objectType | String | The type of the object. | +| RubrikPolaris.Domain.generalInfo.protectionStatus | String | The protection status of the object. | +| RubrikPolaris.Domain.generalInfo.lastSnapshot | Date | The timestamp of the last snapshot of the object. | +| RubrikPolaris.Domain.generalInfo.redirectLink | String | The link to the object in the Rubrik UI. | +| RubrikPolaris.Domain.sensitiveInfo.riskLevel | String | The risk level of the object. | +| RubrikPolaris.Domain.sensitiveInfo.sensitiveFiles.mediumCount | String | The number of sensitive files of medium risk level. | +| RubrikPolaris.Domain.sensitiveInfo.sensitiveHits | Number | The number of sensitive files. | +| RubrikPolaris.Domain.sensitiveInfo.openAccessFiles | Number | The number of open access files. | +| RubrikPolaris.Domain.sensitiveInfo.staleFiles | Number | The number of stale files. | +| RubrikPolaris.Domain.sensitiveInfo.redirectLink | String | The link to the sensitive information in the Rubrik UI. | +| RubrikPolaris.Domain.sensitiveInfo.policyNames | String | The names of the policies associated with the object. | +| RubrikPolaris.Domain.anomalyInfo.severity | String | The severity of the anomaly. | +| RubrikPolaris.Domain.anomalyInfo.detectionTime | Date | The timestamp of the anomaly detection. | +| RubrikPolaris.Domain.anomalyInfo.createdFileCount | String | The number of created files. | +| RubrikPolaris.Domain.anomalyInfo.deletedFileCount | String | The number of deleted files. | +| RubrikPolaris.Domain.anomalyInfo.modifiedFileCount | String | The number of modified files. | +| RubrikPolaris.Domain.anomalyInfo.suspiciousFileCount | String | The number of suspicious files. | +| RubrikPolaris.Domain.anomalyInfo.redirectLink | String | The link to the anomaly information in the Rubrik UI. | +| RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.huntId | String | The ID of the latest threat hunt. | +| RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.huntStartTime | Date | The timestamp of the latest threat hunt. | +| RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.isMalicious | String | Whether the latest threat hunt is malicious. | +| RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.huntId | String | The ID of the latest malicious threat hunt. | +| RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.huntStartTime | Date | The timestamp of the latest malicious threat hunt. | +| RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.isMalicious | String | Whether the latest malicious threat hunt is malicious. | +| RubrikPolaris.Domain.threatHuntInfo.redirectLink | String | The link to the threat hunt information in the Rubrik UI. | +| RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.snapshotFid | String | The foreign ID of the latest threat monitoring snapshot. | +| RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.monitoringScanTime | Date | The timestamp of the latest threat monitoring scan. | +| RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.isMalicious | String | Whether the latest threat monitoring snapshot is malicious. | +| RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.snapshotFid | String | The foreign ID of the latest malicious threat monitoring snapshot. | +| RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.monitoringScanTime | Date | The timestamp of the latest malicious threat monitoring scan. | +| RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious | String | Whether the latest malicious threat monitoring snapshot is malicious. | +| RubrikPolaris.Domain.threatMonitoringInfo.redirectLink | String | The link to the threat monitoring information in the Rubrik UI. | + +#### Command example +```!domain domain="DEMO-RADAR" using-brand=RubrikPolaris``` +#### Context Example +```json +{ + "DBotScore": { + "Indicator": "DEMO-RADAR", + "Reliability": "A - Completely reliable", + "Score": 2, + "Type": "domain", + "Vendor": "Rubrik Security Cloud" + }, + "Domain": { + "Name": "DEMO-RADAR", + "UpdatedDate": "2024-11-05T04:34:47Z", + "WHOIS": { + "UpdatedDate": "2024-11-05T04:34:47Z" + } + }, + "RubrikPolaris": { + "Domain": { + "domain": "DEMO-RADAR", + "generalInfo": { + "fid": "12345678-1234-1234-1234-123456789012", + "name": "DEMO-RADAR", + "objectType": "Vsphere Virtual Machine", + "protectionStatus": "Protected", + "lastSnapshot": "2024-10-18T06:02:25Z", + "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview" + }, + "anomalyInfo": { + "severity": "Critical", + "detectionTime": "2024-10-14T17:57:06Z", + "createdFileCount": "4487", + "deletedFileCount": "4477", + "modifiedFileCount": "32", + "suspiciousFileCount": "4476", + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary" + }, + "sensitiveInfo": { + "riskLevel": "Medium", + "sensitiveFiles": { + "mediumCount": "11" + }, + "sensitiveHits": 2910, + "openAccessFiles": 6, + "staleFiles": 11, + "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse", + "policyNames": [ + "U.S. PII" + ] + }, + "threatHuntInfo": { + "latestThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "latestMaliciousThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details" + }, + "threatMonitoringInfo": { + "latestThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-18T05:51:31Z", + "isMalicious": "No Matches" + }, + "latestMaliciousThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-14T04:41:15Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90" + } + } + } +} +``` + +#### Human Readable Output + +>### General Information for the given medium risk domain: DEMO-RADAR +>|Fid|Last Snapshot|Name|Object Type|Protection Status|Redirect Link| +>|---|---|---|---|---|---| +>| 12345678-1234-1234-1234-123456789012 | 2024-10-18T06:02:25Z | DEMO-RADAR | Vsphere Virtual Machine | Protected | [https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview](https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview) | +> +### Sensitive Information +>|Open Access Files|Policy Names|Redirect Link|Risk Level|Sensitive Files|Sensitive Hits|Stale Files| +>|---|---|---|---|---|---|---| +>| 6 | U.S. PII | [https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse](https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse) | Medium | mediumCount: 11 | 2910 | 11 | +> +>### Anomaly Information +>|Created File Count|Deleted File Count|Detection Time|Modified File Count|Redirect Link|Severity|Suspicious File Count| +>|---|---|---|---|---|---|---| +>| 4487 | 4477 | 2024-10-14T17:57:06Z | 32 | [https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary](https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary) | Critical | 4476 | +> +>### Threat Hunt Information +>|Latest Malicious Threat Hunt|Latest Threat Hunt|Redirect Link| +>|---|---|---| +>| huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | [https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details](https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details) | +> +>### Threat Monitoring Information +>|Latest Malicious Threat Monitoring|Latest Threat Monitoring|Redirect Link| +>|---|---|---| +>| snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-14T04:41:15Z
isMalicious: Matches Found | snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matches | [https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90](https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90) | diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.py b/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.py index 7ab50c8d381b..f0e61726d40f 100644 --- a/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.py +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.py @@ -1,3 +1,4 @@ +from typing import Tuple import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 """Main file for RubrikPolaris Integration.""" @@ -45,6 +46,7 @@ DEFAULT_CLUSTER_SORT_BY = "ClusterName" DEFAULT_REQUEST_NAME = f"PAXSOAR-{get_pack_version(pack_name='') or '1.2.0'}" DEFAULT_PRINCIPAL_SUMMARY_CATEGORY = "USERS_WITH_SENSITIVE_ACCESS" +DEFAULT_RELIABILITY = "A - Completely reliable" SCAN_ID = "Scan ID" SNAPSHOT_ID = "Snapshot ID" START_TIME = "Start Time" @@ -95,6 +97,12 @@ MEDIUM_RISK_HITS = "Medium Risk Hits" LOW_RISK_HITS = "Low Risk Hits" POLICY_NAME = "Policy Name" +VENDOR_NAME = "Rubrik Security Cloud" +GENERAL_INFO_KEY = "generalInfo" +SENSITIVE_INFO_KEY = "sensitiveInfo" +ANOMALY_INFO_KEY = "anomalyInfo" +THREAT_HUNT_INFO_KEY = "threatHuntInfo" +THREAT_MONITORING_INFO_KEY = "threatMonitoringInfo" DAILY_HITS_CHANGE = "Daily Hits Change" START_CURSOR = "Start Cursor" @@ -113,7 +121,10 @@ 'NEXT_PAGE_TOKEN': ('Note: To retrieve the next set of results, use **next_page_token** = "{}".' '\nIf **next_page_token** is provided, then it will reset the record numbers. ' 'For the initial use of **next_page_token**, please avoid specifying the **page_number**.'), - 'NO_RESPONSE': "No response was returned for the given argument(s)." + 'NO_RESPONSE': "No response was returned for the given argument(s).", + 'IP_NOT_FOUND': "No details found for IP: \"{}\".", + 'DOMAIN_NOT_FOUND': "No details found for domain: \"{}\".", + 'NO_OBJECT_FOUND': "No Objects Found", } OUTPUT_PREFIX = { @@ -152,6 +163,8 @@ "FILE_CONTEXT": "RubrikPolaris.FileContext", "PAGE_TOKEN_FILE_CONTEXT": "RubrikPolaris.PageToken.FileContext", "SUSPICIOUS_FILE": "RubrikPolaris.SuspiciousFile", + "IP": "RubrikPolaris.IP", + "DOMAIN": "RubrikPolaris.Domain", } ERROR_MESSAGES = { @@ -182,6 +195,14 @@ "IP_ADDRESS_REQUIRED": "IP Address is required for fetching snapshot files download results command" } +DBOT_SCORE_MAPPING = { + 'unknown': 0, # Unknown + 'no risk': 1, # Good + 'low': 1, # Good + 'medium': 2, # Suspicious + 'high': 3 # Bad +} + TOKEN_EXPIRY_TIME_SPAN = 86400 TOKEN_EXPIRY_BUFFER_TIME = 30 @@ -2092,6 +2113,92 @@ def prepare_context_hr_suspicious_file_list(snappable_investigations_data: dict, return context, f"{anomaly_hr}\n\n{suspicious_file_hr}" +def prepare_score_and_hr_for_reputation_command(response: dict, indicator_value: str, indicator_type: str) -> tuple[int, str]: + """ + Prepare severity score and human-readable response for generic reputation command. + + :type response: ``dict`` + :param response: IP response received from the API. + + :type indicator_value: ``str`` + :param indicator_value: Indicator value. + + :type indicator_type: ``str`` + :param indicator_type: Indicator type. + + :return: Severity score and human-readable for the command. + """ + sensitive_info = response.get(SENSITIVE_INFO_KEY, {}) + severity_str = sensitive_info.get('riskLevel', 'unknown').lower() + if 'none' in severity_str: + severity_str = 'unknown' + severity_score: int = DBOT_SCORE_MAPPING.get(severity_str, 0) + general_info = response.get(GENERAL_INFO_KEY, {}) + severity_str = severity_str.replace(' risk', '') + human_readable = tableToMarkdown(f'General Information for the given {severity_str} risk {indicator_type}: {indicator_value}', + general_info, removeNull=True, headerTransform=header_transform_to_title_case, + url_keys=["redirectLink"]) + human_readable += '\n' + tableToMarkdown( + 'Sensitive Information', sensitive_info, headerTransform=header_transform_to_title_case, + removeNull=True, url_keys=["redirectLink"]) if sensitive_info else '' + anomalies_info = response.get(ANOMALY_INFO_KEY, {}) + human_readable += '\n' + tableToMarkdown( + 'Anomaly Information', anomalies_info, + headerTransform=header_transform_to_title_case, removeNull=True, url_keys=["redirectLink"]) if anomalies_info else '' + threat_hunt_info = response.get(THREAT_HUNT_INFO_KEY, {}) + human_readable += '\n' + tableToMarkdown( + 'Threat Hunt Information', threat_hunt_info, + headerTransform=header_transform_to_title_case, removeNull=True, url_keys=["redirectLink"]) if threat_hunt_info else '' + threat_monitoring_info = response.get(THREAT_MONITORING_INFO_KEY, {}) + human_readable += '\n' + tableToMarkdown( + 'Threat Monitoring Information', threat_monitoring_info, headerTransform=header_transform_to_title_case, + removeNull=True, url_keys=["redirectLink"]) if threat_monitoring_info else '' + + return severity_score, human_readable + + +def header_transform_to_title_case(string: str) -> str: + ''' + Header transform function to convert given string to title case with the spaces between words. + + :type string: ``str`` + :param string: The string to convert to title case. + + :return: The string in title case. + ''' + new_string = [] + for j, i in enumerate(string): + if j == 0: + new_string.append(i.upper()) + elif string[j - 1].islower() and string[j].isupper(): + new_string.append(' ' + i.upper()) + else: + new_string.append(i) + return ''.join(new_string) + + +def validate_ip_addresses(ips_list: List[str]) -> Tuple[List[str], List[str]]: + ''' + Given a list of IP addresses, returns the invalid and valid ips. + + :type ips_list: ``List[str]`` + :param ips_list: List of ip addresses. + + :return: invalid_ip_addresses and valid_ip_addresses. + :rtype: ``Tuple[List[str], List[str]]`` + ''' + invalid_ip_addresses = [] + valid_ip_addresses = [] + for ip in ips_list: + ip = ip.strip().strip('\"') + if ip: + if is_ip_valid(ip, accept_v6_ips=True): + valid_ip_addresses.append(ip) + else: + invalid_ip_addresses.append(ip) + return invalid_ip_addresses, valid_ip_addresses + + ''' COMMAND FUNCTIONS ''' @@ -4012,6 +4119,154 @@ def rubrik_radar_suspicious_file_list_command(client: PolarisClient, args: Dict[ return CommandResults(outputs=outputs, raw_response=raw_response, readable_output=hr) +def ip_command(client: PolarisClient, args: Dict[str, Any]) -> List[CommandResults]: + ''' + Retrieve the detail information of given ip(s). + + :type client: ``Client`` + :param client: Object of Client class. + + :type args: ``Dict[str, Any]`` + :param args: Arguments provided by user. + + :rtype: ``List[CommandResults]`` + :return: List of standard command result. + ''' + ips_list = argToList(args.get('ip')) + ips = [ip for ip in ips_list if ip.strip()] + + if not ips: + raise ValueError(ERROR_MESSAGES['MISSING_REQUIRED_FIELD'].format('ip')) + + invalid_ips, valid_ips = validate_ip_addresses(ips) + if invalid_ips: + return_warning('The following IP Addresses were found invalid: {}'.format(', '.join(invalid_ips)), + exit=len(invalid_ips) == len(ips)) + + command_results = [] + + for ip in valid_ips: + raw_resp = requests.get( + "{}/thirdparty/workload_summary".format(client._baseurl), + params={"search_string": ip, "search_type": "ipv6" if is_ipv6_valid(ip) else "ipv4"}, + headers=client.prepare_headers(), + verify=client._verify, + proxies=client._proxies, + timeout=60 + ) + raw_resp.raise_for_status() + response = raw_resp.json() + + if MESSAGES["NO_OBJECT_FOUND"] in response.get(GENERAL_INFO_KEY, {}).get("fid", MESSAGES["NO_OBJECT_FOUND"]): + return_warning(MESSAGES["IP_NOT_FOUND"].format(ip)) + continue + + ip_response = deepcopy(response) + ip_response = remove_empty_elements(ip_response) + severity_score, ip_hr_output = prepare_score_and_hr_for_reputation_command(ip_response, ip, "IP") + ip_response["ip"] = ip + + dbot_score = Common.DBotScore( + indicator=ip, + indicator_type=DBotScoreType.IP, + integration_name=VENDOR_NAME, + score=severity_score, + reliability=demisto.params().get('integration_reliability', DEFAULT_RELIABILITY) + ) + dbot_score.integration_name = VENDOR_NAME + + ip_indicator = Common.IP( + ip=ip, + updated_date=response.get('threatMonitoringInfo', {}).get( + 'latestThreatMonitoring', {}).get('monitoringScanTime'), + dbot_score=dbot_score, + ) + + command_result = CommandResults( + outputs_prefix=OUTPUT_PREFIX['IP'], + outputs_key_field='ip', + outputs=ip_response, + raw_response=response, + readable_output=ip_hr_output, + indicator=ip_indicator, + ) + + command_results.append(command_result) + + return command_results + + +def domain_command(client: PolarisClient, args: Dict[str, Any]) -> List[CommandResults]: + ''' + Retrieve the detail information of given domain(s). + + :type client: ``Client`` + :param client: Object of Client class. + + :type args: ``Dict[str, Any]`` + :param args: Arguments provided by user. + + :rtype: ``List[CommandResults]`` + :return: List of standard command result. + ''' + domain_list = argToList(args.get('domain')) + domains = [domain for domain in domain_list if domain.strip()] + + if not domains: + raise ValueError(ERROR_MESSAGES['MISSING_REQUIRED_FIELD'].format('domain')) + command_results = [] + + for domain in domains: + raw_resp = requests.get( + "{}/thirdparty/workload_summary".format(client._baseurl), + params={"search_string": domain, "search_type": "name"}, + headers=client.prepare_headers(), + verify=client._verify, + proxies=client._proxies, + timeout=60 + ) + raw_resp.raise_for_status() + response = raw_resp.json() + + if MESSAGES["NO_OBJECT_FOUND"] in response.get(GENERAL_INFO_KEY, {}).get("fid", MESSAGES["NO_OBJECT_FOUND"]): + return_warning(MESSAGES["DOMAIN_NOT_FOUND"].format(domain)) + continue + + domain_response = deepcopy(response) + domain_response = remove_empty_elements(domain_response) + severity_score, domain_hr_output = prepare_score_and_hr_for_reputation_command(domain_response, domain, "domain") + domain_response["domain"] = domain + + dbot_score = Common.DBotScore( + indicator=domain, + indicator_type=DBotScoreType.DOMAIN, + integration_name=VENDOR_NAME, + score=severity_score, + reliability=demisto.params().get('integration_reliability', DEFAULT_RELIABILITY) + ) + dbot_score.integration_name = VENDOR_NAME + + domain_indicator = Common.Domain( + domain=domain, + updated_date=response.get('threatMonitoringInfo', {}).get( + 'latestThreatMonitoring', {}).get('monitoringScanTime'), + dbot_score=dbot_score, + ) + + command_result = CommandResults( + outputs_prefix=OUTPUT_PREFIX['DOMAIN'], + outputs_key_field='domain', + outputs=domain_response, + raw_response=response, + readable_output=domain_hr_output, + indicator=domain_indicator, + ) + + command_results.append(command_result) + + return command_results + + def trim_spaces_from_args(args): """ Trim spaces from values of the args dict. @@ -4140,6 +4395,8 @@ def main() -> None: "rubrik-sonar-user-access-get": rubrik_sonar_user_access_get_command, "rubrik-sonar-file-context-list": rubrik_sonar_file_context_list_command, "rubrik-radar-suspicious-file-list": rubrik_radar_suspicious_file_list_command, + "ip": ip_command, + "domain": domain_command, } if COMMAND_TO_FUNCTION.get(demisto.command()): args = demisto.args() diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.yml b/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.yml index 1cf05eae59a4..d95aff9e010a 100644 --- a/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.yml +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris.yml @@ -58,6 +58,20 @@ configuration: - XSOAR LOW type: 15 required: false +- name: integration_reliability + display: Source Reliability + additionalinfo: Reliability of the source providing the intelligence data. + defaultvalue: A - Completely reliable + options: + - A+ - 3rd party enrichment + - A - Completely reliable + - B - Usually reliable + - C - Fairly reliable + - D - Not usually reliable + - E - Unreliable + - F - Reliability cannot be judged + required: false + type: 15 - additionalinfo: Whether to use XSOAR's system proxy settings to connect to the API. display: Use system proxy settings name: proxy @@ -3060,7 +3074,598 @@ script: - contextPath: RubrikPolaris.SuspiciousFile.__typename description: 'The type name of the suspicious file response.' type: String - dockerimage: demisto/rubrik-polaris-sdk-py3:1.0.0.108068 + - name: ip + description: Retrieve the sensitive information available for the given IP address(es). + arguments: + - name: ip + description: The IP address(es) for which to retrieve sensitive information. + required: true + isArray: true + default: true + outputs: + - contextPath: DBotScore.Indicator + description: The indicator that was tested. + type: String + - contextPath: DBotScore.Type + description: The indicator type. + type: String + - contextPath: DBotScore.Vendor + description: The vendor used to calculate the score. + type: String + - contextPath: DBotScore.Score + description: The actual score. + type: Number + - contextPath: DBotScore.Reliability + description: Reliability of the source providing the intelligence data. + type: String + - contextPath: IP.Address + description: IP address. + type: String + - contextPath: IP.Relationships.EntityA + description: The source of the relationship. + type: String + - contextPath: IP.Relationships.EntityB + description: The destination of the relationship. + type: String + - contextPath: IP.Relationships.Relationship + description: The name of the relationship. + type: String + - contextPath: IP.Relationships.EntityAType + description: The type of the source of the relationship. + type: String + - contextPath: IP.Relationships.EntityBType + description: The type of the destination of the relationship. + type: String + - contextPath: IP.ASN + description: 'The autonomous system name for the IP address, for example: "AS8948".' + type: String + - contextPath: IP.Hostname + description: The hostname that is mapped to this IP address. + type: String + - contextPath: IP.Geo.Location + description: 'The geolocation where the IP address is located, in the format: latitude:longitude.' + type: String + - contextPath: IP.Geo.Country + description: The country in which the IP address is located. + type: String + - contextPath: IP.Geo.Description + description: Additional information about the location. + type: String + - contextPath: IP.DetectionEngines + description: The total number of engines that checked the indicator. + type: Number + - contextPath: IP.PositiveDetections + description: The number of engines that positively detected the indicator as malicious. + type: Number + - contextPath: IP.Malicious.Vendor + description: The vendor reporting the IP address as malicious. + type: String + - contextPath: IP.Malicious.Description + description: A description explaining why the IP address was reported as malicious. + type: String + - contextPath: IP.Tags + description: Tags of the IP address. + type: Unknown + - contextPath: IP.FeedRelatedIndicators.value + description: Indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.type + description: The type of the indicators that are associated with the IP address. + type: String + - contextPath: IP.FeedRelatedIndicators.description + description: The description of the indicators that are associated with the IP address. + type: String + - contextPath: IP.MalwareFamily + description: The malware family associated with the IP address. + type: String + - contextPath: IP.Organization.Name + description: The organization of the IP address. + type: String + - contextPath: IP.Organization.Type + description: The organization type of the IP address. + type: String + - contextPath: IP.ASOwner + description: The autonomous system owner of the IP address. + type: String + - contextPath: IP.Region + description: The region in which the IP address is located. + type: String + - contextPath: IP.Port + description: Ports that are associated with the IP address. + type: String + - contextPath: IP.Internal + description: Whether the IP address is internal or external. + type: Boolean + - contextPath: IP.UpdatedDate + description: The date that the IP address was last updated. + type: Date + - contextPath: IP.Registrar.Abuse.Name + description: The name of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Address + description: The address of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Country + description: The country of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Network + description: The network of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Phone + description: The phone number of the contact for reporting abuse. + type: String + - contextPath: IP.Registrar.Abuse.Email + description: The email address of the contact for reporting abuse. + type: String + - contextPath: IP.Campaign + description: The campaign associated with the IP address. + type: String + - contextPath: IP.TrafficLightProtocol + description: The Traffic Light Protocol (TLP) color that is suitable for the IP address. + type: String + - contextPath: IP.CommunityNotes.note + description: Notes on the IP address that were given by the community. + type: String + - contextPath: IP.CommunityNotes.timestamp + description: The time in which the note was published. + type: Date + - contextPath: IP.Publications.source + description: The source in which the article was published. + type: String + - contextPath: IP.Publications.title + description: The name of the article. + type: String + - contextPath: IP.Publications.link + description: A link to the original article. + type: String + - contextPath: IP.Publications.timestamp + description: The time in which the article was published. + type: Date + - contextPath: IP.ThreatTypes.threatcategory + description: The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. + type: String + - contextPath: IP.ThreatTypes.threatcategoryconfidence + description: The confidence level provided by the vendor for the threat type category For example, a confidence of 90 for the threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. + type: String + - contextPath: RubrikPolaris.IP.ip + description: 'IP address of the object.' + type: String + - contextPath: RubrikPolaris.IP.generalInfo.fid + description: 'The foreign ID of the object.' + type: String + - contextPath: RubrikPolaris.IP.generalInfo.name + description: 'The name of the object.' + type: String + - contextPath: RubrikPolaris.IP.generalInfo.objectType + description: 'The type of the object.' + type: String + - contextPath: RubrikPolaris.IP.generalInfo.protectionStatus + description: 'The protection status of the object.' + type: String + - contextPath: RubrikPolaris.IP.generalInfo.lastSnapshot + description: 'The timestamp of the last snapshot of the object.' + type: Date + - contextPath: RubrikPolaris.IP.generalInfo.redirectLink + description: 'The link to the object in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.IP.sensitiveInfo.riskLevel + description: 'The risk level of the object.' + type: String + - contextPath: RubrikPolaris.IP.sensitiveInfo.sensitiveFiles.mediumCount + description: 'The number of sensitive files of medium risk level.' + type: String + - contextPath: RubrikPolaris.IP.sensitiveInfo.sensitiveHits + description: 'The number of sensitive files.' + type: Number + - contextPath: RubrikPolaris.IP.sensitiveInfo.openAccessFiles + description: 'The number of open access files.' + type: Number + - contextPath: RubrikPolaris.IP.sensitiveInfo.staleFiles + description: 'The number of stale files.' + type: Number + - contextPath: RubrikPolaris.IP.sensitiveInfo.redirectLink + description: 'The link to the sensitive information in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.IP.sensitiveInfo.policyNames + description: 'The names of the policies associated with the object.' + type: String + - contextPath: RubrikPolaris.IP.anomalyInfo.severity + description: 'The severity of the anomaly.' + type: String + - contextPath: RubrikPolaris.IP.anomalyInfo.detectionTime + description: 'The timestamp of the anomaly detection.' + type: Date + - contextPath: RubrikPolaris.IP.anomalyInfo.createdFileCount + description: 'The number of created files.' + type: String + - contextPath: RubrikPolaris.IP.anomalyInfo.deletedFileCount + description: 'The number of deleted files.' + type: String + - contextPath: RubrikPolaris.IP.anomalyInfo.modifiedFileCount + description: 'The number of modified files.' + type: String + - contextPath: RubrikPolaris.IP.anomalyInfo.suspiciousFileCount + description: 'The number of suspicious files.' + type: String + - contextPath: RubrikPolaris.IP.anomalyInfo.redirectLink + description: 'The link to the anomaly information in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.huntId + description: 'The ID of the latest threat hunt.' + type: String + - contextPath: RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.huntStartTime + description: 'The timestamp of the latest threat hunt.' + type: Date + - contextPath: RubrikPolaris.IP.threatHuntInfo.latestThreatHunt.isMalicious + description: 'Whether the latest threat hunt is malicious.' + type: String + - contextPath: RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.huntId + description: 'The ID of the latest malicious threat hunt.' + type: String + - contextPath: RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.huntStartTime + description: 'The timestamp of the latest malicious threat hunt.' + type: Date + - contextPath: RubrikPolaris.IP.threatHuntInfo.latestMaliciousThreatHunt.isMalicious + description: 'Whether the latest malicious threat hunt is malicious.' + type: String + - contextPath: RubrikPolaris.IP.threatHuntInfo.redirectLink + description: 'The link to the threat hunt information in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.snapshotFid + description: 'The foreign ID of the latest threat monitoring snapshot.' + type: String + - contextPath: RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.monitoringScanTime + description: 'The timestamp of the latest threat monitoring scan.' + type: Date + - contextPath: RubrikPolaris.IP.threatMonitoringInfo.latestThreatMonitoring.isMalicious + description: 'Whether the latest threat monitoring snapshot is malicious.' + type: String + - contextPath: RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.snapshotFid + description: 'The foreign ID of the latest malicious threat monitoring snapshot.' + type: String + - contextPath: RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.monitoringScanTime + description: 'The timestamp of the latest malicious threat monitoring scan.' + type: Date + - contextPath: RubrikPolaris.IP.threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious + description: 'Whether the latest malicious threat monitoring snapshot is malicious.' + type: String + - contextPath: RubrikPolaris.IP.threatMonitoringInfo.redirectLink + description: 'The link to the threat monitoring information in the Rubrik UI.' + type: String + - name: domain + description: Retrieve the sensitive information available for the given domain(s). + arguments: + - name: domain + description: The domain(s) for which to retrieve sensitive information. + required: true + isArray: true + default: true + outputs: + - contextPath: DBotScore.Indicator + description: The indicator that was tested. + type: String + - contextPath: DBotScore.Type + description: The indicator type. + type: String + - contextPath: DBotScore.Vendor + description: The vendor used to calculate the score. + type: String + - contextPath: DBotScore.Score + description: The actual score. + type: Number + - contextPath: DBotScore.Reliability + description: Reliability of the source providing the intelligence data. + type: String + - contextPath: Domain.Name + description: 'The domain name, for example: "google.com".' + type: String + - contextPath: Domain.Relationships.EntityA + description: The source of the relationship. + type: string + - contextPath: Domain.Relationships.EntityB + description: The destination of the relationship. + type: string + - contextPath: Domain.Relationships.Relationship + description: The name of the relationship. + type: string + - contextPath: Domain.Relationships.EntityAType + description: The type of the source of the relationship. + type: string + - contextPath: Domain.Relationships.EntityBType + description: The type of the destination of the relationship. + type: string + - contextPath: Domain.DNS + description: A list of IP objects resolved by DNS. + type: String + - contextPath: Domain.DetectionEngines + description: The total number of engines that checked the indicator. + type: Number + - contextPath: Domain.PositiveDetections + description: The number of engines that positively detected the indicator as malicious. + type: Number + - contextPath: Domain.CreationDate + description: The date that the domain was created. + type: Date + - contextPath: Domain.UpdatedDate + description: The date that the domain was last updated. + type: String + - contextPath: Domain.ExpirationDate + description: The expiration date of the domain. + type: Date + - contextPath: Domain.DomainStatus + description: The status of the domain. + type: Datte + - contextPath: Domain.NameServers + description: (List) Name servers of the domain. + type: Unknown + - contextPath: Domain.Organization + description: The organization of the domain. + type: String + - contextPath: Domain.Subdomains + description: (List) Subdomains of the domain. + type: Unknown + - contextPath: Domain.Admin.Country + description: The country of the domain administrator. + type: String + - contextPath: Domain.Admin.Email + description: The email address of the domain administrator. + type: String + - contextPath: Domain.Admin.Name + description: The name of the domain administrator. + type: String + - contextPath: Domain.Admin.Phone + description: The phone number of the domain administrator. + type: String + - contextPath: Domain.Registrant.Country + description: The country of the registrant. + type: String + - contextPath: Domain.Registrant.Email + description: The email address of the registrant. + type: String + - contextPath: Domain.Registrant.Name + description: The name of the registrant. + type: String + - contextPath: Domain.Registrant.Phone + description: The phone number for receiving abuse reports. + type: String + - contextPath: Domain.Tags + description: Tags of the domain. + type: Unknown + - contextPath: Domain.FeedRelatedIndicators.value + description: Indicators that are associated with the domain. + type: String + - contextPath: Domain.FeedRelatedIndicators.type + description: The type of the indicators that are associated with the domain. + type: String + - contextPath: Domain.FeedRelatedIndicators.description + description: The description of the indicators that are associated with the domain. + type: String + - contextPath: Domain.MalwareFamily + description: The malware family associated with the domain. + type: String + - contextPath: Domain.WHOIS.DomainStatus + description: The status of the domain. + type: String + - contextPath: Domain.WHOIS.NameServers + description: (List) Name servers of the domain. + type: String + - contextPath: Domain.WHOIS.CreationDate + description: The date that the domain was created. + type: Date + - contextPath: Domain.WHOIS.UpdatedDate + description: The date that the domain was last updated. + type: Date + - contextPath: Domain.WHOIS.ExpirationDate + description: The expiration date of the domain. + type: Date + - contextPath: Domain.WHOIS.Registrant.Name + description: The name of the registrant. + type: String + - contextPath: Domain.WHOIS.Registrant.Email + description: The email address of the registrant. + type: String + - contextPath: Domain.WHOIS.Registrant.Phone + description: The phone number of the registrant. + type: String + - contextPath: Domain.WHOIS.Registrar.Name + description: 'The name of the registrar, for example: "GoDaddy".' + type: String + - contextPath: Domain.WHOIS.Registrar.AbuseEmail + description: The email address of the contact for reporting abuse. + type: String + - contextPath: Domain.WHOIS.Registrar.AbusePhone + description: The phone number of contact for reporting abuse. + type: String + - contextPath: Domain.WHOIS.Admin.Name + description: The name of the domain administrator. + type: String + - contextPath: Domain.WHOIS.Admin.Email + description: The email address of the domain administrator. + type: String + - contextPath: Domain.WHOIS.Admin.Phone + description: The phone number of the domain administrator. + type: String + - contextPath: Domain.WHOIS/History + description: List of Whois objects. + type: String + - contextPath: Domain.Malicious.Vendor + description: The vendor reporting the domain as malicious. + type: String + - contextPath: Domain.Malicious.Description + description: A description explaining why the domain was reported as malicious. + type: String + - contextPath: Domain.DomainIDNName + description: The internationalized domain name (IDN) of the domain. + type: String + - contextPath: Domain.Port + description: Ports that are associated with the domain. + type: String + - contextPath: Domain.Internal + description: Whether or not the domain is internal or external. + type: Bool + - contextPath: Domain.Category + description: The category associated with the indicator. + type: String + - contextPath: Domain.Campaign + description: The campaign associated with the domain. + type: String + - contextPath: Domain.TrafficLightProtocol + description: The Traffic Light Protocol (TLP) color that is suitable for the domain. + type: String + - contextPath: Domain.ThreatTypes.threatcategory + description: The threat category associated to this indicator by the source vendor. For example, Phishing, Control, TOR, etc. + type: String + - contextPath: Domain.ThreatTypes.threatcategoryconfidence + description: Threat Category Confidence is the confidence level provided by the vendor for the threat type category For example a confidence of 90 for threat type category 'malware' means that the vendor rates that this is 90% confidence of being a malware. + type: String + - contextPath: Domain.Geo.Location + description: 'The geolocation where the domain address is located, in the format: latitude:longitude.' + type: String + - contextPath: Domain.Geo.Country + description: The country in which the domain address is located. + type: String + - contextPath: Domain.Geo.Description + description: Additional information about the location. + type: String + - contextPath: Domain.Tech.Country + description: The country of the domain technical contact. + type: String + - contextPath: Domain.Tech.Name + description: The name of the domain technical contact. + type: String + - contextPath: Domain.Tech.Organization + description: The organization of the domain technical contact. + type: String + - contextPath: Domain.Tech.Email + description: The email address of the domain technical contact. + type: String + - contextPath: Domain.CommunityNotes.note + description: Notes on the domain that were given by the community. + type: String + - contextPath: Domain.CommunityNotes.timestamp + description: The time in which the note was published. + type: Date + - contextPath: Domain.Publications.source + description: The source in which the article was published. + type: String + - contextPath: Domain.Publications.title + description: The name of the article. + type: String + - contextPath: Domain.Publications.link + description: A link to the original article. + type: String + - contextPath: Domain.Publications.timestamp + description: The time in which the article was published. + type: Date + - contextPath: Domain.Billing + description: The billing address of the domain. + type: String + - contextPath: RubrikPolaris.Domain.domain + description: 'The domain of the object.' + type: String + - contextPath: RubrikPolaris.Domain.generalInfo.fid + description: 'The foreign ID of the object.' + type: String + - contextPath: RubrikPolaris.Domain.generalInfo.name + description: 'The name of the object.' + type: String + - contextPath: RubrikPolaris.Domain.generalInfo.objectType + description: 'The type of the object.' + type: String + - contextPath: RubrikPolaris.Domain.generalInfo.protectionStatus + description: 'The protection status of the object.' + type: String + - contextPath: RubrikPolaris.Domain.generalInfo.lastSnapshot + description: 'The timestamp of the last snapshot of the object.' + type: Date + - contextPath: RubrikPolaris.Domain.generalInfo.redirectLink + description: 'The link to the object in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.Domain.sensitiveInfo.riskLevel + description: 'The risk level of the object.' + type: String + - contextPath: RubrikPolaris.Domain.sensitiveInfo.sensitiveFiles.mediumCount + description: 'The number of sensitive files of medium risk level.' + type: String + - contextPath: RubrikPolaris.Domain.sensitiveInfo.sensitiveHits + description: 'The number of sensitive files.' + type: Number + - contextPath: RubrikPolaris.Domain.sensitiveInfo.openAccessFiles + description: 'The number of open access files.' + type: Number + - contextPath: RubrikPolaris.Domain.sensitiveInfo.staleFiles + description: 'The number of stale files.' + type: Number + - contextPath: RubrikPolaris.Domain.sensitiveInfo.redirectLink + description: 'The link to the sensitive information in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.Domain.sensitiveInfo.policyNames + description: 'The names of the policies associated with the object.' + type: String + - contextPath: RubrikPolaris.Domain.anomalyInfo.severity + description: 'The severity of the anomaly.' + type: String + - contextPath: RubrikPolaris.Domain.anomalyInfo.detectionTime + description: 'The timestamp of the anomaly detection.' + type: Date + - contextPath: RubrikPolaris.Domain.anomalyInfo.createdFileCount + description: 'The number of created files.' + type: String + - contextPath: RubrikPolaris.Domain.anomalyInfo.deletedFileCount + description: 'The number of deleted files.' + type: String + - contextPath: RubrikPolaris.Domain.anomalyInfo.modifiedFileCount + description: 'The number of modified files.' + type: String + - contextPath: RubrikPolaris.Domain.anomalyInfo.suspiciousFileCount + description: 'The number of suspicious files.' + type: String + - contextPath: RubrikPolaris.Domain.anomalyInfo.redirectLink + description: 'The link to the anomaly information in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.huntId + description: 'The ID of the latest threat hunt.' + type: String + - contextPath: RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.huntStartTime + description: 'The timestamp of the latest threat hunt.' + type: Date + - contextPath: RubrikPolaris.Domain.threatHuntInfo.latestThreatHunt.isMalicious + description: 'Whether the latest threat hunt is malicious.' + type: String + - contextPath: RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.huntId + description: 'The ID of the latest malicious threat hunt.' + type: String + - contextPath: RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.huntStartTime + description: 'The timestamp of the latest malicious threat hunt.' + type: Date + - contextPath: RubrikPolaris.Domain.threatHuntInfo.latestMaliciousThreatHunt.isMalicious + description: 'Whether the latest malicious threat hunt is malicious.' + type: String + - contextPath: RubrikPolaris.Domain.threatHuntInfo.redirectLink + description: 'The link to the threat hunt information in the Rubrik UI.' + type: String + - contextPath: RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.snapshotFid + description: 'The foreign ID of the latest threat monitoring snapshot.' + type: String + - contextPath: RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.monitoringScanTime + description: 'The timestamp of the latest threat monitoring scan.' + type: Date + - contextPath: RubrikPolaris.Domain.threatMonitoringInfo.latestThreatMonitoring.isMalicious + description: 'Whether the latest threat monitoring snapshot is malicious.' + type: String + - contextPath: RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.snapshotFid + description: 'The foreign ID of the latest malicious threat monitoring snapshot.' + type: String + - contextPath: RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.monitoringScanTime + description: 'The timestamp of the latest malicious threat monitoring scan.' + type: Date + - contextPath: RubrikPolaris.Domain.threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious + description: 'Whether the latest malicious threat monitoring snapshot is malicious.' + type: String + - contextPath: RubrikPolaris.Domain.threatMonitoringInfo.redirectLink + description: 'The link to the threat monitoring information in the Rubrik UI.' + type: String + dockerimage: demisto/rubrik-polaris-sdk-py3:1.0.0.117242 isfetch: true runonce: false script: '-' diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris_test.py b/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris_test.py index b013cd6a6cfe..10a7a4a5b9ba 100644 --- a/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris_test.py +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/RubrikPolaris_test.py @@ -46,6 +46,12 @@ def util_load_json(path): return json.loads(f.read()) +def util_load_text_data(path: str) -> str: + """Load a text file.""" + with open(path, mode='r', encoding='utf-8') as f: + return f.read() + + def test_main_incorrect_credentials(requests_mock, monkeypatch, capfd, caplog): """Tests the execution of main function when incorrect credentials are provided.""" from RubrikPolaris import main @@ -2803,3 +2809,97 @@ def test_rubrik_radar_suspicious_file_list_command_with_invalid_args(client, arg with pytest.raises(ValueError) as e: rubrik_radar_suspicious_file_list_command(client, args=args) assert str(e.value) == error + + +@patch('RubrikPolaris.return_warning') +def test_ip_command_success(mock_return, client, requests_mock, capfd): + ''' + Test case scenario for successful execution of ip_command. + + Given: + - mocked client. + When: + - Calling `ip_command` function. + Then: + - Returns CommandResult. + ''' + response = util_load_json('test_data/ip_command_success_response.json') + output = util_load_json('test_data/ip_command_success_output.json') + ip_hr = util_load_text_data('test_data/ip_command_success_hr.md') + ip_indicator = util_load_json('test_data/ip_indicator.json') + + requests_mock.get(f'{BASE_URL}/thirdparty/workload_summary?search_string=0.0.0.1&search_type=ipv4', + json=response, status_code=200) + requests_mock.get(f'{BASE_URL}/thirdparty/workload_summary?search_string=0.0.0.2&search_type=ipv4', json={}, status_code=200) + + args = {"ip": "0.0.0.1,0.0.0.2,0.0.0.256"} + + capfd.close() + from RubrikPolaris import ip_command + command_output = ip_command(client, args=args) + + assert MESSAGES["IP_NOT_FOUND"].format('0.0.0.2') == mock_return.call_args[0][0] + assert output == command_output[0].outputs + assert response == command_output[0].raw_response + assert ip_hr == command_output[0].readable_output + assert 'ip' == command_output[0].outputs_key_field + assert OUTPUT_PREFIX['IP'] == command_output[0].outputs_prefix + assert ip_indicator == command_output[0].indicator.to_context() + + +def test_ip_command_when_all_ips_invalid(client, capfd): + ''' + Test case scenario for the execution of ip_command with invalid ip addresses. + + Given: + - mocked client. + When: + - Calling `ip_command` function. + Then: + - Returns exception. + ''' + from RubrikPolaris import ip_command + + args = {'ip': '0: 0: 85a3: 0000: asv: 8a2e: 0370: 7334, 2.2.2'} + capfd.close() + with pytest.raises(SystemExit) as err: + ip_command(client, args) + + assert err.value.code == 0 + + +@patch('RubrikPolaris.return_warning') +def test_domain_command_success(mock_return, client, requests_mock, capfd): + ''' + Test case scenario for successful execution of domain_command. + + Given: + - mocked client. + When: + - Calling `domain_command` function. + Then: + - Returns CommandResult. + ''' + response = util_load_json('test_data/domain_command_success_response.json') + output = util_load_json('test_data/domain_command_success_output.json') + domain_hr = util_load_text_data('test_data/domain_command_success_hr.md') + domain_indicator = util_load_json('test_data/domain_indicator.json') + + requests_mock.get(f'{BASE_URL}/thirdparty/workload_summary?search_string=DEMO-RADAR&search_type=name', + json=response, status_code=200) + requests_mock.get(f'{BASE_URL}/thirdparty/workload_summary?search_string=DEMO-RADAR02&search_type=name', + json={}, status_code=200) + + args = {"domain": "DEMO-RADAR, ,DEMO-RADAR02"} + + capfd.close() + from RubrikPolaris import domain_command + command_output = domain_command(client, args=args) + + assert MESSAGES["DOMAIN_NOT_FOUND"].format('DEMO-RADAR02') == mock_return.call_args[0][0] + assert output == command_output[0].outputs + assert response == command_output[0].raw_response + assert domain_hr == command_output[0].readable_output + assert 'domain' == command_output[0].outputs_key_field + assert OUTPUT_PREFIX['DOMAIN'] == command_output[0].outputs_prefix + assert domain_indicator == command_output[0].indicator.to_context() diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_hr.md b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_hr.md new file mode 100644 index 000000000000..05335199c3c1 --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_hr.md @@ -0,0 +1,24 @@ +### General Information for the given medium risk domain: DEMO-RADAR +|Fid|Last Snapshot|Name|Object Type|Protection Status|Redirect Link| +|---|---|---|---|---|---| +| 12345678-1234-1234-1234-123456789012 | 2024-10-18T06:02:25Z | DEMO-RADAR | Vsphere Virtual Machine | Protected | [https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview](https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview) | + +### Sensitive Information +|Open Access Files|Policy Names|Redirect Link|Risk Level|Sensitive Files|Sensitive Hits|Stale Files| +|---|---|---|---|---|---|---| +| 6 | U.S. PII | [https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse](https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse) | Medium | mediumCount: 11 | 2910 | 11 | + +### Anomaly Information +|Created File Count|Deleted File Count|Detection Time|Modified File Count|Redirect Link|Severity|Suspicious File Count| +|---|---|---|---|---|---|---| +| 4487 | 4477 | 2024-10-14T17:57:06Z | 32 | [https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary](https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary) | Critical | 4476 | + +### Threat Hunt Information +|Latest Malicious Threat Hunt|Latest Threat Hunt|Redirect Link| +|---|---|---| +| huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | [https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details](https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details) | + +### Threat Monitoring Information +|Latest Malicious Threat Monitoring|Latest Threat Monitoring|Redirect Link| +|---|---|---| +| snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-14T04:41:15Z
isMalicious: Matches Found | snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matches | [https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90](https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90) | diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_output.json b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_output.json new file mode 100644 index 000000000000..5f345fe7ad58 --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_output.json @@ -0,0 +1,59 @@ +{ + "domain": "DEMO-RADAR", + "generalInfo": { + "fid": "12345678-1234-1234-1234-123456789012", + "name": "DEMO-RADAR", + "objectType": "Vsphere Virtual Machine", + "protectionStatus": "Protected", + "lastSnapshot": "2024-10-18T06:02:25Z", + "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview" + }, + "sensitiveInfo": { + "riskLevel": "Medium", + "sensitiveFiles": { + "mediumCount": "11" + }, + "sensitiveHits": 2910, + "openAccessFiles": 6, + "staleFiles": 11, + "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse", + "policyNames": [ + "U.S. PII" + ] + }, + "anomalyInfo": { + "severity": "Critical", + "detectionTime": "2024-10-14T17:57:06Z", + "createdFileCount": "4487", + "deletedFileCount": "4477", + "modifiedFileCount": "32", + "suspiciousFileCount": "4476", + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary" + }, + "threatHuntInfo": { + "latestThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "latestMaliciousThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details" + }, + "threatMonitoringInfo": { + "latestThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-18T05:51:31Z", + "isMalicious": "No Matches" + }, + "latestMaliciousThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-14T04:41:15Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90" + } +} \ No newline at end of file diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_response.json b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_response.json new file mode 100644 index 000000000000..65062b0a422c --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_command_success_response.json @@ -0,0 +1,58 @@ +{ + "generalInfo": { + "fid": "12345678-1234-1234-1234-123456789012", + "name": "DEMO-RADAR", + "objectType": "Vsphere Virtual Machine", + "protectionStatus": "Protected", + "lastSnapshot": "2024-10-18T06:02:25Z", + "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview" + }, + "sensitiveInfo": { + "riskLevel": "Medium", + "sensitiveFiles": { + "mediumCount": "11" + }, + "sensitiveHits": 2910, + "openAccessFiles": 6, + "staleFiles": 11, + "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse", + "policyNames": [ + "U.S. PII" + ] + }, + "anomalyInfo": { + "severity": "Critical", + "detectionTime": "2024-10-14T17:57:06Z", + "createdFileCount": "4487", + "deletedFileCount": "4477", + "modifiedFileCount": "32", + "suspiciousFileCount": "4476", + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary" + }, + "threatHuntInfo": { + "latestThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "latestMaliciousThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details" + }, + "threatMonitoringInfo": { + "latestThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-18T05:51:31Z", + "isMalicious": "No Matches" + }, + "latestMaliciousThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-14T04:41:15Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90" + } +} \ No newline at end of file diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_indicator.json b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_indicator.json new file mode 100644 index 000000000000..f0197ebe4e3f --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/domain_indicator.json @@ -0,0 +1,16 @@ +{ + "Domain(val.Name && val.Name == obj.Name)": { + "Name": "DEMO-RADAR", + "UpdatedDate": "2024-10-18T05:51:31Z", + "WHOIS": { + "UpdatedDate": "2024-10-18T05:51:31Z" + } + }, + "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)": { + "Indicator": "DEMO-RADAR", + "Reliability": "A - Completely reliable", + "Type": "domain", + "Vendor": "Rubrik Security Cloud", + "Score": 2 + } +} \ No newline at end of file diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_hr.md b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_hr.md new file mode 100644 index 000000000000..f786caa53d04 --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_hr.md @@ -0,0 +1,24 @@ +### General Information for the given medium risk IP: 0.0.0.1 +|Fid|Last Snapshot|Name|Object Type|Protection Status|Redirect Link| +|---|---|---|---|---|---| +| 12345678-1234-1234-1234-123456789012 | 2024-10-18T06:02:25Z | DEMO-RADAR | Vsphere Virtual Machine | Protected | [https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview](https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview) | + +### Sensitive Information +|Open Access Files|Policy Names|Redirect Link|Risk Level|Sensitive Files|Sensitive Hits|Stale Files| +|---|---|---|---|---|---|---| +| 6 | U.S. PII | [https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse](https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse) | Medium | mediumCount: 11 | 2910 | 11 | + +### Anomaly Information +|Created File Count|Deleted File Count|Detection Time|Modified File Count|Redirect Link|Severity|Suspicious File Count| +|---|---|---|---|---|---|---| +| 4487 | 4477 | 2024-10-14T17:57:06Z | 32 | [https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary](https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary) | Critical | 4476 | + +### Threat Hunt Information +|Latest Malicious Threat Hunt|Latest Threat Hunt|Redirect Link| +|---|---|---| +| huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | huntId: 12345678-1234-1234-1234-123456789012
huntStartTime: 2024-10-11T09:23:26Z
isMalicious: Matches Found | [https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details](https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details) | + +### Threat Monitoring Information +|Latest Malicious Threat Monitoring|Latest Threat Monitoring|Redirect Link| +|---|---|---| +| snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-14T04:41:15Z
isMalicious: Matches Found | snapshotFid: 12345678-1234-1234-1234-123456789012
monitoringScanTime: 2024-10-18T05:51:31Z
isMalicious: No Matches | [https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90](https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90) | diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_output.json b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_output.json new file mode 100644 index 000000000000..369ba1077708 --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_output.json @@ -0,0 +1,59 @@ +{ + "ip": "0.0.0.1", + "generalInfo": { + "fid": "12345678-1234-1234-1234-123456789012", + "name": "DEMO-RADAR", + "objectType": "Vsphere Virtual Machine", + "protectionStatus": "Protected", + "lastSnapshot": "2024-10-18T06:02:25Z", + "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview" + }, + "sensitiveInfo": { + "riskLevel": "Medium", + "sensitiveFiles": { + "mediumCount": "11" + }, + "sensitiveHits": 2910, + "openAccessFiles": 6, + "staleFiles": 11, + "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse", + "policyNames": [ + "U.S. PII" + ] + }, + "anomalyInfo": { + "severity": "Critical", + "detectionTime": "2024-10-14T17:57:06Z", + "createdFileCount": "4487", + "deletedFileCount": "4477", + "modifiedFileCount": "32", + "suspiciousFileCount": "4476", + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary" + }, + "threatHuntInfo": { + "latestThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "latestMaliciousThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details" + }, + "threatMonitoringInfo": { + "latestThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-18T05:51:31Z", + "isMalicious": "No Matches" + }, + "latestMaliciousThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-14T04:41:15Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90" + } +} \ No newline at end of file diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_response.json b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_response.json new file mode 100644 index 000000000000..65062b0a422c --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_command_success_response.json @@ -0,0 +1,58 @@ +{ + "generalInfo": { + "fid": "12345678-1234-1234-1234-123456789012", + "name": "DEMO-RADAR", + "objectType": "Vsphere Virtual Machine", + "protectionStatus": "Protected", + "lastSnapshot": "2024-10-18T06:02:25Z", + "redirectLink": "https://rubrik-test.my.rubrik.com/inventory_hierarchy/vsphere/12345678-1234-1234-1234-123456789012/overview" + }, + "sensitiveInfo": { + "riskLevel": "Medium", + "sensitiveFiles": { + "mediumCount": "11" + }, + "sensitiveHits": 2910, + "openAccessFiles": 6, + "staleFiles": 11, + "redirectLink": "https://rubrik-test.my.rubrik.com/sonar/objects/detail/12345678-1234-1234-1234-123456789012/12345678-1234-1234-1234-123456789012/browse", + "policyNames": [ + "U.S. PII" + ] + }, + "anomalyInfo": { + "severity": "Critical", + "detectionTime": "2024-10-14T17:57:06Z", + "createdFileCount": "4487", + "deletedFileCount": "4477", + "modifiedFileCount": "32", + "suspiciousFileCount": "4476", + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/vsphere/12345678-1234-1234-1234-123456789012/snapshot/77dc1474-a654-5f20-bcac-348a0f83cd3a/summary" + }, + "threatHuntInfo": { + "latestThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "latestMaliciousThreatHunt": { + "huntId": "12345678-1234-1234-1234-123456789012", + "huntStartTime": "2024-10-11T09:23:26Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/investigations/threat_hunts/12345678-1234-1234-1234-123456789012/details" + }, + "threatMonitoringInfo": { + "latestThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-18T05:51:31Z", + "isMalicious": "No Matches" + }, + "latestMaliciousThreatMonitoring": { + "snapshotFid": "12345678-1234-1234-1234-123456789012", + "monitoringScanTime": "2024-10-14T04:41:15Z", + "isMalicious": "Matches Found" + }, + "redirectLink": "https://rubrik-test.my.rubrik.com/radar/threat_monitoring/12345678-1234-1234-1234-123456789012/Cluster_B/8b4fe6f6-cc87-4354-a125-b65e23cf8c90" + } +} \ No newline at end of file diff --git a/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_indicator.json b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_indicator.json new file mode 100644 index 000000000000..f1579b4e7735 --- /dev/null +++ b/Packs/RubrikPolaris/Integrations/RubrikPolaris/test_data/ip_indicator.json @@ -0,0 +1,13 @@ +{ + "IP(val.Address && val.Address == obj.Address)": { + "Address": "0.0.0.1", + "UpdatedDate": "2024-10-18T05:51:31Z" + }, + "DBotScore(val.Indicator && val.Indicator == obj.Indicator && val.Vendor == obj.Vendor && val.Type == obj.Type)": { + "Indicator": "0.0.0.1", + "Reliability": "A - Completely reliable", + "Type": "ip", + "Vendor": "Rubrik Security Cloud", + "Score": 2 + } +} \ No newline at end of file diff --git a/Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.yml b/Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.yml new file mode 100644 index 000000000000..3910d2490afc --- /dev/null +++ b/Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.yml @@ -0,0 +1,697 @@ +id: Rubrik Workload Analysis - Rubrik Security Cloud +version: -1 +name: Rubrik Workload Analysis - Rubrik Security Cloud +description: This playbook fetches workload information for the provided IPs or domains, and then increases the incident severity based on the workload risk levels and threat information. +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: 26498228-85c0-425c-8dc2-0c0368407ed8 + type: start + task: + id: 26498228-85c0-425c-8dc2-0c0368407ed8 + version: -1 + name: "" + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "1" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 705, + "y": 50 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "1": + id: "1" + taskid: ffc3a86f-c4e3-4db4-8716-f5969a59c476 + type: condition + task: + id: ffc3a86f-c4e3-4db4-8716-f5969a59c476 + version: -1 + name: Is Rubrik Polaris integration enabled? + description: Checks whether Rubrik Polaris integration is enabled or not. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "6" + "yes": + - "2" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isExists + left: + value: + complex: + root: modules + filters: + - - operator: containsGeneral + left: + value: + simple: modules.brand + iscontext: true + right: + value: + simple: RubrikPolaris + - - operator: isEqualString + left: + value: + simple: modules.state + iscontext: true + right: + value: + simple: active + accessor: name + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 705, + "y": 195 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "2": + id: "2" + taskid: 5600df97-3517-4bf1-8ee8-1053355d9cc8 + type: regular + task: + id: 5600df97-3517-4bf1-8ee8-1053355d9cc8 + version: -1 + name: Delete Context. + description: |- + Delete field from context. + + This automation runs using the default Limited User role, unless you explicitly change the permissions. + For more information, see the section about permissions here: + https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.10/Cortex-XSOAR-Administrator-Guide/Automations + scriptName: DeleteContext + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "8" + scriptarguments: + key: + simple: FoundIndicators,threatMonitoringMalicious,threatHuntMalicious,anomalySeverity,riskLevel + subplaybook: + simple: auto + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 592.5, + "y": 370 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "3": + id: "3" + taskid: 962d42be-66a6-4b12-830a-6717d28c0e9a + type: regular + task: + id: 962d42be-66a6-4b12-830a-6717d28c0e9a + version: -1 + name: Get Indicators. + description: commands.local.cmd.find.indicators + script: Builtin|||findIndicators + type: regular + iscommand: true + brand: Builtin + nexttasks: + '#none#': + - "10" + scriptarguments: + extend-context: + simple: FoundIndicators=.={"value":val.value,"indicator_type":val.indicator_type} + query: + complex: + root: incident + accessor: id + transformers: + - operator: Stringify + - operator: concat + args: + prefix: + value: + simple: 'investigationIDs:' + suffix: {} + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 807.5, + "y": 720 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "4": + id: "4" + taskid: 1872b686-b785-45a4-821f-0ad0ab8f4b95 + type: regular + task: + id: 1872b686-b785-45a4-821f-0ad0ab8f4b95 + version: -1 + name: Check for IP indicator. + description: Return all the detailed information available for the given IP address(es). + script: RubrikPolaris|||ip + type: regular + iscommand: true + brand: RubrikPolaris + nexttasks: + '#none#': + - "13" + scriptarguments: + extend-context: + simple: anomalySeverity=anomalyInfo.severity::threatHuntMalicious=threatHuntInfo.latestMaliciousThreatHunt.isMalicious::threatMonitoringMalicious=threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious::riskLevel=sensitiveInfo.riskLevel + ip: + complex: + root: FoundIndicators + filters: + - - operator: isEqualString + left: + value: + simple: FoundIndicators.indicator_type + iscontext: true + right: + value: + simple: ip + ignorecase: true + accessor: value + transformers: + - operator: SetIfEmpty + args: + applyIfEmpty: {} + defaultValue: + value: + simple: inputs.ip_addresses + iscontext: true + separatecontext: false + continueonerror: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 377.5, + "y": 1225 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "5": + id: "5" + taskid: ea61438f-5e3d-4d2f-89be-f531a7e644cd + type: regular + task: + id: ea61438f-5e3d-4d2f-89be-f531a7e644cd + version: -1 + name: Set Incident Severity. + description: Script used to set the incident severity using the risk level(s) provided from the argument. + scriptName: RubrikSetIncidentSeverityUsingWorkLoadRiskLevel + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "6" + scriptarguments: + anomaly_severities: + complex: + root: anomalySeverity + increase_severity_by: + complex: + root: inputs.increase_severity_by + risk_levels: + complex: + root: riskLevel + threat_hunt_malicious: + complex: + root: threatHuntMalicious + threat_monitoring_malicious: + complex: + root: threatMonitoringMalicious + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 592.5, + "y": 1610 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "6": + id: "6" + taskid: 1075cb4a-58ad-4ce9-89f3-025627ffa221 + type: title + task: + id: 1075cb4a-58ad-4ce9-89f3-025627ffa221 + version: -1 + name: Done + type: title + iscommand: false + brand: "" + description: '' + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1070, + "y": 1790 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "8": + id: "8" + taskid: 83eb8f64-fe43-46c8-8d74-237a17d60b1b + type: condition + task: + id: 83eb8f64-fe43-46c8-8d74-237a17d60b1b + version: -1 + name: Check whether IPs or domains are available in playbook input. + description: Check whether ips or domains are available in playbook input. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "3" + "yes": + - "10" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + complex: + root: inputs.ip_addresses + transformers: + - operator: trim + iscontext: true + right: + value: {} + - operator: isNotEmpty + left: + value: + complex: + root: inputs.domains + transformers: + - operator: trim + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 592.5, + "y": 545 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "9": + id: "9" + taskid: be556a30-526d-430f-824f-e863a90f85b8 + type: regular + task: + id: be556a30-526d-430f-824f-e863a90f85b8 + version: -1 + name: Check for domain indicator. + description: Retrieve the sensitive information available for the given domain(s). + script: RubrikPolaris|||domain + type: regular + iscommand: true + brand: RubrikPolaris + nexttasks: + '#none#': + - "13" + scriptarguments: + domain: + complex: + root: FoundIndicators + filters: + - - operator: isEqualString + left: + value: + simple: FoundIndicators.indicator_type + iscontext: true + right: + value: + simple: domain + ignorecase: true + accessor: value + transformers: + - operator: SetIfEmpty + args: + applyIfEmpty: {} + defaultValue: + value: + simple: inputs.domains + iscontext: true + extend-context: + simple: anomalySeverity=anomalyInfo.severity::threatHuntMalicious=threatHuntInfo.latestMaliciousThreatHunt.isMalicious::threatMonitoringMalicious=threatMonitoringInfo.latestMaliciousThreatMonitoring.isMalicious::riskLevel=sensitiveInfo.riskLevel + separatecontext: false + continueonerror: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 807.5, + "y": 1225 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "10": + id: "10" + taskid: c09e4bfd-0a78-49ea-8515-2569a992e090 + type: title + task: + id: c09e4bfd-0a78-49ea-8515-2569a992e090 + version: -1 + name: Check for malicious indicators. + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "11" + - "12" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 592.5, + "y": 900 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "11": + id: "11" + taskid: 97143252-e0a0-4dc5-8b56-00ea7c455cc8 + type: condition + task: + id: 97143252-e0a0-4dc5-8b56-00ea7c455cc8 + version: -1 + name: Check that IP indicators are present or not. + description: Check that IP address(es) is present or not. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "6" + "yes": + - "4" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + complex: + root: FoundIndicators + filters: + - - operator: isEqualString + left: + value: + simple: FoundIndicators.indicator_type + iscontext: true + right: + value: + simple: ip + ignorecase: true + accessor: value + transformers: + - operator: SetIfEmpty + args: + applyIfEmpty: {} + defaultValue: + value: + simple: inputs.ip_addresses + iscontext: true + - operator: trim + iscontext: true + right: + value: {} + continueonerrortype: "" + view: |- + { + "position": { + "x": 377.5, + "y": 1040 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "12": + id: "12" + taskid: ad618db1-0cf1-45bc-8e9b-f61085bc12f3 + type: condition + task: + id: ad618db1-0cf1-45bc-8e9b-f61085bc12f3 + version: -1 + name: Check that domain indicators are present or not. + description: Check that domain(s) is present or not. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "6" + "yes": + - "9" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + complex: + root: FoundIndicators + filters: + - - operator: isEqualString + left: + value: + simple: FoundIndicators.indicator_type + iscontext: true + right: + value: + simple: domain + ignorecase: true + accessor: value + transformers: + - operator: SetIfEmpty + args: + applyIfEmpty: {} + defaultValue: + value: + simple: inputs.domains + iscontext: true + - operator: trim + iscontext: true + right: + value: {} + continueonerrortype: "" + view: |- + { + "position": { + "x": 807.5, + "y": 1040 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "13": + id: "13" + taskid: c1a2dd6a-f918-49bd-857a-40f5a4be5f7e + type: condition + task: + id: c1a2dd6a-f918-49bd-857a-40f5a4be5f7e + version: -1 + name: Check that any workload data found or not. + description: Check that any workload data(riskLevel, threatMonitoringMalicious, threatHuntMalicious, anomalySeverity) found or not. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "6" + Found: + - "5" + separatecontext: false + conditions: + - label: Found + condition: + - - operator: isNotEmpty + left: + value: + complex: + root: riskLevel + iscontext: true + right: + value: {} + - operator: isNotEmpty + left: + value: + complex: + root: threatMonitoringMalicious + iscontext: true + - operator: isNotEmpty + left: + value: + complex: + root: threatHuntMalicious + iscontext: true + - operator: isNotEmpty + left: + value: + complex: + root: anomalySeverity + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 592.5, + "y": 1420 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false +view: |- + { + "linkLabelsPosition": { + "11_4_yes": 0.46, + "11_6_#default#": 0.2, + "12_6_#default#": 0.28, + "12_9_yes": 0.49, + "13_5_Found": 0.44, + "13_6_#default#": 0.44, + "1_2_yes": 0.58, + "1_6_#default#": 0.23, + "8_10_yes": 0.32, + "8_3_#default#": 0.56 + }, + "paper": { + "dimensions": { + "height": 1805, + "width": 1072.5, + "x": 377.5, + "y": 50 + } + } + } +inputs: +- key: increase_severity_by + value: + simple: "1" + required: false + description: Specify the level by which to increase the incident severity. Only applicable if match found for the malicious threat hunt or for the malicious threat monitoring of workload. + playbookInputQuery: +- key: ip_addresses + value: {} + required: false + description: The IP address(es) for which to use workload information to increase incident severity. + playbookInputQuery: +- key: domains + value: {} + required: false + description: The domain(s) for which to use workload information to increase incident severity. + playbookInputQuery: +outputs: [] +tests: +- No tests (auto formatted) +fromversion: 6.5.0 diff --git a/Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud_README.md b/Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud_README.md new file mode 100644 index 000000000000..87569deafe38 --- /dev/null +++ b/Packs/RubrikPolaris/Playbooks/playbook-Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud_README.md @@ -0,0 +1,45 @@ +This playbook fetches workload information for the provided IPs or domains, and then increases the incident severity based on the workload risk levels and threat information. + +## Dependencies + +This playbook uses the following sub-playbooks, integrations, and scripts. + +### Sub-playbooks + +This playbook does not use any sub-playbooks. + +### Integrations + +* RubrikPolaris + +### Scripts + +* DeleteContext +* RubrikSetIncidentSeverityUsingWorkLoadRiskLevel + +### Commands + +* domain +* ip +* findIndicators + +## Playbook Inputs + +--- + +| **Name** | **Description** | **Default Value** | **Required** | +| --- | --- | --- | --- | +| increase_severity_by | Specify the level by which to increase the incident severity. Only applicable if match found for the malicious threat hunt or for the malicious threat monitoring of workload. | 1 | Optional | +| ip_addresses | The IP address\(es\) for which to use workload information to increase incident severity. | | Optional | +| domains | The domain\(s\) for which to use workload information to increase incident severity. | | Optional | + +## Playbook Outputs + +--- +There are no outputs for this playbook. + +## Playbook Image + +--- + +![Rubrik Workload Analysis - Rubrik Security Cloud](../doc_files/Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.png) diff --git a/Packs/RubrikPolaris/ReleaseNotes/1_4_0.md b/Packs/RubrikPolaris/ReleaseNotes/1_4_0.md new file mode 100644 index 000000000000..f770549098cb --- /dev/null +++ b/Packs/RubrikPolaris/ReleaseNotes/1_4_0.md @@ -0,0 +1,21 @@ + +#### Integrations + +##### Rubrik Security Cloud + +- Added the "ip" and "domain" commands. +- Updated the Docker image to: *demisto/rubrik-polaris-sdk-py3:1.0.0.117242*. + +#### Playbooks + +##### New: Rubrik Workload Analysis - Rubrik Security Cloud + +- New: This playbook fetches workload information for the provided IPs or domains, and then increases the incident severity based on the workload risk levels and threat information.<~XSIAM> (Available from Cortex XSIAM %%XSIAM_VERSION%%). +<~XSOAR> (Available from Cortex XSOAR 6.5.0). + +#### Scripts + +##### New: RubrikSetIncidentSeverityUsingWorkLoadRiskLevel + +- New: Script used to set the incident severity using the workload data provided from the argument.<~XSIAM> (Available from Cortex XSIAM %%XSIAM_VERSION%%). +<~XSOAR> (Available from Cortex XSOAR 6.5.0). diff --git a/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/README.md b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/README.md new file mode 100644 index 000000000000..35b7e078d1ec --- /dev/null +++ b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/README.md @@ -0,0 +1,27 @@ +Script used to set the incident severity using the workload data provided from the argument. + +## Script Data + +--- + +| **Name** | **Description** | +| --- | --- | +| Script Type | python3 | +| Cortex XSOAR Version | 6.5.0 | + +## Inputs + +--- + +| **Argument Name** | **Description** | +| --- | --- | +| risk_levels | Specify the risk level values. Supports comma separated values.

Supported values are: High, Medium, Low, No Risk. | +| anomaly_severities | Specify the anomaly severity values. Supports comma separated values.

Supported values are: Critical, Warning, Informational. | +| threat_hunt_malicious | Specify the malicious threat hunt values. Supports comma separated values.

Supported values are: Matches Found, No Matches Found. | +| threat_monitoring_malicious | Specify the malicious threat monitoring values. Supports comma separated values.

Supported values are: Matches Found, No Matches Found. | +| increase_severity_by | Specify the level by which to increase the incident severity. Only applicable if match found for the malicious threat hunt or for the malicious threat monitoring of workload. | + +## Outputs + +--- +There are no outputs for this script. \ No newline at end of file diff --git a/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.py b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.py new file mode 100644 index 000000000000..eda48bb3a73d --- /dev/null +++ b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.py @@ -0,0 +1,101 @@ +import demistomock as demisto +from CommonServerPython import * + +INCIDENT_SEVERITY_INT_TO_NAME = { + 0: 'Unknown', + 0.5: 'Info', + 1: 'Low', + 2: 'Medium', + 3: 'High', + 4: 'Critical' +} +MATCHES_FOUND = 'Matches Found' + +ANOMALY_SEVERITY_TO_INCIDENT_SEVERITY = { + 'critical': 4, + 'warning': 2, + 'informational': 0.5 +} + +RISK_LEVEL_TO_INCIDENT_SEVERITY = { + 'high': 3, + 'medium': 2, + 'low': 1, + 'no risk': 1 +} + +''' COMMAND FUNCTION ''' + + +def set_incident_severity_using_risk_level_command(args: dict[str, Any]) -> CommandResults: + """Set the incident severity using the provided workload data. + + :type args: ``Dict[str, Any]`` + :param args: Arguments provided by user. + + :rtype: ``CommandResults`` + :return: Standard command result. + """ + remove_nulls_from_dictionary(args) + + anomaly_severities: list = argToList(args.get('anomaly_severities')) + threat_hunt_malicious: list = argToList(args.get('threat_hunt_malicious')) + threat_monitoring_malicious: list = argToList(args.get('threat_monitoring_malicious')) + risk_levels: list = argToList(args.get('risk_levels')) + increase_severity_by: int = arg_to_number(args.get('increase_severity_by', 1), + arg_name='increase_severity_by') # type: ignore + + # If increase severity by value is not between 1 and 4, we will only show a message to user. + if increase_severity_by < 1 or increase_severity_by > 4: + raise DemistoException('Increase severity by value must be between 1 and 4.') + + # If there are no workload data are available in the argument, we will only show a message to user. + if not risk_levels and not anomaly_severities and not threat_hunt_malicious and not threat_monitoring_malicious: + raise DemistoException('No data specified to update the incident severity.') + + # Get current incident severity. + current_severity: int = demisto.incident().get('severity', 0) + + if not isinstance(current_severity, (float, int)): + raise DemistoException('Not able to get the correct value for the current incident severity.') + + anomaly_severity, threat_hunt_severity, risk_level_severity = 0, 0, 0 + + for anomaly in anomaly_severities: + severity_value = ANOMALY_SEVERITY_TO_INCIDENT_SEVERITY.get(anomaly.lower(), 0) + anomaly_severity = max(anomaly_severity, severity_value) # type: ignore + + for risk_level in risk_levels: + severity_value = RISK_LEVEL_TO_INCIDENT_SEVERITY.get(risk_level.lower(), 0) + risk_level_severity = max(risk_level_severity, severity_value) # type: ignore + + if MATCHES_FOUND in threat_hunt_malicious or MATCHES_FOUND in threat_monitoring_malicious: + threat_hunt_severity = int(min(4, current_severity + increase_severity_by)) + + new_severity = max(risk_level_severity, anomaly_severity, threat_hunt_severity) + + if new_severity > current_severity: + demisto.executeCommand("setIncident", {"severity": new_severity}) + return CommandResults( + readable_output=f"Increased the incident severity to {INCIDENT_SEVERITY_INT_TO_NAME[new_severity]}.") + else: + return CommandResults(readable_output="No workload data with a risk level higher than the current incident " + f"severity ({INCIDENT_SEVERITY_INT_TO_NAME[current_severity]}).") + + +''' MAIN FUNCTION ''' + + +def main(): + try: + return_results(set_incident_severity_using_risk_level_command(demisto.args())) + except Exception as ex: + return_error( + f'Failed to execute RubrikSonarSetIncidentSeverityUsingWorkLoadRiskLevel-RubrikSecurityCloud. Error: {str(ex)}') + + +''' ENTRY POINT ''' + + +if __name__ in ('__main__', '__builtin__', 'builtins'): + main() diff --git a/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.yml b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.yml new file mode 100644 index 000000000000..1260c995d3e7 --- /dev/null +++ b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.yml @@ -0,0 +1,53 @@ +args: +- description: "Specify the risk level values. Supports comma separated values.\n\nSupported values are: High, Medium, Low, No Risk." + name: risk_levels + auto: PREDEFINED + predefined: + - High + - Medium + - Low + - No Risk + isArray: true +- description: "Specify the anomaly severity values. Supports comma separated values.\n\nSupported values are: Critical, Warning, Informational." + name: anomaly_severities + auto: PREDEFINED + predefined: + - Critical + - Warning + - Informational + isArray: true +- description: "Specify the malicious threat hunt values. Supports comma separated values.\n\nSupported values are: Matches Found, No Matches Found." + name: threat_hunt_malicious + auto: PREDEFINED + predefined: + - Matches Found + - No Matches Found + isArray: true +- description: "Specify the malicious threat monitoring values. Supports comma separated values.\n\nSupported values are: Matches Found, No Matches Found." + name: threat_monitoring_malicious + auto: PREDEFINED + predefined: + - Matches Found + - No Matches Found + isArray: true +- description: "Specify the level by which to increase the incident severity. Only applicable if match found for the malicious threat hunt or for the malicious threat monitoring of workload." + name: increase_severity_by + defaultValue: "1" +comment: 'Script used to set the incident severity using the workload data provided from the argument.' +commonfields: + id: RubrikSetIncidentSeverityUsingWorkLoadRiskLevel + version: -1 +enabled: false +name: RubrikSetIncidentSeverityUsingWorkLoadRiskLevel +script: '-' +system: false +timeout: '0' +type: python +subtype: python3 +dockerimage: demisto/python3:3.11.10.113941 +fromversion: 6.5.0 +marketplaces: +- xsoar +- marketplacev2 +tests: +- No tests (auto formatted) diff --git a/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel_test.py b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel_test.py new file mode 100644 index 000000000000..095d35e75352 --- /dev/null +++ b/Packs/RubrikPolaris/Scripts/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel/RubrikSetIncidentSeverityUsingWorkLoadRiskLevel_test.py @@ -0,0 +1,146 @@ +"""RubrikSonarSetIncidentSeverityUsingUserRiskLevel Script for Cortex XSOAR - Unit Tests file.""" +from unittest.mock import patch +import pytest + +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 + + +from RubrikSetIncidentSeverityUsingWorkLoadRiskLevel import set_incident_severity_using_risk_level_command, main + + +@pytest.fixture +def mock_execute_command(): + '''Fixture to mock the `executeCommand` function from the `demisto` module.''' + with patch('RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.demisto.executeCommand') as mock: + yield mock + + +def test_set_incident_severity_using_risk_level_command_with_no_workload_data_specified(capfd): + """Tests set_incident_severity_using_risk_level command function when no workload data specified. + + Checks the output of the command function with the expected output. + """ + capfd.disabled() + with pytest.raises(Exception) as e: + set_incident_severity_using_risk_level_command({}) + + assert str(e.value) == 'No data specified to update the incident severity.' + + +@pytest.mark.parametrize("increase_severity_by", [0, 5]) +def test_set_incident_severity_using_risk_level_command_with_invalid_increase_severity_by_value(increase_severity_by, capfd): + args = {'increase_severity_by': increase_severity_by} + + with capfd.disabled(): + with pytest.raises(Exception) as e: + set_incident_severity_using_risk_level_command(args) + + assert str(e.value) == 'Increase severity by value must be between 1 and 4.' + + +def test_set_incident_severity_using_risk_level_command_with_invalid_severity(mocker, capfd): + """Tests set_incident_severity_using_risk_level command function when invalid severity found. + + Checks the output of the command function with the expected output. + """ + # Mock the demisto.incident() function to return an incident with mocked values. + mocker.patch.object(demisto, 'incident', return_value={ + 'severity': 'invalid' + }) + + with capfd.disabled(): + with pytest.raises(Exception) as e: + set_incident_severity_using_risk_level_command({'risk_levels': 'High'}) + + assert str(e.value) == 'Not able to get the correct value for the current incident severity.' + + +@pytest.mark.parametrize("args,severity", [ + ({'risk_levels': ['High', 'Low'], 'increase_severity_by': 1}, 'High'), + ({'risk_levels': ['Medium', 'Low'], 'increase_severity_by': 1}, 'Medium'), + ({'risk_levels': ['Low'], 'increase_severity_by': 1}, 'Low'), + ({'risk_levels': ['No Risk'], 'increase_severity_by': 1}, 'Low'), + ({'risk_levels': ['High', 'Low'], 'anomaly_severities': ['Critical'], 'increase_severity_by': 1}, 'Critical'), + ({'threat_hunt_malicious': ['Matches Found'], 'anomaly_severities': ['Warning'], 'increase_severity_by': 2}, 'Medium'), + ({'threat_monitoring_malicious': ['Matches Found'], 'increase_severity_by': 4}, 'Critical'), +]) +def test_set_incident_severity_using_risk_level_command_with_success(mocker, args, severity): + """Tests set_incident_severity_using_risk_level command function with success. + + Checks the output of the command function with the expected output. + """ + + # Mock the demisto.incident() function to return an incident with mocked values. + mocker.patch.object(demisto, 'incident', return_value={'severity': 0}) + + response = set_incident_severity_using_risk_level_command(args) + + assert response.readable_output == f'Increased the incident severity to {severity}.' + + +@pytest.mark.parametrize("args,incident_severity,severity", [ + ({'threat_hunt_malicious': ['Matches Found'], 'increase_severity_by': None}, 2, 'High'), + ({'threat_hunt_malicious': ['Matches Found'], 'increase_severity_by': 2}, 0, 'Medium'), + ({'threat_hunt_malicious': ['Matches Found'], 'increase_severity_by': 3}, 0.5, 'High'), + ({'threat_hunt_malicious': ['Matches Found'], 'increase_severity_by': 4}, 2, 'Critical'), + ({'threat_hunt_malicious': ['Matches Found'], 'increase_severity_by': 1}, 3, 'Critical'), + ({'threat_hunt_malicious': ['Matches Found'], 'anomaly_severities': ['Critical'], 'increase_severity_by': 1}, 2, 'Critical'), + ({'anomaly_severities': ['Critical'], 'increase_severity_by': 1}, 2, 'Critical'), + ({'anomaly_severities': ['Warning'], 'increase_severity_by': 1}, 1, 'Medium'), + ({'anomaly_severities': ['Informational'], 'increase_severity_by': 1}, 0, 'Info') +]) +def test_set_incident_severity_using_risk_level_command_with_success_using_command(mocker, args, incident_severity, severity): + """Tests set_incident_severity_using_risk_level command function with success and using command function. + + Checks the output of the command function with the expected output. + """ + + # Mock the demisto.incident() function to return an incident with mocked values. + mocker.patch.object(demisto, 'incident', return_value={ + 'severity': incident_severity + }) + + response = set_incident_severity_using_risk_level_command( + args) + + assert response.readable_output == f'Increased the incident severity to {severity}.' + + +def test_set_incident_severity_using_risk_level_command_with_high_current_severity_compared_to_new_severity(mocker): + """Tests set_incident_severity_using_risk_level function when current incident severity is higher than the new severity. + + Checks the output of the command function with the expected output. + """ + # Mock the demisto.incident() function to return an incident with mocked values. + mocker.patch.object(demisto, 'incident', return_value={ + 'severity': 3 + }) + + response = set_incident_severity_using_risk_level_command( + {'risk_levels': 'Low'}) + + assert (response.readable_output == 'No workload data with a risk level higher than the current incident severity (High).') + + +def test_main_with_exception(mock_execute_command, mocker, capfd): + '''Test case scenario for successful execution of the `main` function when an exception is raised.''' + # Test case: When an exception is raised + # Arrange + mocker.patch.object(demisto, 'incident', return_value={ + 'severity': 1 + }) + mocker.patch.object(demisto, 'args', return_value={'risk_levels': ['High', 'Low'], 'increase_severity_by': 1}) + mock_execute_command.side_effect = Exception('Some error message') + + # Mock the return_results() function to capture the output + mock_return_results = mocker.patch('RubrikSetIncidentSeverityUsingWorkLoadRiskLevel.return_results') + + # Act and Assert + with capfd.disabled(): + with pytest.raises(SystemExit) as err: + main() + + assert err.value.code == 0 + mock_execute_command.assert_called_once_with('setIncident', {"severity": 3}) + mock_return_results.assert_not_called() diff --git a/Packs/RubrikPolaris/doc_files/Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.png b/Packs/RubrikPolaris/doc_files/Rubrik_Workload_Analysis_-_Rubrik_Security_Cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..ed2595888884716d4322744b0726a572adf6f40b GIT binary patch literal 148582 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
uei5*AyzCk`^7>9>NnR=1nKdL>|g0m!n@R% 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