diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 6f15b22..131c639 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,7 +1,7 @@ name: Linting on: [push, pull_request] jobs: - lint: + lint: # Run per push for internal contributers. This isn't possible for forked pull requests, # so we'll need to run on PR events for external contributers. # String comparison below is case insensitive. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b0379ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +varonissaas.tgz +dependencies/ +__pycache__ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e6c658..a04d1e6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/phantomcyber/dev-cicd-tools - rev: v1.13 + rev: v1.20 hooks: - id: org-hook - id: package-app-dependencies - repo: https://github.com/Yelp/detect-secrets - rev: v1.2.0 + rev: v1.5.0 hooks: - id: detect-secrets args: ['--no-verify'] diff --git a/LICENSE b/LICENSE index 81a1474..8cb3d65 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Splunk Inc. + Copyright (c) Varonis, 2024 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 5bb8e26..0644ede 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,273 @@ -# Splunk> Phantom +[comment]: # "Auto-generated SOAR connector documentation" +# Varonis SaaS -Welcome to the open-source repository for Splunk> Phantom's varonissaas App. +Publisher: Varonis +Connector Version: 1.0.1 +Product Vendor: Varonis +Product Name: Varonis SaaS +Product Version Supported (regex): ".\*" +Minimum Product Version: 6.2.1 -Please have a look at our [Contributing Guide](https://github.com/Splunk-SOAR-Apps/.github/blob/main/.github/CONTRIBUTING.md) if you are interested in contributing, raising issues, or learning more about open-source Phantom apps. +Varonis SaaS for Splunk SOAR -## Legal and License +[comment]: # "File: README.md" +[comment]: # "Copyright (c) Varonis, 2024" +[comment]: # "" +[comment]: # "This unpublished material is proprietary to Varonis SaaS. All" +[comment]: # "rights reserved. The methods and techniques described herein are" +[comment]: # "considered trade secrets and/or confidential. Reproduction or" +[comment]: # "distribution, in whole or in part, is forbidden except by express" +[comment]: # "written permission of Varonis SaaS." +[comment]: # "" +[comment]: # "Licensed under the Apache License, Version 2.0 (the 'License');" +[comment]: # "you may not use this file except in compliance with the License." +[comment]: # "You may obtain a copy of the License at" +[comment]: # "" +[comment]: # " http://www.apache.org/licenses/LICENSE-2.0" +[comment]: # "" +[comment]: # "Unless required by applicable law or agreed to in writing, software distributed under" +[comment]: # "the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND," +[comment]: # "either express or implied. See the License for the specific language governing permissions" +[comment]: # "and limitations under the License." +[comment]: # "" -This Phantom App is licensed under the Apache 2.0 license. Please see our [Contributing Guide](https://github.com/Splunk-SOAR-Apps/.github/blob/main/.github/CONTRIBUTING.md#legal-notice) for further details. +Provide the following configuration settings for the integration setup to establish a successful connection: + +* **Varonis FQDN** - Enter the Varonis Web Interface address. This is the Fully Qualified Domain Name (FQDN) or IP address of the Varonis server to which you want to connect. +* **Varonis Api Key** - [API key generation](https://help.varonis.com/s/document-item?bundleId=ami1661784208197&topicId=emp1703144742927.html&_LANG=enus). +* **Alert Retrieval Start Point** - Enter the past number of days from which to start retrieving alerts. Up to 30 days and 1,000 alerts are supported. +* **Threat Detection Policies** - To retrieve alerts related to specific threat detection policies, enter the relevant policy names. **Recomended: Leave this blank to retrive all Alerts (default)**. +* **Alert Status** - Specify the Varonis alert status. +* **Alert Severity** - Specify the alert severity. + +For additional information, please check: [Our General documentation](https://help.varonis.com/s/documents?page=1). +Have a general inquiry or want to contact Varonis? [Contact us](https://www.varonis.com/resources/support). + +### Configuration Variables +The below configuration variables are required for this Connector to operate. These variables are specified when configuring a Varonis SaaS asset in SOAR. + +VARIABLE | REQUIRED | TYPE | DESCRIPTION +-------- | -------- | ---- | ----------- +**base_url** | required | string | Varonis FQDN/IP the integration should connect to +**api_key** | required | password | Varonis API Key +**verify_server_cert** | optional | boolean | Whether to verify the server certificate +**ingest_artifacts** | required | boolean | Should artifacts be ingested +**ingest_period** | required | string | Alert Retrieval Start (Days Ago) +**severity** | optional | string | Alert Severity +**threat_model** | optional | string | Threat Detection Policies +**alert_status** | optional | string | Alert Status + +### Supported Actions +[test connectivity](#action-test-connectivity) - Validate the asset configuration for connectivity using supplied configuration +[get alerts](#action-get-alerts) - Get alerts from Varonis SaaS +[update alert status](#action-update-alert-status) - Update Varonis alert status command +[close alert](#action-close-alert) - Close Varonis alert command +[get alerted events](#action-get-alerted-events) - Get alerted events from Varonis SaaS +[on poll](#action-on-poll) - Callback action for the on_poll ingest functionality + +## action: 'test connectivity' +Validate the asset configuration for connectivity using supplied configuration + +Type: **test** +Read only: **True** + +#### Action Parameters +No parameters are required for this action + +#### Action Output +No Output + +## action: 'get alerts' +Get alerts from Varonis SaaS + +Type: **investigate** +Read only: **True** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**threat_model_name** | optional | List of requested threat models to retrieve | string | +**page** | optional | Page number (default 1) | numeric | +**max_results** | optional | The max number of alerts to retrieve (up to 50) | numeric | +**start_time** | optional | Start time of the range of alerts | string | +**end_time** | optional | End time of the range of alerts | string | +**alert_status** | optional | List of required alerts status | string | +**alert_severity** | optional | List of alerts severity | string | +**device_name** | optional | List of device names | string | +**user_name** | optional | List of user names | string | `user name` +**last_days** | optional | Number of days you want the search to go back to | numeric | +**descending_order** | optional | Indicates whether alerts should be ordered in newest to oldest order | boolean | + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.data.\*.ID | string | `varonis alert id` | +action_result.data.\*.Name | string | | +action_result.data.\*.Time | string | | 2022-11-11T19:35:00 +action_result.data.\*.Severity | string | | High +action_result.data.\*.Category | string | | +action_result.data.\*.Country | string | | +action_result.data.\*.State | string | | +action_result.data.\*.Status | string | | Open +action_result.data.\*.CloseReason | string | | +action_result.data.\*.BlacklistLocation | boolean | | +action_result.data.\*.AbnormalLocation | string | | +action_result.data.\*.NumOfAlertedEvents | numeric | | +action_result.data.\*.UserName | string | `user name` | +action_result.data.\*.EventUTC | string | | +action_result.data.\*.SamAccountName | string | | +action_result.data.\*.PrivilegedAccountType | string | | +action_result.data.\*.EventUTC | string | | 2022-11-11T19:35:00 +action_result.data.\*.DeviceName | string | | +action_result.data.\*.ContainMaliciousExternalIP | string | | +action_result.data.\*.IPThreatTypes | string | | +action_result.data.\*.AssetContainsFlaggedData | string | | +action_result.data.\*.AssetContainsSensitiveData | string | | +action_result.data.\*.Platform | string | | DNS +action_result.data.\*.Asset | string | | DNS +action_result.data.\*.FileServerOrDomain | string | | DNS +action_result.status | string | | success failed +action_result.parameter.alert_severity | string | | +action_result.parameter.alert_status | string | | +action_result.parameter.descending_order | boolean | | +action_result.parameter.device_name | string | | +action_result.parameter.end_time | string | | +action_result.parameter.last_days | numeric | | +action_result.parameter.max_results | numeric | | +action_result.parameter.page | numeric | | +action_result.parameter.start_time | string | | +action_result.parameter.threat_model_name | string | | +action_result.parameter.user_name | string | `user name` | +action_result.summary | string | | +action_result.message | string | | +summary.total_objects | numeric | | +summary.total_objects_successful | numeric | | + +## action: 'update alert status' +Update Varonis alert status command + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**status** | required | Alert's new status | string | +**alert_id** | required | Array of alert IDs to be updated | string | `varonis alert id` + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.alert_id | string | `varonis alert id` | +action_result.parameter.status | string | | +action_result.data | string | | +action_result.summary | string | | +action_result.message | string | | +summary.total_objects | numeric | | +summary.total_objects_successful | numeric | | + +## action: 'close alert' +Close Varonis alert command + +Type: **generic** +Read only: **False** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**close_reason** | required | Alert's close reason | string | +**alert_id** | required | Array of alert IDs to be closed | string | `varonis alert id` + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.alert_id | string | `varonis alert id` | +action_result.parameter.close_reason | string | | +action_result.data | string | | +action_result.summary | string | | +action_result.message | string | | +summary.total_objects | numeric | | +summary.total_objects_successful | numeric | | + +## action: 'get alerted events' +Get alerted events from Varonis SaaS + +Type: **investigate** +Read only: **True** + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**alert_id** | required | List of alert IDs | string | `varonis alert id` +**page** | optional | Page number (default 1) | numeric | +**max_results** | optional | The max number of events to retrieve (up to 5k) | numeric | +**descending_order** | optional | Indicates whether events should be ordered in newest to oldest order | boolean | + +#### Action Output +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed +action_result.parameter.alert_id | string | `varonis alert id` | +action_result.parameter.descending_order | boolean | | +action_result.parameter.max_results | numeric | | +action_result.parameter.page | numeric | | +action_result.data.\*.IsDisabledAccount | boolean | | +action_result.data.\*.ByUserAccountDomain | string | `domain` | +action_result.data.\*.IsLockoutAccount | boolean | | +action_result.data.\*.ByUserAccount | string | `user name` | +action_result.data.\*.BySamAccountName | string | | +action_result.data.\*.IsStaleAccount | boolean | | +action_result.data.\*.ByUserAccountType | string | | +action_result.data.\*.AlertId | string | | +action_result.data.\*.Country | string | | +action_result.data.\*.Description | string | | +action_result.data.\*.BlacklistedLocation | boolean | | +action_result.data.\*.EventOperation | string | | +action_result.data.\*.ExternalIP | string | `ip` | +action_result.data.\*.ID | string | | +action_result.data.\*.ExternalIPReputation | string | | +action_result.data.\*.ExternalIPThreatTypes | string | | +action_result.data.\*.IsMaliciousIP | boolean | | +action_result.data.\*.DestinationDevice | string | | +action_result.data.\*.DestinationIP | string | `ip` | +action_result.data.\*.Filer | string | | +action_result.data.\*.OnAccountIsDisabled | boolean | | +action_result.data.\*.OnAccountIsLockout | boolean | | +action_result.data.\*.IsSensitive | boolean | | +action_result.data.\*.OnObjectName | string | | +action_result.data.\*.OnObjectType | string | | +action_result.data.\*.Path | string | | +action_result.data.\*.Platform | string | | +action_result.data.\*.OnSamAccountName | string | | +action_result.data.\*.SourceDevice | string | | +action_result.data.\*.SourceIP | string | `ip` | +action_result.data.\*.State | string | | +action_result.data.\*.Status | string | | +action_result.data.\*.Type | string | | +action_result.data.\*.TimeUTC | string | | +action_result.summary | string | | +action_result.message | string | | +summary.total_objects | numeric | | +summary.total_objects_successful | numeric | | + +## action: 'on poll' +Callback action for the on_poll ingest functionality + +Type: **ingest** +Read only: **True** + +The default start_time is the past 5 days. The default end_time is now. + +#### Action Parameters +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**container_id** | optional | Parameter ignored for this app | string | +**start_time** | optional | Parameter ignored for this app | numeric | +**end_time** | optional | Parameter ignored for this app | numeric | +**container_count** | optional | Maximum number of containers to create | numeric | +**artifact_count** | optional | Maximum number of artifacts to create per container | numeric | + +#### Action Output +No Output \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..c2c8098 --- /dev/null +++ b/__init__.py @@ -0,0 +1,20 @@ +# File: __init__.py +# +# Copyright (c) Varonis, 2024 +# +# This unpublished material is proprietary to Varonis SaaS. All +# rights reserved. The methods and techniques described herein are +# considered trade secrets and/or confidential. Reproduction or +# distribution, in whole or in part, is forbidden except by express +# written permission of Varonis SaaS. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language governing permissions +# and limitations under the License. diff --git a/logo_varonissaas.svg b/logo_varonissaas.svg new file mode 100644 index 0000000..2cc698a --- /dev/null +++ b/logo_varonissaas.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/logo_varonissaas_dark.svg b/logo_varonissaas_dark.svg new file mode 100644 index 0000000..94e5d3c --- /dev/null +++ b/logo_varonissaas_dark.svg @@ -0,0 +1,21 @@ + + + + diff --git a/manual_readme_content.md b/manual_readme_content.md new file mode 100644 index 0000000..d6b2a2d --- /dev/null +++ b/manual_readme_content.md @@ -0,0 +1,32 @@ +[comment]: # "File: README.md" +[comment]: # "Copyright (c) Varonis, 2024" +[comment]: # "" +[comment]: # "This unpublished material is proprietary to Varonis SaaS. All" +[comment]: # "rights reserved. The methods and techniques described herein are" +[comment]: # "considered trade secrets and/or confidential. Reproduction or" +[comment]: # "distribution, in whole or in part, is forbidden except by express" +[comment]: # "written permission of Varonis SaaS." +[comment]: # "" +[comment]: # "Licensed under the Apache License, Version 2.0 (the 'License');" +[comment]: # "you may not use this file except in compliance with the License." +[comment]: # "You may obtain a copy of the License at" +[comment]: # "" +[comment]: # " http://www.apache.org/licenses/LICENSE-2.0" +[comment]: # "" +[comment]: # "Unless required by applicable law or agreed to in writing, software distributed under" +[comment]: # "the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND," +[comment]: # "either express or implied. See the License for the specific language governing permissions" +[comment]: # "and limitations under the License." +[comment]: # "" + +Provide the following configuration settings for the integration setup to establish a successful connection: + +* **Varonis FQDN** - Enter the Varonis Web Interface address. This is the Fully Qualified Domain Name (FQDN) or IP address of the Varonis server to which you want to connect. +* **Varonis Api Key** - [API key generation](https://help.varonis.com/s/document-item?bundleId=ami1661784208197&topicId=emp1703144742927.html&_LANG=enus). +* **Alert Retrieval Start Point** - Enter the past number of days from which to start retrieving alerts. Up to 30 days and 1,000 alerts are supported. +* **Threat Detection Policies** - To retrieve alerts related to specific threat detection policies, enter the relevant policy names. **Recomended: Leave this blank to retrive all Alerts (default)**. +* **Alert Status** - Specify the Varonis alert status. +* **Alert Severity** - Specify the alert severity. + +For additional information, please check: [Our General documentation](https://help.varonis.com/s/documents?page=1). +Have a general inquiry or want to contact Varonis? [Contact us](https://www.varonis.com/resources/support). \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..474efd9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[tool.black] +line-length = 145 +target-version = ['py39'] +verbose = true + +[tool.isort] +line_length = 145 diff --git a/release_notes/1.0.1.md b/release_notes/1.0.1.md new file mode 100644 index 0000000..d959ed1 --- /dev/null +++ b/release_notes/1.0.1.md @@ -0,0 +1 @@ +* Initial Release \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7ac617a --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +dateparser==1.1.7 diff --git a/test_data/get_varonissaas_alerted_events_query.json b/test_data/get_varonissaas_alerted_events_query.json new file mode 100644 index 0000000..5d12159 --- /dev/null +++ b/test_data/get_varonissaas_alerted_events_query.json @@ -0,0 +1,82 @@ +{ + "query": { + "entityName": "Event", + "filter": { + "filterOperator": 0, + "filters": [ + { + "path": "Event.Alert.ID", + "operator": 1, + "values": [ + { + "Event.Alert.ID": "EE53B604-087A-499C-88F5-7E97ABA5BD9E" + }, + { + "Event.Alert.ID": "A08C35C2-731A-4EA1-B350-11204EACA972" + } + ] + }, + { + "path": "Event.TimeUTC", + "operator": 10, + "values": [ + { + "Event.TimeUTC": 365, + "displayValue": 365 + } + ] + } + ] + } + }, + "rows": { + "columns": [ + "Event.Alert.ID", + "Event.ID", + "Event.Type.Name", + "Event.TimeUTC", + "Event.Status.Name", + "Event.Description", + "Event.Location.Country.Name", + "Event.Location.Subdivision.Name", + "Event.Location.BlacklistedLocation", + "Event.Operation.Name", + "Event.ByAccount.Identity.Name", + "Event.ByAccount.Type.Name", + "Event.ByAccount.Domain.Name", + "Event.ByAccount.SamAccountName", + "Event.Filer.Name", + "Event.Filer.Platform.Name", + "Event.IP", + "Event.Device.ExternalIP.IP", + "Event.Destination.IP", + "Event.Device.Name", + "Event.Destination.DeviceName", + "Event.ByAccount.IsDisabled", + "Event.ByAccount.IsStale", + "Event.ByAccount.IsLockout", + "Event.Device.ExternalIP.ThreatTypes.Name", + "Event.Device.ExternalIP.IsMalicious", + "Event.Device.ExternalIP.Reputation.Name", + "Event.OnObjectName", + "Event.OnResource.ObjectType.Name", + "Event.OnAccount.SamAccountName", + "Event.OnResource.IsSensitive", + "Event.OnAccount.IsDisabled", + "Event.OnAccount.IsLockout", + "Event.OnResource.Path" + ], + "filter": [], + "grouping": null, + "ordering": [ + { + "Path": "Event.TimeUTC", + "SortOrder": "Desc" + } + ] + }, + "requestParams": { + "searchSource": 1, + "searchSourceName": "Phantom" + } +} diff --git a/test_data/get_varonissaas_alerted_events_response.json b/test_data/get_varonissaas_alerted_events_response.json new file mode 100644 index 0000000..b877bf1 --- /dev/null +++ b/test_data/get_varonissaas_alerted_events_response.json @@ -0,0 +1,123 @@ +{ + "columns": [ + "Event.Alert.ID", + "Event.ID", + "Event.Type.Name", + "Event.TimeUTC", + "Event.Status.Name", + "Event.Description", + "Event.Location.Country.Name", + "Event.Location.Subdivision.Name", + "Event.Location.BlacklistedLocation", + "Event.Operation.Name", + "Event.ByAccount.Identity.Name", + "Event.ByAccount.Type.Name", + "Event.ByAccount.Domain.Name", + "Event.ByAccount.SamAccountName", + "Event.Filer.Name", + "Event.Filer.Platform.Name", + "Event.IP", + "Event.Device.ExternalIP.IP", + "Event.Destination.IP", + "Event.Device.Name", + "Event.Destination.DeviceName", + "Event.ByAccount.IsDisabled", + "Event.ByAccount.IsStale", + "Event.ByAccount.IsLockout", + "Event.Device.ExternalIP.ThreatTypes.Name", + "Event.Device.ExternalIP.IsMalicious", + "Event.Device.ExternalIP.Reputation.Name", + "Event.OnObjectName", + "Event.OnResource.ObjectType.Name", + "Event.OnAccount.SamAccountName", + "Event.OnResource.IsSensitive", + "Event.OnAccount.IsDisabled", + "Event.OnAccount.IsLockout", + "Event.OnResource.Path" + ], + "rows": [ + [ + "A08C35C2-731A-4EA1-B350-11204EACA972", + "E0349937-5104-4B16-B199-95F3E4253F8F", + "Account authentication (TGT)", + "2023-12-19T11:31:23.000Z", + "Success", + "\"dev3cf41.com\\varadm\" authenticated via Kerberos", + "", + "", + "", + "Created", + "varadm", + "User", + "dev3cf41.com", + "varadm", + "AD-dev3cf41.com", + "Active Directory", + "10.188.33.201", + "", + "", + "dev3cf41col01", + "", + "No", + "No", + "No", + "", + "", + "", + "dev3cf41.com", + "Domain", + "", + "", + "", + "", + "dev3cf41.com" + ], + [ + "EE53B604-087A-499C-88F5-7E97ABA5BD9E", + "F63E74E3-227C-47DF-97BE-E6D555D1A27A", + "Access request (TGS Request)", + "2023-12-19T11:23:06.000Z", + "Success", + "\"dev3cf41.com\\varadm\" was granted access to \"dev3cf41dc$\"", + "", + "", + "", + "Created", + "varadm", + "User", + "dev3cf41.com", + "varadm", + "AD-dev3cf41.com", + "Active Directory", + "10.188.33.201", + "", + "", + "dev3cf41col01", + "", + "No", + "No", + "No", + "", + "", + "", + "dev3cf41.com", + "Domain", + "", + "", + "", + "", + "dev3cf41.com" + ] + ], + "hasResults": true, + "rowsCount": 2, + "cappedNumber": 0, + "progress": 100, + "finished": true, + "entityTagHeaderValue": { + "tag": "\"3\"", + "isWeak": false + }, + "versionId": 3, + "bookmark": null +} diff --git a/test_data/get_varonissaas_alerted_events_result.json b/test_data/get_varonissaas_alerted_events_result.json new file mode 100644 index 0000000..5a9472c --- /dev/null +++ b/test_data/get_varonissaas_alerted_events_result.json @@ -0,0 +1,74 @@ +[ + { + "ID": "E0349937-5104-4B16-B199-95F3E4253F8F", + "AlertId": "A08C35C2-731A-4EA1-B350-11204EACA972", + "Type": "Account authentication (TGT)", + "TimeUTC": "2023-12-19T11:31:23.000000+0000", + "Status": "Success", + "Description": "\"dev3cf41.com\\varadm\" authenticated via Kerberos", + "Country": "", + "State": "", + "BlacklistedLocation": null, + "EventOperation": "Created", + "ByUserAccount": "varadm", + "ByUserAccountType": "User", + "ByUserAccountDomain": "dev3cf41.com", + "BySamAccountName": "varadm", + "Filer": "AD-dev3cf41.com", + "Platform": "Active Directory", + "SourceIP": "10.188.33.201", + "ExternalIP": "", + "DestinationIP": "", + "SourceDevice": "dev3cf41col01", + "DestinationDevice": "", + "IsDisabledAccount": false, + "IsLockoutAccount": false, + "IsStaleAccount": false, + "IsMaliciousIP": null, + "ExternalIPThreatTypes": "", + "ExternalIPReputation": "", + "OnObjectName": "dev3cf41.com", + "OnObjectType": "Domain", + "OnSamAccountName": "", + "IsSensitive": null, + "OnAccountIsDisabled": null, + "OnAccountIsLockout": null, + "Path": "dev3cf41.com" + }, + { + "ID": "F63E74E3-227C-47DF-97BE-E6D555D1A27A", + "AlertId": "EE53B604-087A-499C-88F5-7E97ABA5BD9E", + "Type": "Access request (TGS Request)", + "TimeUTC": "2023-12-19T11:23:06.000000+0000", + "Status": "Success", + "Description": "\"dev3cf41.com\\varadm\" was granted access to \"dev3cf41dc$\"", + "Country": "", + "State": "", + "BlacklistedLocation": null, + "EventOperation": "Created", + "ByUserAccount": "varadm", + "ByUserAccountType": "User", + "ByUserAccountDomain": "dev3cf41.com", + "BySamAccountName": "varadm", + "Filer": "AD-dev3cf41.com", + "Platform": "Active Directory", + "SourceIP": "10.188.33.201", + "ExternalIP": "", + "DestinationIP": "", + "SourceDevice": "dev3cf41col01", + "DestinationDevice": "", + "IsDisabledAccount": false, + "IsLockoutAccount": false, + "IsStaleAccount": false, + "IsMaliciousIP": null, + "ExternalIPThreatTypes": "", + "ExternalIPReputation": "", + "OnObjectName": "dev3cf41.com", + "OnObjectType": "Domain", + "OnSamAccountName": "", + "IsSensitive": null, + "OnAccountIsDisabled": null, + "OnAccountIsLockout": null, + "Path": "dev3cf41.com" + } +] diff --git a/test_data/get_varonissaas_alerts_empty_param_query.json b/test_data/get_varonissaas_alerts_empty_param_query.json new file mode 100644 index 0000000..2a2b507 --- /dev/null +++ b/test_data/get_varonissaas_alerts_empty_param_query.json @@ -0,0 +1,64 @@ +{ + "query": { + "entityName": "Alert", + "filter": { + "filterOperator": 0, + "filters": [ + { + "path": "Alert.AggregationFilter", + "operator": 4, + "values": [ + { + "Alert.AggregationFilter": 1 + } + ] + } + ] + } + }, + "rows": { + "columns": [ + "Alert.ID", + "Alert.Rule.Name", + "Alert.Rule.ID", + "Alert.TimeUTC", + "Alert.Rule.Severity.Name", + "Alert.Rule.Severity.ID", + "Alert.Rule.Category.Name", + "Alert.Location.CountryName", + "Alert.Location.SubdivisionName", + "Alert.Status.Name", + "Alert.Status.ID", + "Alert.EventsCount", + "Alert.Initial.Event.TimeUTC", + "Alert.User.Name", + "Alert.User.SamAccountName", + "Alert.User.AccountType.Name", + "Alert.Device.HostName", + "Alert.Device.IsMaliciousExternalIP", + "Alert.Device.ExternalIPThreatTypesName", + "Alert.Data.IsFlagged", + "Alert.Data.IsSensitive", + "Alert.Filer.Platform.Name", + "Alert.Asset.Path", + "Alert.Filer.Name", + "Alert.CloseReason.Name", + "Alert.Location.BlacklistedLocation", + "Alert.Location.AbnormalLocation", + "Alert.User.SidID", + "Alert.IngestTime" + ], + "filter": [], + "grouping": null, + "ordering": [ + { + "Path": "Alert.IngestTime", + "SortOrder": "Desc" + } + ] + }, + "requestParams": { + "searchSource": 1, + "searchSourceName": "Phantom" + } +} diff --git a/test_data/get_varonissaas_alerts_empty_param_response.json b/test_data/get_varonissaas_alerts_empty_param_response.json new file mode 100644 index 0000000..6e542a6 --- /dev/null +++ b/test_data/get_varonissaas_alerts_empty_param_response.json @@ -0,0 +1,108 @@ +{ + "columns": [ + "Alert.ID", + "Alert.Rule.Name", + "Alert.Rule.ID", + "Alert.TimeUTC", + "Alert.Rule.Severity.Name", + "Alert.Rule.Severity.ID", + "Alert.Rule.Category.Name", + "Alert.Location.CountryName", + "Alert.Location.SubdivisionName", + "Alert.Status.Name", + "Alert.Status.ID", + "Alert.EventsCount", + "Alert.Initial.Event.TimeUTC", + "Alert.User.Name", + "Alert.User.SamAccountName", + "Alert.User.AccountType.Name", + "Alert.Device.HostName", + "Alert.Device.IsMaliciousExternalIP", + "Alert.Device.ExternalIPThreatTypesName", + "Alert.Data.IsFlagged", + "Alert.Data.IsSensitive", + "Alert.Filer.Platform.Name", + "Alert.Asset.Path", + "Alert.Filer.Name", + "Alert.CloseReason.Name", + "Alert.Location.BlacklistedLocation", + "Alert.Location.AbnormalLocation", + "Alert.User.SidID", + "Alert.IngestTime" + ], + "rows": [ + [ + "B0C4208A-EB12-4A88-A1E5-433DE4F69F8C", + "Capture Access request for varadm", + "189", + "2023-12-19T16:36:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T16:30:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T16:38:42" + ], + [ + "C0FC6064-C85B-4043-AA46-C40B0598F0F4", + "Capture Account authentication for varadm", + "186", + "2023-12-19T16:36:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T16:32:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T16:38:39" + ] + ], + "hasResults": true, + "rowsCount": 2, + "cappedNumber": 50000, + "progress": 100, + "finished": true, + "entityTagHeaderValue": { + "tag": "\"3\"", + "isWeak": false + }, + "versionId": 3, + "bookmark": null +} diff --git a/test_data/get_varonissaas_alerts_empty_param_result.json b/test_data/get_varonissaas_alerts_empty_param_result.json new file mode 100644 index 0000000..ca7d4eb --- /dev/null +++ b/test_data/get_varonissaas_alerts_empty_param_result.json @@ -0,0 +1,62 @@ +[ + { + "ID": "B0C4208A-EB12-4A88-A1E5-433DE4F69F8C", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T16:36:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T16:30:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T16:38:42.000000+0000", + "Url": null + }, + { + "ID": "C0FC6064-C85B-4043-AA46-C40B0598F0F4", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T16:36:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T16:32:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T16:38:39.000000+0000", + "Url": null + } +] diff --git a/test_data/get_varonissaas_alerts_query.json b/test_data/get_varonissaas_alerts_query.json new file mode 100644 index 0000000..90d9b40 --- /dev/null +++ b/test_data/get_varonissaas_alerts_query.json @@ -0,0 +1,162 @@ +{ + "query": { + "entityName": "Alert", + "filter": { + "filterOperator": 0, + "filters": [ + { + "path": "Alert.Rule.Name", + "operator": 1, + "values": [ + { + "Alert.Rule.Name": "Capture Access request for varadm", + "displayValue": "New" + }, + { + "Alert.Rule.Name": "Capture Account authentication for varadm", + "displayValue": "New" + }, + { + "Alert.Rule.Name": "Capture SYSTEM", + "displayValue": "New" + } + ] + }, + { + "path": "Alert.TimeUTC", + "operator": 3, + "values": [ + { + "Alert.TimeUTC": "2023-12-01T13:00:00+02:00", + "Alert.TimeUTC0": "2023-12-30T13:59:00+02:00" + } + ] + }, + { + "path": "Alert.Device.HostName", + "operator": 1, + "values": [ + { + "Alert.Device.HostName": "dev3cf41col01", + "displayValue": "dev3cf41col01" + }, + { + "Alert.Device.HostName": "dev3cf41dh", + "displayValue": "dev3cf41dh" + } + ] + }, + { + "path": "Alert.TimeUTC", + "operator": 10, + "values": [ + { + "Alert.TimeUTC": 2, + "displayValue": 2 + } + ] + }, + { + "path": "Alert.User.Identity.Name", + "operator": 1, + "values": [ + { + "Alert.User.Identity.Name": "varadm", + "displayValue": "varadm" + }, + { + "Alert.User.Identity.Name": "SYSTEM", + "displayValue": "SYSTEM" + } + ] + }, + { + "path": "Alert.Status.ID", + "operator": 1, + "values": [ + { + "Alert.Status.ID": 1, + "displayValue": "New" + }, + { + "Alert.Status.ID": 3, + "displayValue": "Closed" + } + ] + }, + { + "path": "Alert.Rule.Severity.ID", + "operator": 1, + "values": [ + { + "Alert.Rule.Severity.ID": 0, + "displayValue": "High" + }, + { + "Alert.Rule.Severity.ID": 2, + "displayValue": "Low" + }, + { + "Alert.Rule.Severity.ID": 1, + "displayValue": "Medium" + } + ] + }, + { + "path": "Alert.AggregationFilter", + "operator": 4, + "values": [ + { + "Alert.AggregationFilter": 1 + } + ] + } + ] + } + }, + "rows": { + "columns": [ + "Alert.ID", + "Alert.Rule.Name", + "Alert.Rule.ID", + "Alert.TimeUTC", + "Alert.Rule.Severity.Name", + "Alert.Rule.Severity.ID", + "Alert.Rule.Category.Name", + "Alert.Location.CountryName", + "Alert.Location.SubdivisionName", + "Alert.Status.Name", + "Alert.Status.ID", + "Alert.EventsCount", + "Alert.Initial.Event.TimeUTC", + "Alert.User.Name", + "Alert.User.SamAccountName", + "Alert.User.AccountType.Name", + "Alert.Device.HostName", + "Alert.Device.IsMaliciousExternalIP", + "Alert.Device.ExternalIPThreatTypesName", + "Alert.Data.IsFlagged", + "Alert.Data.IsSensitive", + "Alert.Filer.Platform.Name", + "Alert.Asset.Path", + "Alert.Filer.Name", + "Alert.CloseReason.Name", + "Alert.Location.BlacklistedLocation", + "Alert.Location.AbnormalLocation", + "Alert.User.SidID", + "Alert.IngestTime" + ], + "filter": [], + "grouping": null, + "ordering": [ + { + "Path": "Alert.IngestTime", + "SortOrder": "Asc" + } + ] + }, + "requestParams": { + "searchSource": 1, + "searchSourceName": "Phantom" + } +} diff --git a/test_data/get_varonissaas_alerts_response.json b/test_data/get_varonissaas_alerts_response.json new file mode 100644 index 0000000..e91b9e5 --- /dev/null +++ b/test_data/get_varonissaas_alerts_response.json @@ -0,0 +1,1627 @@ +{ + "columns": [ + "Alert.ID", + "Alert.Rule.Name", + "Alert.Rule.ID", + "Alert.TimeUTC", + "Alert.Rule.Severity.Name", + "Alert.Rule.Severity.ID", + "Alert.Rule.Category.Name", + "Alert.Location.CountryName", + "Alert.Location.SubdivisionName", + "Alert.Status.Name", + "Alert.Status.ID", + "Alert.EventsCount", + "Alert.Initial.Event.TimeUTC", + "Alert.User.Name", + "Alert.User.SamAccountName", + "Alert.User.AccountType.Name", + "Alert.Device.HostName", + "Alert.Device.IsMaliciousExternalIP", + "Alert.Device.ExternalIPThreatTypesName", + "Alert.Data.IsFlagged", + "Alert.Data.IsSensitive", + "Alert.Filer.Platform.Name", + "Alert.Asset.Path", + "Alert.Filer.Name", + "Alert.CloseReason.Name", + "Alert.Location.BlacklistedLocation", + "Alert.Location.AbnormalLocation", + "Alert.User.SidID", + "Alert.IngestTime" + ], + "rows": [ + [ + "16157A69-F4E5-4144-B1F2-FEACE2B650C0", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:31:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:23:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:33:42" + ], + [ + "83597141-4F0D-461B-9829-94D9CDB23277", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:31:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:23:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:33:45" + ], + [ + "F1F74698-949C-4210-BBAD-D00B27D6A978", + "Capture Access request for varadm", + "189", + "2023-12-19T11:31:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:23:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:33:51" + ], + [ + "EE53B604-087A-499C-88F5-7E97ABA5BD9E", + "Capture Access request for varadm", + "189", + "2023-12-19T11:31:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:23:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:33:53" + ], + [ + "A08C35C2-731A-4EA1-B350-11204EACA972", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:36:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:31:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:38:37" + ], + [ + "0668C8FC-2D0A-49A7-B9E7-AF1B5C9BEB6F", + "Capture Access request for varadm", + "189", + "2023-12-19T11:36:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:31:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:38:40" + ], + [ + "60EA6EA8-AC3D-4538-9DED-FE56D7F6655C", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:36:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:33:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:39:25" + ], + [ + "7B51C4C4-4D95-4906-89FC-2BF96703FB47", + "Capture Access request for varadm", + "189", + "2023-12-19T11:36:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:33:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:39:28" + ], + [ + "ED88E22C-CD37-4FC1-9829-C60C2783802F", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:41:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:35:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:43:37" + ], + [ + "95319421-0A3E-4FFC-A1D2-8180CD82FFD6", + "Capture Access request for varadm", + "189", + "2023-12-19T11:41:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:37:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:43:40" + ], + [ + "35B0CCE6-081E-429E-B0E3-A85CAE8B4F1A", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:41:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:37:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:43:43" + ], + [ + "A755EA69-3AAD-4E62-8E50-1934BC8210F9", + "Capture Access request for varadm", + "189", + "2023-12-19T11:46:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:39:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:48:39" + ], + [ + "F503FC20-0BA1-41D6-95FC-195B6A73DB56", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:46:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:39:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:48:42" + ], + [ + "C66D68EF-214C-49F7-A4FF-5EF1E3C44134", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:46:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:43:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:49:25" + ], + [ + "3D4DBB2B-77F6-4C04-8DDE-C375D27BE89C", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:51:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:47:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:53:37" + ], + [ + "6F729949-EBEC-45F7-9854-8BB1615C4B90", + "Capture Access request for varadm", + "189", + "2023-12-19T11:51:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:47:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:53:40" + ], + [ + "5C8D551C-152F-49FE-A958-E248DEFF743C", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:56:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:51:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:58:37" + ], + [ + "D88DC32F-90DF-4CB9-A451-D136575653A9", + "Capture Access request for varadm", + "189", + "2023-12-19T11:56:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:49:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:58:40" + ], + [ + "43DE70CC-A656-4641-9612-C243AA44D6AD", + "Capture Account authentication for varadm", + "186", + "2023-12-19T11:56:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:49:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T11:58:43" + ], + [ + "00F81966-0107-4947-902A-1B562FC75A8D", + "Capture Access request for varadm", + "189", + "2023-12-19T12:01:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:57:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:03:37" + ], + [ + "99C8770A-D5EA-4462-B153-79C774044FE3", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:01:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:55:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:03:40" + ], + [ + "CA543655-89AC-4F7A-BB3A-66829D881D33", + "Capture Access request for varadm", + "189", + "2023-12-19T12:06:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:01:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:08:37" + ], + [ + "31E2AEDB-0AB6-40DC-85C7-5E2E7A5F47FB", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:06:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T11:59:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:08:40" + ], + [ + "D1EF163F-63C3-4493-9D57-0F0130EB80C3", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:11:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:07:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:16:39" + ], + [ + "92A17E49-38BF-4A02-B8C7-1DD4C8E3385C", + "Capture Access request for varadm", + "189", + "2023-12-19T12:11:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:05:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:16:41" + ], + [ + "07171D44-AE13-44F5-9464-7C1F99D04225", + "Capture Access request for varadm", + "189", + "2023-12-19T12:16:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:11:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:18:37" + ], + [ + "E3F22810-6D4B-43BE-B773-FD501729FAC9", + "Capture Access request for varadm", + "189", + "2023-12-19T12:16:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:09:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:18:40" + ], + [ + "8B0717C0-AD88-4FC2-9DCC-28C6F1756381", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:16:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:09:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:18:43" + ], + [ + "A5EA0561-D975-41C1-98CF-539A246B332C", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:21:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:17:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:23:38" + ], + [ + "B5EDC5BD-C44A-4ABE-824A-3223A28DF753", + "Capture Access request for varadm", + "189", + "2023-12-19T12:21:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:17:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:23:40" + ], + [ + "95770693-53AE-4F45-AD13-77A6A1D5D997", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:26:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:21:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:31:39" + ], + [ + "33E7C32E-E765-4D2E-8331-67499CA6AA8D", + "Capture Access request for varadm", + "189", + "2023-12-19T12:26:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:21:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:31:41" + ], + [ + "403F2256-B191-42B6-8BAB-EAA76F966A45", + "Capture Access request for varadm", + "189", + "2023-12-19T12:31:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:27:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:33:37" + ], + [ + "B87732A0-4E94-4DF2-9730-94E2F126A635", + "Capture Access request for varadm", + "189", + "2023-12-19T12:31:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:25:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:33:40" + ], + [ + "F362F3B3-E9A0-47CB-A6C4-4699FAEFBCA6", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:31:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:25:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:33:43" + ], + [ + "7789D913-76B1-44E8-86E6-1C5D8FA9BE81", + "Capture Access request for varadm", + "189", + "2023-12-19T12:31:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:29:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:35:27" + ], + [ + "E5976A92-5660-4059-88C4-FF5D69B60C54", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:36:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:33:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:39:27" + ], + [ + "D37FA3B9-913C-4D9D-A266-80286224D703", + "Capture Access request for varadm", + "189", + "2023-12-19T12:36:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:33:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:39:30" + ], + [ + "E15E1E98-3E48-4F4C-8CED-D5D2EE27C713", + "Capture Access request for varadm", + "189", + "2023-12-19T12:36:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:31:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:41:38" + ], + [ + "1999F1C7-8BE7-47C6-A979-087821EF02D7", + "Capture Access request for varadm", + "189", + "2023-12-19T12:41:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:37:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:46:39" + ], + [ + "9A31E675-1395-4520-ADBC-7D3BD4C37611", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:41:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:37:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:46:41" + ], + [ + "287EE4BB-64AC-45D6-8683-E3C407AD3AFA", + "Capture Access request for varadm", + "189", + "2023-12-19T12:41:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:35:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:46:44" + ], + [ + "495CF2BE-CB76-4683-98C1-40C80DB734DF", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:41:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:35:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:46:47" + ], + [ + "D7DCAE16-EA50-487B-B1CF-14355E7FD20D", + "Capture Access request for varadm", + "189", + "2023-12-19T12:46:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:39:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:48:39" + ], + [ + "F7470406-B72D-4707-8881-3AE68BB51904", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:46:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:39:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:48:42" + ], + [ + "2DEDDD50-1AD3-44E7-81EA-149850EFE062", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:51:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:45:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:53:39" + ], + [ + "93D7886D-7994-4608-8733-D3F13AD65A1E", + "Capture Access request for varadm", + "189", + "2023-12-19T12:51:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:45:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:53:41" + ], + [ + "1FCB38BF-1E17-4840-AC2C-C16FB504E2A4", + "Capture Access request for varadm", + "189", + "2023-12-19T12:56:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:51:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:58:39" + ], + [ + "11369F80-2708-44B5-AA5C-3BD6DE65EA27", + "Capture Account authentication for varadm", + "186", + "2023-12-19T12:56:00", + "Medium", + "1", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:49:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:58:41" + ], + [ + "3DCE8FB9-C5F3-43F2-953E-CBC1EBE0C522", + "Capture Access request for varadm", + "189", + "2023-12-19T12:56:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:49:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T12:58:44" + ], + [ + "30D9EBA7-D6B8-4938-9559-83C6FBB29641", + "Capture Access request for varadm", + "189", + "2023-12-19T13:01:00", + "Low", + "2", + "Privilege Escalation", + "", + "", + "New", + "1", + "1", + "2023-12-19T12:55:00", + "varadm (dev3cf41.com)", + "varadm", + "", + "dev3cf41col01", + "", + "", + "0", + "0", + "Active Directory", + "dev3cf41.com(AD-dev3cf41.com)", + "AD-dev3cf41.com", + "", + "", + "", + "603", + "2023-12-19T13:03:38" + ] + ], + "hasResults": true, + "rowsCount": 51, + "cappedNumber": 50000, + "progress": 100, + "finished": true, + "entityTagHeaderValue": { + "tag": "\"3\"", + "isWeak": false + }, + "versionId": 3, + "bookmark": null +} diff --git a/test_data/get_varonissaas_alerts_result.json b/test_data/get_varonissaas_alerts_result.json new file mode 100644 index 0000000..58cd8f5 --- /dev/null +++ b/test_data/get_varonissaas_alerts_result.json @@ -0,0 +1,1532 @@ +[ + { + "ID": "16157A69-F4E5-4144-B1F2-FEACE2B650C0", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:31:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:23:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:33:42.000000+0000", + "Url": null + }, + { + "ID": "83597141-4F0D-461B-9829-94D9CDB23277", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:31:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:23:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:33:45.000000+0000", + "Url": null + }, + { + "ID": "F1F74698-949C-4210-BBAD-D00B27D6A978", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:31:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:23:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:33:51.000000+0000", + "Url": null + }, + { + "ID": "EE53B604-087A-499C-88F5-7E97ABA5BD9E", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:31:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:23:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:33:53.000000+0000", + "Url": null + }, + { + "ID": "A08C35C2-731A-4EA1-B350-11204EACA972", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:36:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:31:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:38:37.000000+0000", + "Url": null + }, + { + "ID": "0668C8FC-2D0A-49A7-B9E7-AF1B5C9BEB6F", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:36:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:31:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:38:40.000000+0000", + "Url": null + }, + { + "ID": "60EA6EA8-AC3D-4538-9DED-FE56D7F6655C", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:36:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:33:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:39:25.000000+0000", + "Url": null + }, + { + "ID": "7B51C4C4-4D95-4906-89FC-2BF96703FB47", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:36:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:33:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:39:28.000000+0000", + "Url": null + }, + { + "ID": "ED88E22C-CD37-4FC1-9829-C60C2783802F", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:41:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:35:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:43:37.000000+0000", + "Url": null + }, + { + "ID": "95319421-0A3E-4FFC-A1D2-8180CD82FFD6", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:41:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:37:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:43:40.000000+0000", + "Url": null + }, + { + "ID": "35B0CCE6-081E-429E-B0E3-A85CAE8B4F1A", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:41:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:37:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:43:43.000000+0000", + "Url": null + }, + { + "ID": "A755EA69-3AAD-4E62-8E50-1934BC8210F9", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:46:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:39:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:48:39.000000+0000", + "Url": null + }, + { + "ID": "F503FC20-0BA1-41D6-95FC-195B6A73DB56", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:46:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:39:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:48:42.000000+0000", + "Url": null + }, + { + "ID": "C66D68EF-214C-49F7-A4FF-5EF1E3C44134", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:46:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:43:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:49:25.000000+0000", + "Url": null + }, + { + "ID": "3D4DBB2B-77F6-4C04-8DDE-C375D27BE89C", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:51:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:47:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:53:37.000000+0000", + "Url": null + }, + { + "ID": "6F729949-EBEC-45F7-9854-8BB1615C4B90", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:51:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:47:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:53:40.000000+0000", + "Url": null + }, + { + "ID": "5C8D551C-152F-49FE-A958-E248DEFF743C", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:56:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:51:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:58:37.000000+0000", + "Url": null + }, + { + "ID": "D88DC32F-90DF-4CB9-A451-D136575653A9", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T11:56:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:49:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:58:40.000000+0000", + "Url": null + }, + { + "ID": "43DE70CC-A656-4641-9612-C243AA44D6AD", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T11:56:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:49:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T11:58:43.000000+0000", + "Url": null + }, + { + "ID": "00F81966-0107-4947-902A-1B562FC75A8D", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:01:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:57:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:03:37.000000+0000", + "Url": null + }, + { + "ID": "99C8770A-D5EA-4462-B153-79C774044FE3", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:01:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:55:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:03:40.000000+0000", + "Url": null + }, + { + "ID": "CA543655-89AC-4F7A-BB3A-66829D881D33", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:06:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:01:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:08:37.000000+0000", + "Url": null + }, + { + "ID": "31E2AEDB-0AB6-40DC-85C7-5E2E7A5F47FB", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:06:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T11:59:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:08:40.000000+0000", + "Url": null + }, + { + "ID": "D1EF163F-63C3-4493-9D57-0F0130EB80C3", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:11:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:07:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:16:39.000000+0000", + "Url": null + }, + { + "ID": "92A17E49-38BF-4A02-B8C7-1DD4C8E3385C", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:11:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:05:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:16:41.000000+0000", + "Url": null + }, + { + "ID": "07171D44-AE13-44F5-9464-7C1F99D04225", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:16:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:11:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:18:37.000000+0000", + "Url": null + }, + { + "ID": "E3F22810-6D4B-43BE-B773-FD501729FAC9", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:16:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:09:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:18:40.000000+0000", + "Url": null + }, + { + "ID": "8B0717C0-AD88-4FC2-9DCC-28C6F1756381", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:16:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:09:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:18:43.000000+0000", + "Url": null + }, + { + "ID": "A5EA0561-D975-41C1-98CF-539A246B332C", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:21:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:17:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:23:38.000000+0000", + "Url": null + }, + { + "ID": "B5EDC5BD-C44A-4ABE-824A-3223A28DF753", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:21:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:17:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:23:40.000000+0000", + "Url": null + }, + { + "ID": "95770693-53AE-4F45-AD13-77A6A1D5D997", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:26:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:21:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:31:39.000000+0000", + "Url": null + }, + { + "ID": "33E7C32E-E765-4D2E-8331-67499CA6AA8D", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:26:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:21:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:31:41.000000+0000", + "Url": null + }, + { + "ID": "403F2256-B191-42B6-8BAB-EAA76F966A45", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:31:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:27:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:33:37.000000+0000", + "Url": null + }, + { + "ID": "B87732A0-4E94-4DF2-9730-94E2F126A635", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:31:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:25:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:33:40.000000+0000", + "Url": null + }, + { + "ID": "F362F3B3-E9A0-47CB-A6C4-4699FAEFBCA6", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:31:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:25:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:33:43.000000+0000", + "Url": null + }, + { + "ID": "7789D913-76B1-44E8-86E6-1C5D8FA9BE81", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:31:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:29:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:35:27.000000+0000", + "Url": null + }, + { + "ID": "E5976A92-5660-4059-88C4-FF5D69B60C54", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:36:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:33:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:39:27.000000+0000", + "Url": null + }, + { + "ID": "D37FA3B9-913C-4D9D-A266-80286224D703", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:36:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:33:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:39:30.000000+0000", + "Url": null + }, + { + "ID": "E15E1E98-3E48-4F4C-8CED-D5D2EE27C713", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:36:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:31:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:41:38.000000+0000", + "Url": null + }, + { + "ID": "1999F1C7-8BE7-47C6-A979-087821EF02D7", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:41:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:37:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:46:39.000000+0000", + "Url": null + }, + { + "ID": "9A31E675-1395-4520-ADBC-7D3BD4C37611", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:41:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:37:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:46:41.000000+0000", + "Url": null + }, + { + "ID": "287EE4BB-64AC-45D6-8683-E3C407AD3AFA", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:41:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:35:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:46:44.000000+0000", + "Url": null + }, + { + "ID": "495CF2BE-CB76-4683-98C1-40C80DB734DF", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:41:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:35:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:46:47.000000+0000", + "Url": null + }, + { + "ID": "D7DCAE16-EA50-487B-B1CF-14355E7FD20D", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:46:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:39:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:48:39.000000+0000", + "Url": null + }, + { + "ID": "F7470406-B72D-4707-8881-3AE68BB51904", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:46:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:39:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:48:42.000000+0000", + "Url": null + }, + { + "ID": "2DEDDD50-1AD3-44E7-81EA-149850EFE062", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:51:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:45:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:53:39.000000+0000", + "Url": null + }, + { + "ID": "93D7886D-7994-4608-8733-D3F13AD65A1E", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:51:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:45:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:53:41.000000+0000", + "Url": null + }, + { + "ID": "1FCB38BF-1E17-4840-AC2C-C16FB504E2A4", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:56:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:51:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:58:39.000000+0000", + "Url": null + }, + { + "ID": "11369F80-2708-44B5-AA5C-3BD6DE65EA27", + "Name": "Capture Account authentication for varadm", + "Time": "2023-12-19T12:56:00", + "Severity": "Medium", + "SeverityId": 1, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:49:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:58:41.000000+0000", + "Url": null + }, + { + "ID": "3DCE8FB9-C5F3-43F2-953E-CBC1EBE0C522", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T12:56:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:49:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T12:58:44.000000+0000", + "Url": null + }, + { + "ID": "30D9EBA7-D6B8-4938-9559-83C6FBB29641", + "Name": "Capture Access request for varadm", + "Time": "2023-12-19T13:01:00", + "Severity": "Low", + "SeverityId": 2, + "Category": "Privilege Escalation", + "Country": "", + "State": "", + "Status": "New", + "StatusId": 1, + "CloseReason": "", + "BlacklistLocation": "", + "AbnormalLocation": "", + "NumOfAlertedEvents": 1, + "UserName": "varadm (dev3cf41.com)", + "SamAccountName": "varadm", + "PrivilegedAccountType": "", + "ContainMaliciousExternalIP": null, + "IPThreatTypes": "", + "Asset": "dev3cf41.com(AD-dev3cf41.com)", + "AssetContainsFlaggedData": "False", + "AssetContainsSensitiveData": "False", + "Platform": "Active Directory", + "FileServerOrDomain": "AD-dev3cf41.com", + "EventUTC": "2023-12-19T12:55:00.000000+0000", + "DeviceName": "dev3cf41col01", + "IngestTime": "2023-12-19T13:03:38.000000+0000", + "Url": null + } +] diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..2b96e78 --- /dev/null +++ b/tox.ini @@ -0,0 +1,7 @@ +[flake8] +max-line-length = 145 +max-complexity = 28 +extend-ignore = F403,E128,E126,E121,E127,E731,E201,E202,E203,E701,F405,E722,D + +[isort] +line_length = 145 diff --git a/varonissaas.json b/varonissaas.json new file mode 100644 index 0000000..42851f3 --- /dev/null +++ b/varonissaas.json @@ -0,0 +1,967 @@ +{ + "appid": "89cf5316-a44d-4037-a07e-5f7504528044", + "name": "Varonis SaaS", + "description": "Varonis SaaS for Splunk SOAR", + "type": "information", + "product_vendor": "Varonis", + "logo": "logo_varonissaas.svg", + "logo_dark": "logo_varonissaas_dark.svg", + "product_name": "Varonis SaaS", + "python_version": "3", + "product_version_regex": ".*", + "publisher": "Varonis", + "license": "Copyright (c) Varonis, 2024", + "app_version": "1.0.1", + "utctime_updated": "2022-11-11T17:03:39.248366Z", + "package_name": "phantom_varonissaas", + "main_module": "varonissaas_connector.py", + "fips_complaint": false, + "min_phantom_version": "6.2.1", + "app_wizard_version": "1.0.0", + "configuration": { + "base_url": { + "description": "Varonis FQDN/IP the integration should connect to", + "data_type": "string", + "required": true, + "order": 0 + }, + "api_key": { + "description": "Varonis API Key", + "data_type": "password", + "required": true, + "order": 1 + }, + "verify_server_cert": { + "description": "Whether to verify the server certificate", + "data_type": "boolean", + "order": 2 + }, + "ingest_artifacts": { + "description": "Should artifacts be ingested", + "data_type": "boolean", + "required": true, + "order": 3 + }, + "ingest_period": { + "description": "Alert Retrieval Start (Days Ago)", + "data_type": "string", + "required": true, + "default": "7", + "order": 4 + }, + "severity": { + "description": "Alert Severity", + "data_type": "string", + "value_list": [ + "Low", + "Medium", + "High" + ], + "default": "Low", + "order": 5 + }, + "threat_model": { + "description": "Threat Detection Policies", + "data_type": "string", + "order": 6 + }, + "alert_status": { + "description": "Alert Status", + "data_type": "string", + "value_list": [ + "New", + "Under investigation", + "Closed", + "Auto-Resolved" + ], + "order": 7 + } + }, + "actions": [ + { + "action": "test connectivity", + "identifier": "test_connectivity", + "description": "Validate the asset configuration for connectivity using supplied configuration", + "type": "test", + "read_only": true, + "parameters": {}, + "output": [], + "versions": "EQ(*)" + }, + { + "action": "get alerts", + "identifier": "get_alerts", + "description": "Get alerts from Varonis SaaS", + "type": "investigate", + "read_only": true, + "parameters": { + "threat_model_name": { + "description": "List of requested threat models to retrieve", + "data_type": "string", + "order": 0 + }, + "page": { + "description": "Page number (default 1)", + "data_type": "numeric", + "default": 1, + "order": 1 + }, + "max_results": { + "description": "The max number of alerts to retrieve (up to 50)", + "data_type": "numeric", + "default": 50, + "order": 2 + }, + "start_time": { + "description": "Start time of the range of alerts", + "data_type": "string", + "order": 3 + }, + "end_time": { + "description": "End time of the range of alerts", + "data_type": "string", + "order": 4 + }, + "alert_status": { + "description": "List of required alerts status", + "data_type": "string", + "order": 5 + }, + "alert_severity": { + "description": "List of alerts severity", + "data_type": "string", + "order": 6 + }, + "device_name": { + "description": "List of device names", + "data_type": "string", + "order": 7 + }, + "user_name": { + "description": "List of user names", + "data_type": "string", + "contains": [ + "user name" + ], + "primary": true, + "order": 8 + }, + "last_days": { + "description": "Number of days you want the search to go back to", + "data_type": "numeric", + "order": 9 + }, + "descending_order": { + "description": "Indicates whether alerts should be ordered in newest to oldest order", + "data_type": "boolean", + "default": true, + "order": 10 + } + }, + "output": [ + { + "data_path": "action_result.data.*.ID", + "data_type": "string", + "column_name": "Alert ID", + "column_order": 0, + "contains": [ + "varonis alert id" + ] + }, + { + "data_path": "action_result.data.*.Name", + "data_type": "string", + "column_name": "Name", + "column_order": 1 + }, + { + "data_path": "action_result.data.*.Time", + "data_type": "string", + "column_name": "Time", + "column_order": 2, + "example_values": [ + "2022-11-11T19:35:00" + ] + }, + { + "data_path": "action_result.data.*.Severity", + "data_type": "string", + "column_name": "Severity", + "column_order": 3, + "example_values": [ + "High" + ] + }, + { + "data_path": "action_result.data.*.Category", + "data_type": "string", + "column_name": "Category", + "column_order": 4 + }, + { + "data_path": "action_result.data.*.Country", + "data_type": "string", + "column_name": "Country", + "column_order": 5 + }, + { + "data_path": "action_result.data.*.State", + "data_type": "string", + "column_name": "State", + "column_order": 6 + }, + { + "data_path": "action_result.data.*.Status", + "data_type": "string", + "column_name": "Status", + "column_order": 7, + "example_values": [ + "Open" + ] + }, + { + "data_path": "action_result.data.*.CloseReason", + "data_type": "string", + "column_name": "Close Reason", + "column_order": 8 + }, + { + "data_path": "action_result.data.*.BlacklistLocation", + "data_type": "boolean", + "column_name": "Blacklist Location", + "column_order": 9 + }, + { + "data_path": "action_result.data.*.AbnormalLocation", + "data_type": "string", + "column_name": "Abnormal Location", + "column_order": 10 + }, + { + "data_path": "action_result.data.*.NumOfAlertedEvents", + "data_type": "numeric", + "column_name": "Num Of Alerted Events", + "column_order": 11 + }, + { + "data_path": "action_result.data.*.UserName", + "data_type": "string", + "contains": [ + "user name" + ], + "column_name": "User Name", + "column_order": 12 + }, + { + "data_path": "action_result.data.*.EventUTC", + "data_type": "string", + "column_name": "Event Utc", + "column_order": 13 + }, + { + "data_path": "action_result.data.*.SamAccountName", + "data_type": "string", + "column_name": "Sam Account Name", + "column_order": 14 + }, + { + "data_path": "action_result.data.*.PrivilegedAccountType", + "data_type": "string", + "column_name": "Privileged Account Type", + "column_order": 15 + }, + { + "data_path": "action_result.data.*.EventUTC", + "data_type": "string", + "column_name": "Eventutc", + "column_order": 16, + "example_values": [ + "2022-11-11T19:35:00" + ] + }, + { + "data_path": "action_result.data.*.DeviceName", + "data_type": "string", + "column_name": "Device Name", + "column_order": 17 + }, + { + "data_path": "action_result.data.*.ContainMaliciousExternalIP", + "data_type": "string", + "column_name": "Contain Malicious External IP", + "column_order": 18 + }, + { + "data_path": "action_result.data.*.IPThreatTypes", + "data_type": "string", + "column_name": "IP Threat Types", + "column_order": 19 + }, + { + "data_path": "action_result.data.*.AssetContainsFlaggedData", + "data_type": "string", + "column_name": "Contains Flagged Data", + "column_order": 20 + }, + { + "data_path": "action_result.data.*.AssetContainsSensitiveData", + "data_type": "string", + "column_name": "Contains Sensitive Data", + "column_order": 21 + }, + { + "data_path": "action_result.data.*.Platform", + "data_type": "string", + "column_name": "Platform", + "column_order": 22, + "example_values": [ + "DNS" + ] + }, + { + "data_path": "action_result.data.*.Asset", + "data_type": "string", + "column_name": "Asset", + "column_order": 23, + "example_values": [ + "DNS" + ] + }, + { + "data_path": "action_result.data.*.FileServerOrDomain", + "data_type": "string", + "column_name": "File Server Or Domain", + "column_order": 24, + "example_values": [ + "DNS" + ] + }, + { + "data_path": "action_result.status", + "data_type": "string", + "column_name": "Status", + "column_order": 25, + "example_values": [ + "success", + "failed" + ] + }, + { + "data_path": "action_result.parameter.alert_severity", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.alert_status", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.descending_order", + "data_type": "boolean" + }, + { + "data_path": "action_result.parameter.device_name", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.end_time", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.last_days", + "data_type": "numeric" + }, + { + "data_path": "action_result.parameter.max_results", + "data_type": "numeric" + }, + { + "data_path": "action_result.parameter.page", + "data_type": "numeric" + }, + { + "data_path": "action_result.parameter.start_time", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.threat_model_name", + "data_type": "string" + }, + { + "data_path": "action_result.parameter.user_name", + "contains": [ + "user name" + ], + "data_type": "string" + }, + { + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string" + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric" + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric" + } + ], + "render": { + "type": "table" + }, + "versions": "EQ(*)" + }, + { + "action": "update alert status", + "identifier": "update_alert_status", + "description": "Update Varonis alert status command", + "type": "generic", + "read_only": false, + "parameters": { + "status": { + "description": "Alert's new status", + "data_type": "string", + "required": true, + "value_list": [ + "open", + "under investigation" + ], + "order": 0 + }, + "alert_id": { + "description": "Array of alert IDs to be updated", + "data_type": "string", + "contains": [ + "varonis alert id" + ], + "required": true, + "primary": true, + "order": 1 + } + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "column_name": "Status", + "column_order": 2, + "example_values": [ + "success", + "failed" + ] + }, + { + "data_path": "action_result.parameter.alert_id", + "data_type": "string", + "column_name": "Alert ID", + "contains": [ + "varonis alert id" + ], + "column_order": 1 + }, + { + "data_path": "action_result.parameter.status", + "data_type": "string", + "column_name": "Status", + "column_order": 0 + }, + { + "data_path": "action_result.data", + "data_type": "string" + }, + { + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string" + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric" + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric" + } + ], + "render": { + "type": "table" + }, + "versions": "EQ(*)" + }, + { + "action": "close alert", + "identifier": "close_alert", + "description": "Close Varonis alert command", + "type": "generic", + "read_only": false, + "parameters": { + "close_reason": { + "description": "Alert's close reason", + "data_type": "string", + "required": true, + "value_list": [ + "none", + "other", + "benign activity", + "true positive", + "environment misconfiguration", + "alert recently customized", + "inaccurate alert logic", + "authorized activity" + ], + "order": 0 + }, + "alert_id": { + "description": "Array of alert IDs to be closed", + "data_type": "string", + "contains": [ + "varonis alert id" + ], + "required": true, + "order": 1, + "primary": true + } + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "column_name": "Status", + "column_order": 2, + "example_values": [ + "success", + "failed" + ] + }, + { + "data_path": "action_result.parameter.alert_id", + "data_type": "string", + "column_name": "Alert ID", + "contains": [ + "varonis alert id" + ], + "column_order": 1 + }, + { + "data_path": "action_result.parameter.close_reason", + "data_type": "string", + "column_name": "Close Reason", + "column_order": 0 + }, + { + "data_path": "action_result.data", + "data_type": "string" + }, + { + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string" + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric" + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric" + } + ], + "render": { + "type": "table" + }, + "versions": "EQ(*)" + }, + { + "action": "get alerted events", + "identifier": "get_alerted_events", + "description": "Get alerted events from Varonis SaaS", + "type": "investigate", + "read_only": true, + "parameters": { + "alert_id": { + "description": "List of alert IDs", + "data_type": "string", + "contains": [ + "varonis alert id" + ], + "required": true, + "primary": true, + "order": 0 + }, + "page": { + "description": "Page number (default 1)", + "data_type": "numeric", + "default": 1, + "order": 1 + }, + "max_results": { + "description": "The max number of events to retrieve (up to 5k)", + "data_type": "numeric", + "default": 5000, + "order": 2 + }, + "descending_order": { + "description": "Indicates whether events should be ordered in newest to oldest order", + "data_type": "boolean", + "default": true, + "order": 3 + } + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "success", + "failed" + ] + }, + { + "data_path": "action_result.parameter.alert_id", + "data_type": "string", + "contains": [ + "varonis alert id" + ] + }, + { + "data_path": "action_result.parameter.descending_order", + "data_type": "boolean" + }, + { + "data_path": "action_result.parameter.max_results", + "data_type": "numeric" + }, + { + "data_path": "action_result.parameter.page", + "data_type": "numeric" + }, + { + "data_path": "action_result.data.*.IsDisabledAccount", + "data_type": "boolean", + "column_name": "Disabled Account", + "column_order": 19 + }, + { + "data_path": "action_result.data.*.ByUserAccountDomain", + "data_type": "string", + "contains": [ + "domain" + ], + "column_name": "Domain", + "column_order": 18 + }, + { + "data_path": "action_result.data.*.IsLockoutAccount", + "data_type": "boolean", + "column_name": "Lockout Accounts", + "column_order": 21 + }, + { + "data_path": "action_result.data.*.ByUserAccount", + "data_type": "string", + "contains": [ + "user name" + ], + "column_name": "User Name", + "column_order": 14 + }, + { + "data_path": "action_result.data.*.BySamAccountName", + "data_type": "string", + "column_name": "Sam Account Name", + "column_order": 17 + }, + { + "data_path": "action_result.data.*.IsStaleAccount", + "data_type": "boolean", + "column_name": "Stale Account", + "column_order": 20 + }, + { + "data_path": "action_result.data.*.ByUserAccountType", + "data_type": "string", + "column_name": "User Account Type", + "column_order": 16 + }, + { + "data_path": "action_result.data.*.AlertId", + "data_type": "string", + "column_name": "Alert ID", + "column_order": 15 + }, + { + "data_path": "action_result.data.*.Country", + "data_type": "string", + "column_name": "Country", + "column_order": 5 + }, + { + "data_path": "action_result.data.*.Description", + "data_type": "string", + "column_name": "Description", + "column_order": 4 + }, + { + "data_path": "action_result.data.*.BlacklistedLocation", + "data_type": "boolean", + "column_name": "Is Blacklist", + "column_order": 12 + }, + { + "data_path": "action_result.data.*.EventOperation", + "data_type": "string", + "column_name": "Operation", + "column_order": 13 + }, + { + "data_path": "action_result.data.*.ExternalIP", + "data_type": "string", + "contains": [ + "ip" + ], + "column_name": "External IP", + "column_order": 11 + }, + { + "data_path": "action_result.data.*.ID", + "data_type": "string", + "column_name": "Event ID", + "column_order": 0 + }, + { + "data_path": "action_result.data.*.ExternalIPReputation", + "data_type": "string", + "column_name": "IP Reputation", + "column_order": 9 + }, + { + "data_path": "action_result.data.*.ExternalIPThreatTypes", + "data_type": "string", + "column_name": "IP Threat Type", + "column_order": 10 + }, + { + "data_path": "action_result.data.*.IsMaliciousIP", + "data_type": "boolean", + "column_name": "Is Malicious IP", + "column_order": 8 + }, + { + "data_path": "action_result.data.*.DestinationDevice", + "data_type": "string", + "column_name": "Destination Device", + "column_order": 32 + }, + { + "data_path": "action_result.data.*.DestinationIP", + "data_type": "string", + "contains": [ + "ip" + ], + "column_name": "Destination IP", + "column_order": 31 + }, + { + "data_path": "action_result.data.*.Filer", + "data_type": "string", + "column_name": "Filer Name", + "column_order": 26 + }, + { + "data_path": "action_result.data.*.OnAccountIsDisabled", + "data_type": "boolean", + "column_name": "Is Disabled Account", + "column_order": 27 + }, + { + "data_path": "action_result.data.*.OnAccountIsLockout", + "data_type": "boolean", + "column_name": "Is Lock Out Account", + "column_order": 28 + }, + { + "data_path": "action_result.data.*.IsSensitive", + "data_type": "boolean", + "column_name": "Is Sensitive", + "column_order": 25 + }, + { + "data_path": "action_result.data.*.OnObjectName", + "data_type": "string", + "column_name": "Object Name", + "column_order": 22 + }, + { + "data_path": "action_result.data.*.OnObjectType", + "data_type": "string", + "column_name": "Object Type", + "column_order": 23 + }, + { + "data_path": "action_result.data.*.Path", + "data_type": "string", + "column_name": "Path", + "column_order": 33 + }, + { + "data_path": "action_result.data.*.Platform", + "data_type": "string", + "column_name": "Platform", + "column_order": 24 + }, + { + "data_path": "action_result.data.*.OnSamAccountName", + "data_type": "string", + "column_name": "Sam Account Name", + "column_order": 29 + }, + { + "data_path": "action_result.data.*.SourceDevice", + "data_type": "string", + "column_name": "Source Device", + "column_order": 30 + }, + { + "data_path": "action_result.data.*.SourceIP", + "data_type": "string", + "contains": [ + "ip" + ], + "column_name": "Source IP", + "column_order": 7 + }, + { + "data_path": "action_result.data.*.State", + "data_type": "string", + "column_name": "State", + "column_order": 6 + }, + { + "data_path": "action_result.data.*.Status", + "data_type": "string", + "column_name": "Status", + "column_order": 3 + }, + { + "data_path": "action_result.data.*.Type", + "data_type": "string", + "column_name": "Event Type", + "column_order": 1 + }, + { + "data_path": "action_result.data.*.TimeUTC", + "data_type": "string", + "column_name": "Utc Time", + "column_order": 2 + }, + { + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string" + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric" + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric" + } + ], + "render": { + "type": "table" + }, + "versions": "EQ(*)" + }, + { + "action": "on poll", + "description": "Callback action for the on_poll ingest functionality", + "verbose": "The default start_time is the past 5 days. The default end_time is now.", + "type": "ingest", + "identifier": "on_poll", + "read_only": true, + "parameters": { + "container_id": { + "data_type": "string", + "order": 0, + "description": "Parameter ignored for this app" + }, + "start_time": { + "data_type": "numeric", + "order": 1, + "description": "Parameter ignored for this app" + }, + "end_time": { + "data_type": "numeric", + "order": 2, + "description": "Parameter ignored for this app" + }, + "container_count": { + "data_type": "numeric", + "order": 3, + "description": "Maximum number of containers to create" + }, + "artifact_count": { + "data_type": "numeric", + "order": 4, + "description": "Maximum number of artifacts to create per container" + } + }, + "output": [], + "versions": "EQ(*)" + } + ], + "pip_dependencies": { + "wheel": [ + { + "module": "dateparser", + "input_file": "wheels/shared/dateparser-1.1.7-py2.py3-none-any.whl" + }, + { + "module": "pytz", + "input_file": "wheels/shared/pytz-2024.2-py2.py3-none-any.whl" + }, + { + "module": "regex", + "input_file": "wheels/py39/regex-2024.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl" + }, + { + "module": "tzlocal", + "input_file": "wheels/py3/tzlocal-5.2-py3-none-any.whl" + } + ] + }, + "pip39_dependencies": { + "wheel": [ + { + "module": "dateparser", + "input_file": "wheels/shared/dateparser-1.1.7-py2.py3-none-any.whl" + }, + { + "module": "pytz", + "input_file": "wheels/shared/pytz-2024.2-py2.py3-none-any.whl" + }, + { + "module": "regex", + "input_file": "wheels/py39/regex-2024.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl" + }, + { + "module": "tzlocal", + "input_file": "wheels/py3/tzlocal-5.2-py3-none-any.whl" + } + ] + } +} diff --git a/varonissaas_connector.py b/varonissaas_connector.py new file mode 100644 index 0000000..1d21d61 --- /dev/null +++ b/varonissaas_connector.py @@ -0,0 +1,908 @@ +# File: varonissaas_connector.py +# +# Copyright (c) Varonis, 2024 +# +# This unpublished material is proprietary to Varonis SaaS. All +# rights reserved. The methods and techniques described herein are +# considered trade secrets and/or confidential. Reproduction or +# distribution, in whole or in part, is forbidden except by express +# written permission of Varonis SaaS. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language governing permissions +# and limitations under the License. + +# Python 3 Compatibility imports +from __future__ import print_function, unicode_literals + +import json +import sys +import time +from datetime import datetime, timedelta +from typing import Any, Dict, List, Optional + +# Phantom App imports +import phantom.app as phantom +import requests +from bs4 import BeautifulSoup +from phantom.action_result import ActionResult +from phantom.base_connector import BaseConnector +from requests.adapters import HTTPAdapter +from requests.models import Response +from urllib3 import Retry + +import varonissaas_tools as tools +from varonissaas_consts import * +from varonissaas_search import * + +REQUEST_RETRIES = 30 +HTTP_STATUS_WHITE_LIST = [304, 206] + + +class RetVal(tuple): + + def __new__(cls, val1: bool, val2=None): + return tuple.__new__(RetVal, (val1, val2)) + + +class VaronisSaasConnector(BaseConnector): + + def __init__(self): + + # Call the BaseConnectors init first + super(VaronisSaasConnector, self).__init__() + + self._state: Dict[str, Any] = None + self._session = None + self._verify = None + self._headers = None + + # Variable to hold a base_url in case the app makes REST calls + # Do note that the app json defines the asset config, so please + # modify this as you deem fit. + self._base_url = None + + # HELPERS + def _process_empty_response(self, response, action_result): + if response.status_code == 200: + return RetVal(phantom.APP_SUCCESS, {}) + + return RetVal( + action_result.set_status(phantom.APP_ERROR, "Empty response and no information in the header"), + None, + ) + + def _process_html_response(self, response, action_result): + # An html response, treat it like an error + status_code = response.status_code + + try: + soup = BeautifulSoup(response.text, "html.parser") + error_text = soup.text + split_lines = error_text.split("\n") + split_lines = [x.strip() for x in split_lines if x.strip()] + error_text = "\n".join(split_lines) + except: + error_text = "Cannot parse error details" + + message = "Status Code: {0}. Data from server:\n{1}\n".format(status_code, error_text) + + message = message.replace("{", "{{").replace("}", "}}") + return RetVal(action_result.set_status(phantom.APP_ERROR, message), None) + + def _process_json_response(self, r, action_result): + # Try a json parse + try: + resp_json = r.json() + except Exception as e: + return RetVal( + action_result.set_status( + phantom.APP_ERROR, + "Unable to parse JSON response. Error: {0}".format(str(e)), + ), + None, + ) + + # Please specify the status codes here + if 200 <= r.status_code < 399: + return RetVal(phantom.APP_SUCCESS, resp_json) + + # You should process the error returned in the json + message = "Error from server. Status Code: {0} Data from server: {1}".format(r.status_code, r.text.replace("{", "{{").replace("}", "}}")) + + return RetVal(action_result.set_status(phantom.APP_ERROR, message), None) + + def _process_response(self, r, action_result): + # store the r_text in debug data, it will get dumped in the logs if the action fails + if hasattr(action_result, "add_debug_data"): + action_result.add_debug_data({"r_status_code": r.status_code}) + action_result.add_debug_data({"r_text": r.text}) + action_result.add_debug_data({"r_headers": r.headers}) + + # Process each 'Content-Type' of response separately + + # Process a json response + if "json" in r.headers.get("Content-Type", ""): + return self._process_json_response(r, action_result) + + # Process an HTML response, Do this no matter what the api talks. + # There is a high chance of a PROXY in between phantom and the rest of + # world, in case of errors, PROXY's return HTML, this function parses + # the error and adds it to the action_result. + if "html" in r.headers.get("Content-Type", ""): + return self._process_html_response(r, action_result) + + # it's not content-type that is to be parsed, handle an empty response + if not r.text or "text" in r.headers.get("Content-Type", ""): + return self._process_empty_response(r, action_result) + + # everything else is actually an error at this point + message = "Can't process response from server. Status Code: {0} Data from server: {1}".format( + r.status_code, r.text.replace("{", "{{").replace("}", "}}") + ) + + return RetVal(action_result.set_status(phantom.APP_ERROR, message), None) + + def _http_request( + self, + url_suffix="", + method="GET", + full_url=None, + headers=None, + auth=None, + params=None, + data=None, + timeout=VDSP_REQUEST_TIMEOUT, + **kwargs, + ) -> Response: + + address = full_url if full_url else tools.urljoin(self._base_url, url_suffix) + headers = headers if headers else self._headers + headers["varonis-integration"] = "Splunk SOAR" + + resp = self._session.request( + method, + address, + verify=self._verify, + params=params, + data=data, + headers=headers, + auth=auth, + timeout=timeout, + **kwargs, + ) + return resp + + def _make_rest_call( + self, + action_result, + url_suffix="", + method="GET", + full_url=None, + headers=None, + auth=None, + params=None, + data=None, + json=None, + timeout=VDSP_REQUEST_TIMEOUT, + **kwargs, + ): + try: + resp = self._http_request( + url_suffix=url_suffix, + method=method, + full_url=full_url, + headers=headers, + auth=auth, + params=params, + data=data, + json=json, + timeout=timeout, + **kwargs, + ) + except Exception as e: + return RetVal( + action_result.set_status( + phantom.APP_ERROR, + "Error Connecting to server. Details: {0}".format(str(e)), + ), + None, + ) + + return self._process_response(resp, action_result) + + def _make_search_call(self, action_result, query: SearchRequest, count: int, page: int = 1) -> RetVal: + + ret_val, results = self._make_rest_call( + action_result=action_result, + url_suffix=VDSP_SEARCH_ENDPOINT, + method="POST", + json=query.to_dict(), + ) + + if phantom.is_fail(ret_val): + self.save_progress("Faild to make search query call.") + return action_result.get_status() + + search_result_location = next(filter(lambda x: (x["dataType"] == "rows"), results))["location"] + + ret_val, results = self._make_rest_call( + action_result=action_result, + url_suffix=f"{VDSP_SEARCH_RESULT_ENDPOINT}/{search_result_location}", + method="GET", + params=get_query_range(count, page), + ) + + if phantom.is_fail(ret_val): + self.save_progress("Faild to get results of search query call.") + return action_result.get_status() + + return ret_val, results + + def _authorize(self, api_key: str) -> Dict[str, Any]: + action_result = self.add_action_result(ActionResult({})) + headers = {"x-api-key": api_key} + ret_val, response = self._make_rest_call( + action_result=action_result, + method="POST", + url_suffix=VDSP_AUTH_ENDPOINT, + data="grant_type=varonis_custom", + headers=headers, + ) + + if phantom.is_fail(ret_val): + self.save_progress(f"Faild to authorize on {VDSP_AUTH_ENDPOINT} endpoint.") + return action_result.get_status() + + self._state[VDSP_ACCESS_TOKEN_KEY] = response[VDSP_ACCESS_TOKEN_KEY] + self._state[VDSP_TOKEN_TYPE_KEY] = response[VDSP_TOKEN_TYPE_KEY] + self._state[VDSP_EXPIRES_IN_KEY] = int(time.time()) + response[VDSP_EXPIRES_IN_KEY] - VDSP_REQUEST_TIMEOUT + + self.debug_print("Expiration time", self._state[VDSP_EXPIRES_IN_KEY]) + + return response + + def _get_alerts_payload( + self, + threat_models: Optional[List[str]] = None, + start_time: Optional[datetime] = None, + end_time: Optional[datetime] = None, + device_names: Optional[List[str]] = None, + last_days: Optional[int] = None, + user_names: Optional[List[str]] = None, + from_ingest_time: Optional[datetime] = None, + alert_statuses: Optional[List[str]] = None, + alert_severities: Optional[List[str]] = None, + descending_order: bool = True, + ) -> SearchRequest: + """Get alerts parameters + + :type threat_models: ``Optional[List[str]]`` + :param threat_models: List of threat models to filter by + + :type start_time: ``Optional[datetime]`` + :param start_time: Start time of the range of alerts + + :type end_time: ``Optional[datetime]`` + :param end_time: End time of the range of alerts + + :type device_names: ``Optional[List[str]]`` + :param device_names: List of device names to filter by + + :type last_days: ``Optional[List[int]]`` + :param last_days: Number of days you want the search to go back to + + :type user_names: ``Optional[List[int]]`` + :param user_names: List of user names + + :type from_alert_id: ``Optional[int]`` + :param from_alert_id: Alert id to fetch from + + :type alert_statuses: ``Optional[List[str]]`` + :param alert_statuses: List of alert statuses to filter by + + :type alert_severities: ``Optional[List[str]]`` + :param alert_severities: List of alert severities to filter by + + :type descendingOrder: ``bool`` + :param descendingOrder: Indicates whether alerts should be ordered in newest to oldest order + + :return: Parameters to be used in get alerts handler + :rtype: ``Dict[str, Any]`` + """ + ingest_time_end = None + if from_ingest_time: + ingest_time_end = datetime.now() + + payload = create_alert_request( + ingest_time_start=from_ingest_time, + ingest_time_end=ingest_time_end, + threat_models=threat_models, + start_time=start_time, + end_time=end_time, + last_days=last_days, + device_names=device_names, + users=user_names, + alert_statuses=alert_statuses, + alert_severities=alert_severities, + descending_order=descending_order, + ) + + return payload + + def _get_alerted_events_payload(self, alert_ids: List[str], descending_order: bool = True) -> SearchRequest: + """Get alerted events parameters + + :type alert_ids: ``List[str]`` + :param alert_ids: List of related alerts + + :return: Parameters to be used in get alerted events handler + :rtype: ``Dict[str, Any]` + """ + payload = create_alerted_events_request(alert_ids, descending_order) + return payload + + def _update_alert_status(self, action_result, query: Dict[str, Any]) -> bool: + """Update alert status + + :type query: ``Dict[str, Any]`` + :param query: Update request body + + :return: Result of execution + :rtype: ``bool`` + + """ + return self._make_rest_call(action_result, VDSP_UPDATE_ALET_STATUS_ENDPOINT, method="POST", json=query) + + def _create_container(self, data: AlertItem): + container = dict() + container["name"] = data.Name + container["source_data_identifier"] = data.ID + container["status"] = data.Status + container["severity"] = data.Severity + container["start_time"] = data.EventUTC.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + container["custom_fields"] = { + "category": data.Category, + "sam_account_name": data.SamAccountName, + "privileged_account_type": data.PrivilegedAccountType, + "asset": data.Asset, + "platform": data.Platform, + "file_server_or_domain": data.FileServerOrDomain, + "contains_flagged_data": data.AssetContainsFlaggedData, + "contains_sensitive_data": data.AssetContainsSensitiveData, + "country": data.Country, + "state": data.State, + "device_name": data.DeviceName, + "ip_threat_types": data.IPThreatTypes, + "contain_malicious_external_ip": data.ContainMaliciousExternalIP, + "blacklist_location": data.BlacklistLocation, + "close_reason": data.CloseReason, + "user_name": data.UserName, + "abnormal_location": data.AbnormalLocation, + } + container["data"] = data.to_dict() + return container + + def _create_artifact(self, data: EventItem): + artifact = dict() + utc_time = data.TimeUTC.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + artifact["name"] = data.Description + artifact["label"] = "event" + artifact["source_data_identifier"] = data.ID + artifact["start_time"] = utc_time + artifact["type"] = data.Type + artifact["data"] = data.to_dict() + return artifact + + # HANDLERS + def _handle_test_connectivity(self, param): + + action_result = self.add_action_result(ActionResult(dict(param))) + self.save_progress("Connecting to endpoint") + + # make rest call + ret_val, _ = self._make_rest_call(action_result, VDSP_TEST_CONNECTION_ENDPOINT) + + if phantom.is_fail(ret_val): + self.save_progress("Test Connectivity Failed.") + return action_result.get_status() + + # Return success + self.save_progress("Test Connectivity Passed") + return action_result.set_status(phantom.APP_SUCCESS) + + def _handle_get_alerts(self, param): + self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + + action_result = self.add_action_result(ActionResult(dict(param))) + + threat_model_names = param.get("threat_model_name", None) + page = param.get("page", 1) + max_results = param.get("max_results", VDSP_MAX_ALERTS) + start_time = param.get("start_time", None) + end_time = param.get("end_time", None) + alert_statuses = param.get("alert_status", None) + alert_severities = param.get("alert_severity", None) + device_names = param.get("device_name", None) + user_names = param.get("user_name", None) + last_days = param.get("last_days", None) + descending_order = param.get("descending_order", True) + + try: + user_names = tools.try_convert(user_names, lambda x: tools.multi_value_to_string_list(x)) + + if last_days: + last_days = tools.try_convert( + last_days, + lambda x: int(x), + ValueError(f"last_days should be integer, but it is {last_days}."), + ) + + if last_days <= 0: + raise ValueError("last_days cannot be less then 1") + + if user_names and len(user_names) > VDSP_MAX_USERS_TO_SEARCH: + raise ValueError(f"cannot provide more then {VDSP_MAX_USERS_TO_SEARCH} users") + + alert_severities = tools.try_convert(alert_severities, lambda x: tools.multi_value_to_string_list(x)) + device_names = tools.try_convert(device_names, lambda x: tools.multi_value_to_string_list(x)) + threat_model_names = tools.try_convert(threat_model_names, lambda x: tools.multi_value_to_string_list(x)) + max_results = tools.try_convert( + max_results, + lambda x: int(x), + ValueError(f"max_results should be integer, but it is {max_results}."), + ) + start_time = tools.try_convert( + start_time, + lambda x: datetime.fromisoformat(x), + ValueError(f"start_time should be in iso format, but it is {start_time}."), + ) + end_time = tools.try_convert( + end_time, + lambda x: datetime.fromisoformat(x), + ValueError(f"end_time should be in iso format, but it is {start_time}."), + ) + + alert_statuses = tools.try_convert(alert_statuses, lambda x: tools.multi_value_to_string_list(x)) + page = tools.try_convert( + page, + lambda x: int(x), + ValueError(f"page should be integer, but it is {page}."), + ) + + if alert_severities: + for severity in alert_severities: + if severity.lower() not in ALERT_SEVERITIES: + raise ValueError(f"There is no severity {severity}. Posible severities: {ALERT_SEVERITIES}") + + if alert_statuses: + for status in alert_statuses: + if status.lower() not in ALERT_STATUSES.keys(): + raise ValueError(f"There is no status {status}.") + + payload = self._get_alerts_payload( + threat_models=threat_model_names, + start_time=start_time, + end_time=end_time, + device_names=device_names, + last_days=last_days, + user_names=user_names, + alert_statuses=alert_statuses, + alert_severities=alert_severities, + descending_order=descending_order, + ) + + self.debug_print("Alert search request payload:", json.dumps(payload.to_dict())) + + ret_val, results = self._make_search_call(action_result, query=payload, page=page, count=max_results) + + self.debug_print("Request completed", ret_val) + + if phantom.is_fail(ret_val): + self.error_print("Get alerts failed.") + return action_result.get_status() + + results = SearchAlertObjectMapper().map(results) + + for res in results: + action_result.add_data(res.to_dict()) + + action_result.update_summary({"alerts_count": len(results)}) + except Exception as e: + self.error_print("Exception occurred while getting alerts.", e) + return action_result.set_status(phantom.APP_ERROR, str(e)) + + return action_result.set_status(phantom.APP_SUCCESS) + + def _handle_update_alert_status(self, param): + self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + + action_result = self.add_action_result(ActionResult(dict(param))) + try: + status = param["status"] + alert_id = param["alert_id"] + + statuses = list(filter(lambda name: name != "closed", ALERT_STATUSES.keys())) + if status.lower() not in statuses: + raise ValueError(f"status must be one of {statuses}.") + + status_id = ALERT_STATUSES[status.lower()] + + query: Dict[str, Any] = { + "AlertGuids": tools.try_convert(alert_id, lambda x: tools.multi_value_to_string_list(x)), + "closeReasonId": CLOSE_REASONS["none"], + "statusId": status_id, + } + + ret_val, response = self._update_alert_status(action_result, query) + + if phantom.is_fail(ret_val): + self.error_print("Update alert status failed.") + return action_result.get_status() + + action_result.add_data(response) + except Exception as ex: + action_result.set_status(phantom.APP_ERROR, str(ex)) + + return action_result.set_status(phantom.APP_SUCCESS) + + def _handle_close_alert(self, param): + self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + + action_result = self.add_action_result(ActionResult(dict(param))) + + try: + alert_id = param["alert_id"] + close_reason = param["close_reason"] + + close_reasons = list(filter(lambda name: not tools.strEqual(name, "none"), CLOSE_REASONS.keys())) + if close_reason.lower() not in close_reasons: + raise ValueError(f"close reason must be one of {close_reasons}") + + alert_ids = tools.try_convert(alert_id, lambda x: tools.multi_value_to_string_list(x)) + close_reason_id = CLOSE_REASONS[close_reason.lower()] + + if len(alert_ids) == 0: + raise ValueError("alert id(s) not specified") + + query: Dict[str, Any] = { + "AlertGuids": alert_ids, + "closeReasonId": close_reason_id, + "statusId": ALERT_STATUSES["closed"], + } + + ret_val, response = self._update_alert_status(action_result, query) + + if phantom.is_fail(ret_val): + self.error_print("Close alert failed.") + return action_result.get_status() + + action_result.add_data(response) + except Exception as ex: + action_result.set_status(phantom.APP_ERROR, str(ex)) + + return action_result.set_status(phantom.APP_SUCCESS) + + def _handle_get_alerted_events(self, param): + self.save_progress("In action handler for: {0}".format(self.get_action_identifier())) + + action_result = self.add_action_result(ActionResult(dict(param))) + try: + alert_ids = tools.multi_value_to_string_list(param["alert_id"]) + page = param.get("page", 1) + count = param.get("max_results", VDSP_MAX_ALERTED_EVENTS) + descending_order = param.get("descending_order", True) + + count = tools.try_convert( + count, + lambda x: int(x), + ValueError(f"max_results should be integer, but it is {count}."), + ) + + page = tools.try_convert( + page, + lambda x: int(x), + ValueError(f"page should be integer, but it is {page}."), + ) + + payload = self._get_alerted_events_payload(alert_ids, descending_order) + + ret_val, results = self._make_search_call(action_result, query=payload, page=page, count=count) + + if phantom.is_fail(ret_val): + self.error_print("Get alerted events failed.") + return action_result.get_status() + + results = SearchEventObjectMapper().map(results) + + for res in results: + action_result.add_data(res.to_dict()) + + action_result.update_summary({"events_count": len(results)}) + except Exception as ex: + action_result.set_status(phantom.APP_ERROR, str(ex)) + + return action_result.set_status(phantom.APP_SUCCESS) + + def _on_poll(self, param): + + action_result = self.add_action_result(ActionResult(dict(param))) + + config = self.get_config() + last_fetched_time = self._state.get(VDSP_LAST_FETCH_TIME, None) + last_fetched_time = tools.try_convert(last_fetched_time, lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S.%f%z")) + ingest_period = config.get(VDSP_INGEST_PERIOD_KEY, VDSP_DEFAULT_INGEST_PERIOD) + is_ingest_artifacts = config.get(VDSP_INGEST_ARTIFACTS_FLAG, True) + alert_status = config.get(VDSP_ALERT_STATUS_KEY, None) + alert_status = tools.multi_value_to_string_list(alert_status) + threat_model = config.get(VDSP_THREAT_MODEL_KEY, None) + threat_model = tools.multi_value_to_string_list(threat_model) + severity = config.get(VDSP_ALERT_SEVERITY_KEY, None) + severity = tools.convert_level(severity, list(ALERT_SEVERITIES.keys())) + + try: + container_count = param.get(phantom.APP_JSON_CONTAINER_COUNT, float("inf")) + start_time = tools.numeric_to_date(ingest_period) + artifact_count = param.get(phantom.APP_JSON_ARTIFACT_COUNT, VDSP_MAX_ALERTED_EVENTS) + + self.save_progress(f"Start ingesting data for interval from {start_time}, amount {container_count}") + + while container_count > 0: + max_alerts = VDSP_MAX_ALERTS if container_count > VDSP_MAX_ALERTS else container_count + container_count -= max_alerts + + alert_payload = self._get_alerts_payload( + start_time=start_time, + from_ingest_time=last_fetched_time, + threat_models=threat_model, + alert_severities=severity, + alert_statuses=alert_status, + descending_order=False, + ) + + self.save_progress(f"Start ingesting data from {last_fetched_time}") + ret_val, alert_results = self._make_search_call(action_result, query=alert_payload, count=max_alerts) + + if phantom.is_fail(ret_val): + self.save_progress("On poll Failed.") + return action_result.get_status() + + self.debug_print("Alert has results:", alert_results["hasResults"]) + + if not alert_results["hasResults"]: + break + + self.debug_print("Request completed", ret_val) + + containers = list() + alert_results = SearchAlertObjectMapper().map(alert_results) + dict_events = None + event_items = [] + + if is_ingest_artifacts: + alert_ids = list(map(lambda x: x.ID, alert_results)) + batch_size = VDSP_MAX_ALERTS + + for batch_alert_ids in tools.batched(alert_ids, batch_size): + event_payload = self._get_alerted_events_payload(batch_alert_ids, descending_order=False) + + ret_val, event_result = self._make_search_call( + action_result, + query=event_payload, + count=artifact_count * batch_size, + ) + + if phantom.is_fail(ret_val): + self.save_progress("On poll Failed while getting alerted events.") + return action_result.get_status() + + event_items.extend(SearchEventObjectMapper().map(event_result)) + + dict_events = tools.group_by(event_items, key_func=lambda x: x.AlertId) + + for alert_res in alert_results: + ingest_time = alert_res.IngestTime + if not last_fetched_time or ingest_time > last_fetched_time: + last_fetched_time = ingest_time + timedelta(seconds=1) + + container = self._create_container(alert_res) + + if dict_events: + artifacts = list(map(self._create_artifact, dict_events[alert_res.ID])) + container["artifacts"] = artifacts + + containers.append(container) + + self.save_progress(f"Prepare {len(containers)} to save.") + ret_val, message, container_responses = self.save_containers(containers) + + for cr in container_responses: + self.save_progress( + "Save container returns, ret_val: {0}, message: {1}, id: {2}".format(cr["success"], cr["message"], cr["id"]) + ) + + if phantom.is_fail(ret_val): + self.save_progress(f"On poll Failed while saving containers. Message: {message}") + return action_result.get_status() + + self._state[VDSP_LAST_FETCH_TIME] = last_fetched_time.strftime("%Y-%m-%dT%H:%M:%S.%f%z") + action_result.update_summary({"alerts_count": len(alert_results)}) + + except Exception as e: + return action_result.set_status(phantom.APP_ERROR, str(e)) + + return action_result.set_status(phantom.APP_SUCCESS) + + def handle_action(self, param): + ret_val = phantom.APP_SUCCESS + + action_id = self.get_action_identifier() + + self.debug_print("action_id", self.get_action_identifier()) + + if action_id == "test_connectivity": + ret_val = self._handle_test_connectivity(param) + + elif action_id == "get_alerts": + ret_val = self._handle_get_alerts(param) + + elif action_id == "update_alert_status": + ret_val = self._handle_update_alert_status(param) + + elif action_id == "close_alert": + ret_val = self._handle_close_alert(param) + + elif action_id == "get_alerted_events": + ret_val = self._handle_get_alerted_events(param) + + elif action_id == phantom.ACTION_ID_INGEST_ON_POLL: + ret_val = self._on_poll(param) + + return ret_val + + def initialize(self): + self._state = self.load_state() + + config = self.get_config() + """ + # Access values in asset config by the name + + # Required values can be accessed directly + required_config_name = config['required_config_name'] + + # Optional values should use the .get() function + optional_config_name = config.get('optional_config_name') + """ + + self._base_url = config.get(VDSP_JSON_BASE_URL_KEY) + self._verify = config.get("verify_server_cert", False) + self._session = requests.Session() + + try: + method_whitelist = "allowed_methods" if hasattr(Retry.DEFAULT, "allowed_methods") else "method_whitelist" + whitelist_kawargs = {method_whitelist: frozenset(["GET", "POST", "PUT"])} + retry = Retry( + total=REQUEST_RETRIES, + read=REQUEST_RETRIES, + connect=REQUEST_RETRIES, + status=REQUEST_RETRIES, + status_forcelist=HTTP_STATUS_WHITE_LIST, + raise_on_status=False, + raise_on_redirect=False, + **whitelist_kawargs, # type: ignore[arg-type] + ) + http_adapter = HTTPAdapter(max_retries=retry) + + self._session.mount("https://", http_adapter) + + except NameError: + pass + + api_key = config.get(VDSP_SCRT) + + try: + state = self._state.get(VDSP_EXPIRES_IN_KEY, -1) + if state < int(time.time()): + self._authorize(api_key) + + self._headers = {"Authorization": f"{self._state[VDSP_TOKEN_TYPE_KEY]} {self._state[VDSP_ACCESS_TOKEN_KEY]}"} + except Exception as e: + self.error_print("Authorization", e) + return phantom.APP_ERROR + + return phantom.APP_SUCCESS + + def finalize(self): + self.save_state(self._state) + return phantom.APP_SUCCESS + + +# MAIN FUNCTION +def main(): + import argparse + + argparser = argparse.ArgumentParser() + + argparser.add_argument("input_test_json", help="Input Test JSON file") + argparser.add_argument("-u", "--username", help="username", required=False) + argparser.add_argument("-p", "--password", help="password", required=False) + argparser.add_argument( + "-v", + "--verify", + action="store_true", + help="verify", + required=False, + default=False, + ) + + args = argparser.parse_args() + session_id = None + + username = args.username + password = args.password + verify = args.verify + + if username is not None and password is None: + + # User specified a username but not a password, so ask + import getpass + + password = getpass.getpass("Password: ") + + if username and password: + try: + login_url = VaronisSaasConnector._get_phantom_base_url() + "/login" + + print("Accessing the Login page") + r = requests.get(login_url, verify=verify, timeout=VDSP_DEFAULT_TIMEOUT) + csrftoken = r.cookies["csrftoken"] + + data = dict() + data["username"] = username + data["password"] = password + data["csrfmiddlewaretoken"] = csrftoken + + headers = dict() + headers["Cookie"] = "csrftoken=" + csrftoken + headers["Referer"] = login_url + + print("Logging into Platform to get the session id") + r2 = requests.post( + login_url, + verify=verify, + data=data, + headers=headers, + timeout=VDSP_DEFAULT_TIMEOUT, + ) + session_id = r2.cookies["sessionid"] + except Exception as e: + print(f"Unable to get session id from the platform. Error: {str(e)}") + sys.exit(1) + + with open(args.input_test_json) as f: + in_json = f.read() + in_json = json.loads(in_json) + print(json.dumps(in_json, indent=4)) + + connector = VaronisSaasConnector() + connector.print_progress_message = True + + if session_id is not None: + in_json["user_session_token"] = session_id + connector._set_csrf_info(csrftoken, headers["Referer"]) + + ret_val = connector._handle_action(json.dumps(in_json), None) + print(json.dumps(json.loads(ret_val), indent=4)) + + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/varonissaas_consts.py b/varonissaas_consts.py new file mode 100644 index 0000000..ed6e0f3 --- /dev/null +++ b/varonissaas_consts.py @@ -0,0 +1,50 @@ +# File: varonissaas_consts.py +# +# Copyright (c) Varonis, 2024 +# +# This unpublished material is proprietary to Varonis SaaS. All +# rights reserved. The methods and techniques described herein are +# considered trade secrets and/or confidential. Reproduction or +# distribution, in whole or in part, is forbidden except by express +# written permission of Varonis SaaS. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language governing permissions +# and limitations under the License. + +# Define your constants here +VDSP_JSON_BASE_URL_KEY = "base_url" +VDSP_AUTH_DATA = "grant_type=client_credentials" +VDSP_SCRT = "api_key" +VDSP_ACCESS_TOKEN_KEY = "access_token" +VDSP_TOKEN_TYPE_KEY = "token_type" +VDSP_EXPIRES_IN_KEY = "expires_in" +VDSP_REQUEST_TIMEOUT = 120 +VDSP_MAX_USERS_TO_SEARCH = 5 +VDSP_MAX_ALERTS = 50 +VDSP_MAX_ALERTED_EVENTS = 5000 +VDSP_THREAT_MODEL_ENUM_ID = 5821 +VDSP_DISPLAY_NAME_KEY = "DisplayName" +VDSP_SAM_ACCOUNT_NAME_KEY = "SAMAccountName" +VDSP_EMAIL_KEY = "Email" +VDSP_AUTH_ENDPOINT = "/api/authentication/api_keys/token" +VDSP_TEST_CONNECTION_ENDPOINT = "/auth/configuration" +VDSP_SEARCH_ENDPOINT = "/app/dataquery/api/search/v2/search" +VDSP_SEARCH_RESULT_ENDPOINT = "/app/dataquery/api/search" +VDSP_UPDATE_ALET_STATUS_ENDPOINT = "/api/alert/alert/SetStatusToAlerts" +VDSP_INGEST_PERIOD_KEY = "ingest_period" +VDSP_INGEST_ARTIFACTS_FLAG = "ingest_artifacts" +VDSP_LAST_FETCH_TIME = "last_fetch_time" +VDSP_DEFAULT_INGEST_PERIOD = "2 week" +VDSP_ALERT_SEVERITY_KEY = "severity" +VDSP_ALERT_STATUS_KEY = "alert_status" +VDSP_THREAT_MODEL_KEY = "threat_model" +VDSP_DEFAULT_TIMEOUT = 30 +VDSP_MAX_DAYS_BACK = 180 diff --git a/varonissaas_search.py b/varonissaas_search.py new file mode 100644 index 0000000..2e1db2e --- /dev/null +++ b/varonissaas_search.py @@ -0,0 +1,902 @@ +# File: varonissaas_search.py +# +# Copyright (c) Varonis, 2024 +# +# This unpublished material is proprietary to Varonis SaaS. All +# rights reserved. The methods and techniques described herein are +# considered trade secrets and/or confidential. Reproduction or +# distribution, in whole or in part, is forbidden except by express +# written permission of Varonis SaaS. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language governing permissions +# and limitations under the License. + +from datetime import datetime, timedelta +from enum import Enum +from typing import Any, Dict, List, Optional, TypeVar + +from varonissaas_consts import VDSP_MAX_DAYS_BACK +from varonissaas_tools import * + +TFilter = TypeVar("TFilter", bound="Filter") +TFilterGroup = TypeVar("TFilterGroup", bound="FilterGroup") +TQuery = TypeVar("TQuery", bound="Query") +TRows = TypeVar("TRows", bound="Rows") +TRequestParams = TypeVar("TRequestParams", bound="RequestParams") +TSearchRequest = TypeVar("TSearchRequest", bound="SearchRequest") +TAlertSearchQueryBuilder = TypeVar("TAlertSearchQueryBuilder", bound="AlertSearchQueryBuilder") +TSearchRequestBuilder = TypeVar("TSearchRequestBuilder", bound="SearchRequestBuilder") +TEventSearchQueryBuilder = TypeVar("TEventSearchQueryBuilder", bound="EventSearchQueryBuilder") + +ALERT_STATUSES = { + "new": 1, + "under investigation": 2, + "closed": 3, + "action required": 4, + "auto-resolved": 5, +} +ALERT_SEVERITIES = {"high": 0, "medium": 1, "low": 2} +CLOSE_REASONS = { + "none": 0, + "other": 1, + "benign activity": 2, + "true positive": 3, + "environment misconfiguration": 4, + "alert recently customized": 5, + "inaccurate alert logic": 6, + "authorized activity": 7, +} + + +""" MODELS """ + + +class EmOperator(Enum): + In = 1 + NotIn = 2 + Between = 3 + Equals = 4 + NotEquals = 5 + Contains = 6 + NotContains = 7 + LastDays = 10 + IncludesAny = 11 + IncludesAll = 12 + ExcludesAll = 13 + GreaterThan = 14 + LessThan = 0xF + QueryId = 0x10 + NotInQueryId = 17 + IsEmpty = 20 + InNestedSearch = 21 + NotInNestedSearch = 22 + HasValue = 23 + + +class FilterOperator(Enum): + And = 0 + Or = 1 + + +class Filter: + def __init__(self): + self.path = None + self.operator = None + self.values = [] + + def set_path(self: TFilter, path: str) -> TFilter: + self.path = path + return self + + def set_operator(self: TFilter, operator: EmOperator) -> TFilter: + self.operator = operator.value + return self + + def add_value(self: TFilter, value: Any) -> TFilter: + self.values.append(value) # FilterValue(value) + return self + + def __repr__(self) -> str: + return f"{self.path} {self.operator} {self.values}" + + +class FilterGroup: + def __init__(self): + self.filterOperator = None + self.filters = [] + + def set_filter_operator(self: TFilterGroup, filter_operator: FilterOperator) -> TFilterGroup: + self.filterOperator = filter_operator.value + return self + + def add_filter(self: TFilterGroup, filter_: Filter) -> TFilterGroup: + self.filters.append(filter_) + return self + + def __repr__(self) -> str: + return f"Filter Operator: {self.filterOperator}, Filters: {self.filters}" + + +class Query: + def __init__(self): + self.entityName = None + self.filter = FilterGroup() + + def set_entity_name(self: TQuery, entity_name: str) -> TQuery: + self.entityName = entity_name + return self + + def set_filter(self: TQuery, filter_: FilterGroup) -> TQuery: + self.filter = filter_ + return self + + def __repr__(self) -> str: + return f"Entity Name: {self.entityName}, Filter: {self.filter}" + + +class Rows: + def __init__(self): + self.columns = [] + self.filter = [] + self.grouping = None + self.ordering = [] + + def set_columns(self: TRows, columns: List[str]) -> TRows: + self.columns = columns + return self + + def add_filter(self: TRows, filter_) -> TRows: + self.filter.append(filter_) + return self + + def add_ordering(self: TRows, ordering) -> TRows: + self.ordering.append(ordering) + return self + + def __repr__(self) -> str: + return f"Columns: {self.columns}, Filter: {self.filter}, Grouping: {self.grouping}, Ordering: {self.ordering}" + + +class RequestParams: + def __init__(self): + self.searchSource = None + self.searchSourceName = None + + def set_search_source(self: TRequestParams, search_source: int) -> TRequestParams: + self.searchSource = search_source + return self + + def set_search_source_name(self: TRequestParams, search_source_name: str) -> TRequestParams: + self.searchSourceName = search_source_name + return self + + def __repr__(self) -> str: + return f"Search Source: {self.searchSource}, Search Source Name: {self.searchSourceName}" + + +class SearchRequest: + def __init__(self): + self.query = Query() + self.rows = Rows() + self.requestParams = RequestParams() + + def set_query(self: TSearchRequest, query: Query) -> TSearchRequest: + self.query = query + return self + + def set_rows(self: TSearchRequest, rows: Rows) -> TSearchRequest: + self.rows = rows + return self + + def set_request_params(self: TSearchRequest, request_params: RequestParams) -> TSearchRequest: + self.requestParams = request_params + return self + + def __repr__(self) -> str: + return f"Query: {self.query}, Rows: {self.rows}, Request Params: {self.requestParams}" + + def to_dict(self) -> str: + result = object_to_dict(self) + return result + + def __eq__(self, __value: object) -> bool: + if isinstance(__value, dict): + return self.to_dict() == __value + elif isinstance(self, type(__value)): + return self.to_dict() == __value.to_dict() + else: + return False + + +class AlertAttributes: + Id = "Alert.ID" + RuleName = "Alert.Rule.Name" + RuleId = "Alert.Rule.ID" + Time = "Alert.TimeUTC" + RuleSeverityName = "Alert.Rule.Severity.Name" + RuleSeverityId = "Alert.Rule.Severity.ID" + RuleCategoryName = "Alert.Rule.Category.Name" + LocationCountryName = "Alert.Location.CountryName" + LocationSubdivisionName = "Alert.Location.SubdivisionName" + StatusName = "Alert.Status.Name" + StatusId = "Alert.Status.ID" + EventsCount = "Alert.EventsCount" + InitialEventUtcTime = "Alert.Initial.Event.TimeUTC" + UserName = "Alert.User.Name" + UserSamAccountName = "Alert.User.SamAccountName" + UserAccountTypeName = "Alert.User.AccountType.Name" + DeviceHostname = "Alert.Device.HostName" + DeviceIsMaliciousExternalIp = "Alert.Device.IsMaliciousExternalIP" + DeviceExternalIpThreatTypesName = "Alert.Device.ExternalIPThreatTypesName" + DataIsFlagged = "Alert.Data.IsFlagged" + DataIsSensitive = "Alert.Data.IsSensitive" + FilerPlatformName = "Alert.Filer.Platform.Name" + AssetPath = "Alert.Asset.Path" + FilerName = "Alert.Filer.Name" + CloseReasonName = "Alert.CloseReason.Name" + LocationBlacklistedLocation = "Alert.Location.BlacklistedLocation" + LocationAbnormalLocation = "Alert.Location.AbnormalLocation" + SidId = "Alert.User.SidID" + Aggregate = "Alert.AggregationFilter" + IngestTime = "Alert.IngestTime" + UserIdentityName = "Alert.User.Identity.Name" + + Columns = [ + Id, + RuleName, + RuleId, + Time, + RuleSeverityName, + RuleSeverityId, + RuleCategoryName, + LocationCountryName, + LocationSubdivisionName, + StatusName, + StatusId, + EventsCount, + InitialEventUtcTime, + UserName, + UserSamAccountName, + UserAccountTypeName, + DeviceHostname, + DeviceIsMaliciousExternalIp, + DeviceExternalIpThreatTypesName, + DataIsFlagged, + DataIsSensitive, + FilerPlatformName, + AssetPath, + FilerName, + CloseReasonName, + LocationBlacklistedLocation, + LocationAbnormalLocation, + SidId, + IngestTime, + ] + + +class EventAttributes: + EventAlertId = "Event.Alert.ID" + EventGuid = "Event.ID" + EventTypeName = "Event.Type.Name" + EventTimeUtc = "Event.TimeUTC" + EventStatusName = "Event.Status.Name" + EventDescription = "Event.Description" + EventLocationCountryName = "Event.Location.Country.Name" + EventLocationSubdivisionName = "Event.Location.Subdivision.Name" + EventLocationBlacklistedLocation = "Event.Location.BlacklistedLocation" + EventOperationName = "Event.Operation.Name" + EventByAccountIdentityName = "Event.ByAccount.Identity.Name" + EventByAccountTypeName = "Event.ByAccount.Type.Name" + EventByAccountDomainName = "Event.ByAccount.Domain.Name" + EventByAccountSamAccountName = "Event.ByAccount.SamAccountName" + EventFilerName = "Event.Filer.Name" + EventFilerPlatformName = "Event.Filer.Platform.Name" + EventIp = "Event.IP" + EventDeviceExternalIp = "Event.Device.ExternalIP.IP" + EventDestinationIp = "Event.Destination.IP" + EventDeviceName = "Event.Device.Name" + EventDestinationDeviceName = "Event.Destination.DeviceName" + EventByAccountIsDisabled = "Event.ByAccount.IsDisabled" + EventByAccountIsStale = "Event.ByAccount.IsStale" + EventByAccountIsLockout = "Event.ByAccount.IsLockout" + EventDeviceExternalIpThreatTypesName = "Event.Device.ExternalIP.ThreatTypes.Name" + EventDeviceExternalIpIsMalicious = "Event.Device.ExternalIP.IsMalicious" + EventDeviceExternalIpReputationName = "Event.Device.ExternalIP.Reputation.Name" + EventOnObjectName = "Event.OnObjectName" + EventOnResourceObjectTypeName = "Event.OnResource.ObjectType.Name" + EventOnAccountSamAccountName = "Event.OnAccount.SamAccountName" + EventOnResourceIsSensitive = "Event.OnResource.IsSensitive" + EventOnAccountIsDisabled = "Event.OnAccount.IsDisabled" + EventOnAccountIsLockout = "Event.OnAccount.IsLockout" + EventOnResourcePath = "Event.OnResource.Path" + + Columns = [ + EventAlertId, + EventGuid, + EventTypeName, + EventTimeUtc, + EventStatusName, + EventDescription, + EventLocationCountryName, + EventLocationSubdivisionName, + EventLocationBlacklistedLocation, + EventOperationName, + EventByAccountIdentityName, + EventByAccountTypeName, + EventByAccountDomainName, + EventByAccountSamAccountName, + EventFilerName, + EventFilerPlatformName, + EventIp, + EventDeviceExternalIp, + EventDestinationIp, + EventDeviceName, + EventDestinationDeviceName, + EventByAccountIsDisabled, + EventByAccountIsStale, + EventByAccountIsLockout, + EventDeviceExternalIpThreatTypesName, + EventDeviceExternalIpIsMalicious, + EventDeviceExternalIpReputationName, + EventOnObjectName, + EventOnResourceObjectTypeName, + EventOnAccountSamAccountName, + EventOnResourceIsSensitive, + EventOnAccountIsDisabled, + EventOnAccountIsLockout, + EventOnResourcePath, + ] + + +class ThreatModelAttributes: + Id = "ruleID" + Name = "ruleName" + Category = "ruleArea" + Source = "ruleSource" + Severity = "severity" + + Columns = [Id, Name, Category, Source, Severity] + + +class AlertItem: + def __init__(self): + self.ID: str = None + self.Name: str = None + self.Time: datetime = None + self.Severity: str = None + self.SeverityId: int = None + self.Category: str = None + self.Country: Optional[List[str]] = None + self.State: Optional[List[str]] = None + self.Status: str = None + self.StatusId: int = None + self.CloseReason: Optional[str] = None + self.BlacklistLocation: Optional[bool] = None + self.AbnormalLocation: Optional[str] = None + self.NumOfAlertedEvents: int = None + self.UserName: Optional[str] = None + self.SamAccountName: Optional[str] = None + self.PrivilegedAccountType: Optional[str] = None + self.ContainMaliciousExternalIP: Optional[bool] = None + self.IPThreatTypes: Optional[str] = None + self.Asset: Optional[str] = None + self.AssetContainsFlaggedData: Optional[bool] = None + self.AssetContainsSensitiveData: Optional[bool] = None + self.Platform: str = None + self.FileServerOrDomain: str = None + self.EventUTC: Optional[datetime] = None + self.DeviceName: str = None + self.IngestTime: datetime = None + + self.Url: str = None + + def __getitem__(self, key: str) -> Any: + if hasattr(self, key): + return getattr(self, key) + raise KeyError(f"{key} not found in AlertItem") + + def to_dict(self) -> Dict[str, Any]: + return object_to_dict(self) + + +class EventItem: + def __init__(self): + self.ID: Optional[str] = None + self.AlertId: Optional[str] = None + self.Type: Optional[str] = None + self.TimeUTC: Optional[datetime] = None + self.Status: Optional[str] = None + self.Description: Optional[str] = None + self.Country: Optional[str] = None + self.State: Optional[str] = None + self.BlacklistedLocation: Optional[bool] = None + self.EventOperation: Optional[str] = None + self.ByUserAccount: Optional[str] = None + self.ByUserAccountType: Optional[str] = None + self.ByUserAccountDomain: Optional[str] = None + self.BySamAccountName: Optional[str] = None + self.Filer: Optional[str] = None + self.Platform: Optional[str] = None + self.SourceIP: Optional[str] = None + self.ExternalIP: Optional[str] = None + self.DestinationIP: Optional[str] = None + self.SourceDevice: Optional[str] = None + self.DestinationDevice: Optional[str] = None + self.IsDisabledAccount: Optional[bool] = None + self.IsLockoutAccount: Optional[bool] = None + self.IsStaleAccount: Optional[bool] = None + self.IsMaliciousIP: Optional[bool] = None + self.ExternalIPThreatTypes: Optional[str] = None + self.ExternalIPReputation: Optional[str] = None + self.OnObjectName: Optional[str] = None + self.OnObjectType: Optional[str] = None + self.OnSamAccountName: Optional[str] = None + self.IsSensitive: Optional[bool] = None + self.OnAccountIsDisabled: Optional[bool] = None + self.OnAccountIsLockout: Optional[bool] = None + self.Path: Optional[str] = None + + def __getitem__(self, key: str) -> Any: + if hasattr(self, key): + return getattr(self, key) + raise KeyError(f"{key} not found in EventItem") + + def to_dict(self) -> Dict[str, Any]: + return object_to_dict(self) + + +class ThreatModelItem: + def __init__(self): + self.Id: Optional[str] = None + self.Name: Optional[List[str]] = None + self.Category: Optional[str] = None + self.Severity: Optional[str] = None + self.Source: Optional[str] = None + + def __getitem__(self, key: str) -> Any: + if hasattr(self, key): + return getattr(self, key) + raise KeyError(f"{key} not found in EventItem") + + def to_dict(self) -> Dict[str, Any]: + return {key: value for key, value in self.__dict__.items() if value is not None} + + +""" MAPPERS """ + + +class SearchAlertObjectMapper: + + def map(self, json_data: Dict[str, Any]) -> List[AlertItem]: + key_valued_objects = convert_json_to_key_value(json_data) + + mapped_items = [] + for obj in key_valued_objects: + mapped_items.append(self.map_item(obj)) + + return mapped_items + + def map_item(self, row: Dict[str, Any]) -> AlertItem: + alert_item = AlertItem() + alert_item.ID = row[AlertAttributes.Id] + alert_item.Name = row[AlertAttributes.RuleName] + alert_item.Time = row[AlertAttributes.Time] + alert_item.Severity = row[AlertAttributes.RuleSeverityName] + alert_item.SeverityId = try_convert(row[AlertAttributes.RuleSeverityId], lambda x: int(x)) + alert_item.Category = row[AlertAttributes.RuleCategoryName] + alert_item.Country = row[AlertAttributes.LocationCountryName] + alert_item.State = row[AlertAttributes.LocationSubdivisionName] + alert_item.Status = row[AlertAttributes.StatusName] + alert_item.StatusId = try_convert(row[AlertAttributes.StatusId], lambda x: int(x)) + alert_item.CloseReason = row[AlertAttributes.CloseReasonName] + alert_item.BlacklistLocation = row.get(AlertAttributes.LocationBlacklistedLocation) + alert_item.AbnormalLocation = row[AlertAttributes.LocationAbnormalLocation] + alert_item.NumOfAlertedEvents = try_convert(row[AlertAttributes.EventsCount], lambda x: int(x)) + alert_item.UserName = row[AlertAttributes.UserName] + alert_item.SamAccountName = row[AlertAttributes.UserSamAccountName] + alert_item.PrivilegedAccountType = row[AlertAttributes.UserAccountTypeName] + alert_item.ContainMaliciousExternalIP = try_convert( + row.get(AlertAttributes.DeviceIsMaliciousExternalIp), + lambda x: parse_bool_list(x), + ) + alert_item.IPThreatTypes = row[AlertAttributes.DeviceExternalIpThreatTypesName] + alert_item.Asset = row[AlertAttributes.AssetPath] + alert_item.AssetContainsFlaggedData = try_convert(row[AlertAttributes.DataIsFlagged], lambda x: parse_bool_list(x)) + alert_item.AssetContainsSensitiveData = try_convert(row[AlertAttributes.DataIsSensitive], lambda x: parse_bool_list(x)) + alert_item.Platform = row[AlertAttributes.FilerPlatformName] + alert_item.FileServerOrDomain = row[AlertAttributes.FilerName] + alert_item.DeviceName = row[AlertAttributes.DeviceHostname] + alert_item.IngestTime = try_convert( + row.get(AlertAttributes.IngestTime), + lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S").replace(tzinfo=timezone.utc), + ) + alert_item.EventUTC = try_convert( + row.get(AlertAttributes.InitialEventUtcTime), + lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S").replace(tzinfo=timezone.utc), + ) + + return alert_item + + +class SearchEventObjectMapper: + + def map(self, json_data: Dict[str, Any]) -> List[EventItem]: + key_valued_objects = convert_json_to_key_value(json_data) + + mapped_items = [] + for obj in key_valued_objects: + mapped_items.extend(self.map_item(obj)) + + return mapped_items + + def map_item(self, row: Dict[str, Any]) -> List[EventItem]: + alertIds = row.get(EventAttributes.EventAlertId) + alertIds = multi_value_to_string_list(alertIds) + + event_items = [] + + for alertId in alertIds: + event_item = EventItem() + + event_item.AlertId = alertId + event_item.ID = row.get(EventAttributes.EventGuid, "") + event_item.Type = row.get(EventAttributes.EventTypeName) + event_item.TimeUTC = try_convert( + row.get(EventAttributes.EventTimeUtc), + lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S.%f%z").replace(tzinfo=timezone.utc), + ) + event_item.Status = row.get(EventAttributes.EventStatusName) + event_item.Description = row.get(EventAttributes.EventDescription) + event_item.Country = row.get(EventAttributes.EventLocationCountryName) + event_item.State = row.get(EventAttributes.EventLocationSubdivisionName) + event_item.BlacklistedLocation = try_convert( + row.get(EventAttributes.EventLocationBlacklistedLocation), + lambda x: parse_bool(x), + ) + event_item.EventOperation = row.get(EventAttributes.EventOperationName) + event_item.ByUserAccount = row.get(EventAttributes.EventByAccountIdentityName) + event_item.ByUserAccountType = row.get(EventAttributes.EventByAccountTypeName) + event_item.ByUserAccountDomain = row.get(EventAttributes.EventByAccountDomainName) + event_item.BySamAccountName = row.get(EventAttributes.EventByAccountSamAccountName) + event_item.Filer = row.get(EventAttributes.EventFilerName) + event_item.Platform = row.get(EventAttributes.EventFilerPlatformName) + event_item.SourceIP = row.get(EventAttributes.EventIp) + event_item.ExternalIP = row.get(EventAttributes.EventDeviceExternalIp) + event_item.DestinationIP = row.get(EventAttributes.EventDestinationIp) + event_item.SourceDevice = row.get(EventAttributes.EventDeviceName) + event_item.DestinationDevice = row.get(EventAttributes.EventDestinationDeviceName) + event_item.IsDisabledAccount = try_convert( + row.get(EventAttributes.EventByAccountIsDisabled), + lambda x: parse_bool(x), + ) + event_item.IsLockoutAccount = try_convert( + row.get(EventAttributes.EventByAccountIsLockout), + lambda x: parse_bool(x), + ) + event_item.IsStaleAccount = try_convert(row.get(EventAttributes.EventByAccountIsStale), lambda x: parse_bool(x)) + event_item.IsMaliciousIP = try_convert( + row.get(EventAttributes.EventDeviceExternalIpIsMalicious), + lambda x: parse_bool(x), + ) + event_item.ExternalIPThreatTypes = row.get(EventAttributes.EventDeviceExternalIpThreatTypesName, "") + event_item.ExternalIPReputation = row.get(EventAttributes.EventDeviceExternalIpReputationName) + event_item.OnObjectName = row.get(EventAttributes.EventOnObjectName) + event_item.OnObjectType = row.get(EventAttributes.EventOnResourceObjectTypeName) + event_item.OnSamAccountName = row.get(EventAttributes.EventOnAccountSamAccountName) + event_item.IsSensitive = try_convert( + row.get(EventAttributes.EventOnResourceIsSensitive), + lambda x: parse_bool(x), + ) + event_item.OnAccountIsDisabled = try_convert( + row.get(EventAttributes.EventOnAccountIsDisabled), + lambda x: parse_bool(x), + ) + event_item.OnAccountIsLockout = try_convert( + row.get(EventAttributes.EventOnAccountIsLockout), + lambda x: parse_bool(x), + ) + event_item.Path = row.get(EventAttributes.EventOnResourcePath) + event_items.append(event_item) + + return event_items + + +class ThreatModelObjectMapper: + def map(self, json_data) -> List[Dict[str, Any]]: + key_valued_objects = json_data + + mapped_items = [] + for obj in key_valued_objects: + mapped_items.append(self.map_item(obj).to_dict()) + + return mapped_items + + def map_item(self, row: Dict[str, str]) -> ThreatModelItem: + threat_model_item = ThreatModelItem() + threat_model_item.ID = row[ThreatModelAttributes.Id] + threat_model_item.Name = row[ThreatModelAttributes.Name] + threat_model_item.Category = row[ThreatModelAttributes.Category] + threat_model_item.Source = row[ThreatModelAttributes.Source] + threat_model_item.Severity = row[ThreatModelAttributes.Severity] + + return threat_model_item + + +class AlertSearchQueryBuilder: + def __init__(self): + self.search_query = Query().set_entity_name("Alert").set_filter(FilterGroup().set_filter_operator(FilterOperator.And)) + + def with_severities(self: TAlertSearchQueryBuilder, severities: List[str]) -> TAlertSearchQueryBuilder: + if severities: + severity_condition = Filter().set_path(AlertAttributes.RuleSeverityId).set_operator(EmOperator.In) + for severity in severities: + severity_id = ALERT_SEVERITIES[severity.lower()] + severity_condition.add_value( + { + AlertAttributes.RuleSeverityId: severity_id, + "displayValue": severity, + } + ) + self.search_query.filter.add_filter(severity_condition) + return self + + def with_threat_models(self: TAlertSearchQueryBuilder, threat_models: List[str]) -> TAlertSearchQueryBuilder: + if threat_models: + rule_condition = Filter().set_path(AlertAttributes.RuleName).set_operator(EmOperator.In) + for threat_model in threat_models: + rule_condition.add_value({AlertAttributes.RuleName: threat_model, "displayValue": "New"}) + self.search_query.filter.add_filter(rule_condition) + return self + + def with_alert_ids(self: TAlertSearchQueryBuilder, alert_ids: List[str]) -> TAlertSearchQueryBuilder: + if alert_ids: + alert_condition = Filter().set_path(AlertAttributes.Id).set_operator(EmOperator.In) + for alert_id in alert_ids: + alert_condition.add_value({AlertAttributes.Id: alert_id, "displayValue": "New"}) + self.search_query.filter.add_filter(alert_condition) + return self + + def with_device(self: TAlertSearchQueryBuilder, devices: List[str]) -> TAlertSearchQueryBuilder: + if devices: + device_condition = Filter().set_path(AlertAttributes.DeviceHostname).set_operator(EmOperator.In) + for device in devices: + device_condition.add_value({AlertAttributes.DeviceHostname: device, "displayValue": device}) + self.search_query.filter.add_filter(device_condition) + return self + + def with_users(self: TAlertSearchQueryBuilder, users: List[str]) -> TAlertSearchQueryBuilder: + if users: + user_condition = Filter().set_path(AlertAttributes.UserIdentityName).set_operator(EmOperator.In) + for user_name in users: + user_condition.add_value( + { + AlertAttributes.UserIdentityName: user_name, + "displayValue": user_name, + } + ) + self.search_query.filter.add_filter(user_condition) + return self + + def with_statuses(self: TAlertSearchQueryBuilder, statuses: List[str]) -> TAlertSearchQueryBuilder: + if statuses: + status_condition = Filter().set_path(AlertAttributes.StatusId).set_operator(EmOperator.In) + for status in statuses: + status_id = ALERT_STATUSES[status.lower()] + status_condition.add_value({AlertAttributes.StatusId: status_id, "displayValue": status}) + self.search_query.filter.add_filter(status_condition) + return self + + def with_time_range( + self: TAlertSearchQueryBuilder, + start_time: Optional[datetime], + end_time: Optional[datetime], + ) -> TAlertSearchQueryBuilder: + days_back = VDSP_MAX_DAYS_BACK + if start_time is None and end_time is not None: + start_time = end_time - timedelta(days=days_back) + elif end_time is None and start_time is not None: + end_time = start_time + timedelta(days=days_back) + + if start_time and end_time: + time_condition = ( + Filter() + .set_path(AlertAttributes.Time) + .set_operator(EmOperator.Between) + .add_value( + { + AlertAttributes.Time: start_time.isoformat(), + f"{AlertAttributes.Time}0": end_time.isoformat(), + } + ) + ) + self.search_query.filter.add_filter(time_condition) + return self + + def with_ingest_time_range( + self: TAlertSearchQueryBuilder, + start: Optional[datetime], + end: Optional[datetime], + ) -> TAlertSearchQueryBuilder: + if start and end: + ingest_time_condition = ( + Filter() + .set_path(AlertAttributes.IngestTime) + .set_operator(EmOperator.Between) + .add_value( + { + AlertAttributes.IngestTime: start.isoformat(), + f"{AlertAttributes.IngestTime}0": end.isoformat(), + } + ) + ) + self.search_query.filter.add_filter(ingest_time_condition) + return self + + def with_last_days(self: TAlertSearchQueryBuilder, last_days: Optional[int]) -> TAlertSearchQueryBuilder: + if last_days: + time_condition = ( + Filter() + .set_path(AlertAttributes.Time) + .set_operator(EmOperator.LastDays) + .add_value({AlertAttributes.Time: last_days, "displayValue": last_days}) + ) + self.search_query.filter.add_filter(time_condition) + return self + + def with_aggregation(self: TAlertSearchQueryBuilder) -> TAlertSearchQueryBuilder: + aggregation = Filter().set_path(AlertAttributes.Aggregate).set_operator(EmOperator.Equals).add_value({AlertAttributes.Aggregate: 1}) + self.search_query.filter.add_filter(aggregation) + return self + + def build(self) -> Query: + return self.search_query + + +class EventSearchQueryBuilder: + def __init__( + self, + ): + self.search_query = Query().set_entity_name("Event").set_filter(FilterGroup().set_filter_operator(FilterOperator.And)) + + def with_alert_ids(self: TEventSearchQueryBuilder, alert_ids: List[str]) -> TEventSearchQueryBuilder: + if alert_ids: + event_condition = Filter().set_path(EventAttributes.EventAlertId).set_operator(EmOperator.In) + for alert_id in alert_ids: + event_condition.add_value({EventAttributes.EventAlertId: alert_id}) + self.search_query.filter.add_filter(event_condition) + return self + + def with_time_range( + self: TEventSearchQueryBuilder, + start_time: Optional[datetime], + end_time: Optional[datetime], + ) -> TEventSearchQueryBuilder: + days_back = VDSP_MAX_DAYS_BACK + if start_time is None and end_time is not None: + start_time = end_time - timedelta(days=days_back) + elif end_time is None and start_time is not None: + end_time = start_time + timedelta(days=days_back) + + if start_time and end_time: + time_condition = ( + Filter() + .set_path(EventAttributes.EventTimeUtc) + .set_operator(EmOperator.Between) + .add_value( + { + EventAttributes.EventTimeUtc: start_time.isoformat(), + f"{EventAttributes.EventTimeUtc}0": end_time.isoformat(), + } + ) + ) + self.search_query.filter.add_filter(time_condition) + return self + + def with_last_days(self: TEventSearchQueryBuilder, last_days: Optional[int]) -> TEventSearchQueryBuilder: + if last_days: + time_condition = ( + Filter() + .set_path(EventAttributes.EventTimeUtc) + .set_operator(EmOperator.LastDays) + .add_value({EventAttributes.EventTimeUtc: last_days, "displayValue": last_days}) + ) + self.search_query.filter.add_filter(time_condition) + return self + + def build(self) -> Query: + return self.search_query + + +class SearchRequestBuilder: + def __init__(self, query: Query, attribute_paths: List[str]): + self.query = query + self.rows = Rows().set_columns(attribute_paths) + self.request_params = RequestParams() + + def with_ordering(self: TSearchRequestBuilder, column: str, desc: bool) -> TSearchRequestBuilder: + self.rows.add_ordering({"Path": column, "SortOrder": "Desc" if desc else "Asc"}) + return self + + def with_request_params(self: TSearchRequestBuilder, source: int, source_name: str) -> TSearchRequestBuilder: + self.request_params.set_search_source_name(source_name).set_search_source(source) + return self + + def build(self) -> SearchRequest: + request = SearchRequest() + request.set_query(self.query).set_rows(self.rows).set_request_params(self.request_params) + return request + + +def create_alert_request( + threat_models: Optional[List[str]] = None, + start_time: Optional[datetime] = None, + end_time: Optional[datetime] = None, + ingest_time_start: Optional[datetime] = None, + ingest_time_end: Optional[datetime] = None, + device_names: Optional[List[str]] = None, + last_days: Optional[int] = None, + users: Optional[List[str]] = None, + alert_statuses: Optional[List[str]] = None, + alert_severities: Optional[List[str]] = None, + alert_ids: Optional[List[str]] = None, + descending_order: bool = True, +) -> SearchRequest: + + alert_query = ( + AlertSearchQueryBuilder() + .with_threat_models(threat_models) + .with_time_range(start_time, end_time) + .with_ingest_time_range(ingest_time_start, ingest_time_end) + .with_device(device_names) + .with_last_days(last_days) + .with_users(users) + .with_statuses(alert_statuses) + .with_severities(alert_severities) + .with_alert_ids(alert_ids) + .with_aggregation() + .build() + ) + + request = ( + SearchRequestBuilder(alert_query, AlertAttributes.Columns) + .with_ordering(AlertAttributes.IngestTime, descending_order) + .with_request_params(1, "Phantom") + .build() + ) + + return request + + +def create_alerted_events_request(alert_ids: List[str], descending_order=True) -> SearchRequest: + event_query = EventSearchQueryBuilder().with_alert_ids(alert_ids).with_last_days(365).build() + + request = ( + SearchRequestBuilder(event_query, EventAttributes.Columns) + .with_ordering(EventAttributes.EventTimeUtc, descending_order) + .with_request_params(1, "Phantom") + .build() + ) + + return request + + +def get_query_range(count: int, page: int = 1) -> Optional[Dict[str, int]]: + """Generate query for range of the search results + :type count: ``int`` + :param count: Max amount of the search results + :type page: ``int`` + :param page: Current page, depends on count + :return: A query range + :rtype: ``str`` + """ + if count: + return {"from": (page - 1) * count, "to": page * count - 1} + return None diff --git a/varonissaas_test.py b/varonissaas_test.py new file mode 100644 index 0000000..860ee4d --- /dev/null +++ b/varonissaas_test.py @@ -0,0 +1,193 @@ +# File: varonissaas_test.py +# +# Copyright (c) Varonis, 2024 +# +# This unpublished material is proprietary to Varonis SaaS. All +# rights reserved. The methods and techniques described herein are +# considered trade secrets and/or confidential. Reproduction or +# distribution, in whole or in part, is forbidden except by express +# written permission of Varonis SaaS. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language governing permissions +# and limitations under the License. + +import json +import unittest +from unittest.mock import MagicMock + +from phantom.action_result import ActionResult + +from varonissaas_connector import VaronisSaasConnector +from varonissaas_consts import * +from varonissaas_search import ALERT_STATUSES, CLOSE_REASONS + + +class VaronisSaaSTest(unittest.TestCase): + def setUp(self) -> None: + self.connector = VaronisSaasConnector() + self.connector._base_url = "https://test.com" + + def test_handle_get_alerts_empty_param(self): + # Arrange + with open("test_data/get_varonissaas_alerts_empty_param_query.json", "r") as file: + expected_search_query = json.load(file) + with open("test_data/get_varonissaas_alerts_empty_param_response.json", "r") as file: + search_response = json.load(file) + with open("test_data/get_varonissaas_alerts_empty_param_result.json", "r") as file: + expected_result = json.load(file) + + self.connector._make_search_call = MagicMock(return_value=(True, search_response)) + param = {} + action_result = ActionResult(param) + self.connector.add_action_result = MagicMock(return_value=action_result) + + # Act + status = self.connector._handle_get_alerts(param) + actual_result = action_result.get_data() + + # Assert + self.connector._make_search_call.assert_called_once_with(action_result, query=expected_search_query, page=1, count=VDSP_MAX_ALERTS) + self.assertTrue(status) + self.assertEqual( + actual_result, + expected_result, + "handle_get_alerts returns unexpected result.", + ) + + def test_handle_get_alerts(self): + # Arrange + with open("test_data/get_varonissaas_alerts_query.json", "r") as file: + expected_search_query = json.load(file) + with open("test_data/get_varonissaas_alerts_response.json", "r") as file: + search_response = json.load(file) + with open("test_data/get_varonissaas_alerts_result.json", "r") as file: + expected_result = json.load(file) + + self.connector._make_search_call = MagicMock(return_value=(True, search_response)) + param = { + "page": 2, + "max_results": VDSP_MAX_ALERTS, + "descending_order": False, + "threat_model_name": "Capture Access request for varadm,Capture Account authentication for varadm,Capture SYSTEM", + "alert_status": "New,Closed", + "end_time": "2023-12-30T13:59:00+02:00", + "start_time": "2023-12-01T13:00:00+02:00", + "alert_severity": "High, Low, Medium", + "device_name": "dev3cf41col01,dev3cf41dh", + "user_name": "varadm,SYSTEM", + "last_days": "2", + } + action_result = ActionResult(param) + self.connector.add_action_result = MagicMock(return_value=action_result) + + # Act + status = self.connector._handle_get_alerts(param) + actual_result = action_result.get_data() + + # Assert + self.connector._make_search_call.assert_called_once_with(action_result, query=expected_search_query, page=2, count=VDSP_MAX_ALERTS) + self.assertTrue(status) + self.assertEqual( + actual_result, + expected_result, + "handle_get_alerts returns unexpected result.", + ) + action_result = ActionResult(param) + self.connector.add_action_result = MagicMock(return_value=action_result) + + def test_handle_get_alerted_events(self): + with open("test_data/get_varonissaas_alerted_events_query.json", "r") as file: + expected_search_query = json.load(file) + with open("test_data/get_varonissaas_alerted_events_response.json", "r") as file: + search_response = json.load(file) + with open("test_data/get_varonissaas_alerted_events_result.json", "r") as file: + expected_result = json.load(file) + + self.connector._make_search_call = MagicMock(return_value=(True, search_response)) + param = {"alert_id": "EE53B604-087A-499C-88F5-7E97ABA5BD9E,A08C35C2-731A-4EA1-B350-11204EACA972"} + action_result = ActionResult(param) + self.connector.add_action_result = MagicMock(return_value=action_result) + + # Act + status = self.connector._handle_get_alerted_events(param) + actual_result = action_result.get_data() + + # Assert + self.connector._make_search_call.assert_called_once_with( + action_result, + query=expected_search_query, + page=1, + count=VDSP_MAX_ALERTED_EVENTS, + ) + self.assertTrue(status) + self.assertEqual( + actual_result, + expected_result, + "handle_get_alerted_events returns unexpected result.", + ) + + def test_handle_update_alert_status(self): + self.connector._make_rest_call = MagicMock() + param = { + "alert_id": "232c60e4-0f74-4f86-998b-8752a41f7910,176ee376-252c-44e0-a2d6-f8c4443ddec1", + "status": "new", + } + action_result = ActionResult(param) + self.connector.add_action_result = MagicMock(return_value=action_result) + json_data = { + "AlertGuids": [ + "232c60e4-0f74-4f86-998b-8752a41f7910", + "176ee376-252c-44e0-a2d6-f8c4443ddec1", + ], + "closeReasonId": CLOSE_REASONS["none"], + "statusId": ALERT_STATUSES["new"], + } + + status = self.connector._handle_update_alert_status(param) + + self.connector._make_rest_call.assert_called_once_with( + action_result, + VDSP_UPDATE_ALET_STATUS_ENDPOINT, + method="POST", + json=json_data, + ) + self.assertTrue(status) + + def test_handle_close_alert(self): + self.connector._make_rest_call = MagicMock() + param = { + "alert_id": "232c60e4-0f74-4f86-998b-8752a41f7910,176ee376-252c-44e0-a2d6-f8c4443ddec1", + "close_reason": "other", + } + action_result = ActionResult(param) + self.connector.add_action_result = MagicMock(return_value=action_result) + json_data = { + "AlertGuids": [ + "232c60e4-0f74-4f86-998b-8752a41f7910", + "176ee376-252c-44e0-a2d6-f8c4443ddec1", + ], + "closeReasonId": CLOSE_REASONS["other"], + "statusId": ALERT_STATUSES["closed"], + } + + status = self.connector._handle_close_alert(param) + + self.connector._make_rest_call.assert_called_once_with( + action_result, + VDSP_UPDATE_ALET_STATUS_ENDPOINT, + method="POST", + json=json_data, + ) + self.assertTrue(status) + + +if __name__ == "__main__": + unittest.main() diff --git a/varonissaas_tools.py b/varonissaas_tools.py new file mode 100644 index 0000000..1784cf5 --- /dev/null +++ b/varonissaas_tools.py @@ -0,0 +1,258 @@ +# File: varonissaas_test.py +# +# Copyright (c) Varonis, 2024 +# +# This unpublished material is proprietary to Varonis SaaS. All +# rights reserved. The methods and techniques described herein are +# considered trade secrets and/or confidential. Reproduction or +# distribution, in whole or in part, is forbidden except by express +# written permission of Varonis SaaS. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language governing permissions +# and limitations under the License. + +from collections import deque +from datetime import datetime, timezone +from itertools import groupby, islice +from typing import Any, Dict, List, Optional + +import dateparser + + +def try_convert(item, converter, error=None): + """Try to convert item + + :type item: ``Any`` + :param item: An item to convert + + :type converter: ``Any`` + :param converter: Converter function + + :type error: ``Any`` + :param error: Error object that will be raised in case of error convertion + + :return: A converted item or None + :rtype: ``Any`` + """ + if item: + try: + return converter(item) + except Exception: + if error: + raise error + raise + return None + + +def urljoin(url, suffix): + if url[-1:] != "/": + url = url + "/" + + if suffix.startswith("/"): + suffix = suffix[1:] + return url + suffix + + return url + suffix + + +def arg_to_datetime(interval: Any, is_utc=True) -> Optional[datetime]: + """Converts an interval to a datetime + + :type interval: ``Any`` + :param arg: argument to convert + + :type is_utc: ``bool`` + :param is_utc: if True then date converted as utc timezone, otherwise will convert with local timezone. + + :return: + returns an ``datetime`` if conversion works + returns ``None`` if arg is ``None`` + otherwise throws an Exception + :rtype: ``Optional[datetime]`` + """ + + if interval is None: + return None + + if (isinstance(interval, str) and interval.isdigit()) or isinstance(interval, (int, float)): + # timestamp is a str containing digits - we just convert it to int + ms = float(interval) + if ms > 2000000000.0: + # in case timestamp was provided as unix time (in milliseconds) + ms = ms / 1000.0 + + if is_utc: + return datetime.utcfromtimestamp(ms).replace(tzinfo=timezone.utc) + else: + return datetime.fromtimestamp(ms) + if isinstance(interval, str): + # we use dateparser to handle strings either in ISO8601 format, or + # relative time stamps. + # For example: format 2019-10-23T00:00:00 or "3 days", etc + + date = dateparser.parse(interval, settings={"TIMEZONE": "UTC"}) + + if date is None: + # if d is None it means dateparser failed to parse it + raise ValueError('"{}" is not a valid date'.format(interval)) + + return date + + raise ValueError('"{}" is not a valid date+'.format(interval)) + + +def numeric_to_date(interval: Any, is_utc=True) -> Optional[datetime]: + if isinstance(interval, str) and interval.isdigit(): + return arg_to_datetime(f"{interval} day", is_utc) + + return arg_to_datetime(interval, is_utc) + + +def multi_value_to_string_list(arg, separator=","): + """ + Converts a string representation of args to a python list + + :type arg: ``str`` or ``list`` + :param arg: Args to be converted (required) + + :type separator: ``str`` + :param separator: A string separator to separate the strings, the default is a comma. + + :return: A python list of args + :rtype: ``list`` + """ + if not arg: + return [] + if isinstance(arg, list): + return arg + if isinstance(arg, str): + return [s.strip() for s in arg.split(separator)] + return [arg] + + +def strEqual(text1: str, text2: str) -> bool: + if not text1 and not text2: + return True + if not text1 or not text2: + return False + + return text1.casefold() == text2.casefold() + + +def parse_bool(value: str) -> Optional[bool]: + if value: + value = value.lower() + if value == "yes": + return True + if value == "no": + return False + if value == "true": + return True + if value == "false": + return False + if value == "1": + return True + if value == "0": + return False + return None + + +def parse_bool_list(value: str) -> str: + if value: + parsed = [str(parse_bool(x.strip())) for x in value.split(sep=",")] + return ",".join(parsed) + return None + + +def convert_json_to_key_value(data: Dict[str, Any]) -> List[Dict[str, Any]]: + result = [] + for row in data["rows"]: + obj = {} + for col, val in zip(data["columns"], row): + obj[col] = val + result.append(obj) + return result + + +def new_construct(obj: Any) -> Any: + if obj is None: + return None + return [] if isinstance(obj, list) else {} + + +def isliteral(obj: Any): + return isinstance(obj, (int, float, str, bool)) + + +def object_to_dict(obj): + result = new_construct(obj) + queue = deque([(id(obj), obj, result)]) + processed = set() + + while queue: + obj_id, obj, constructed_obj = queue.pop() + if obj_id in processed: + continue + processed.add(obj_id) + + if hasattr(obj, "__dict__"): + obj = vars(obj) + + if isinstance(obj, list): + for val in obj: + if isliteral(val): + constructed_obj.append(val) + elif isinstance(val, datetime): + constructed_obj.append(val.strftime("%Y-%m-%dT%H:%M:%S.%f%z")) + else: + new_obj = new_construct(val) + queue.append((id(val), val, new_obj)) + constructed_obj.append(new_obj) + elif isinstance(obj, dict): + for key, val in obj.items(): + if isliteral(val): + constructed_obj[key] = val + elif isinstance(val, datetime): + constructed_obj[key] = val.strftime("%Y-%m-%dT%H:%M:%S.%f%z") + else: + new_obj = new_construct(val) + constructed_obj[key] = new_obj + queue.append((id(val), val, new_obj)) + + return result + + +def convert_level(level: str, levels: List[str]) -> List[str]: + if level is None: + return [] + result = levels.copy() + for lev in levels: + if level == lev: + break + result.remove(lev) + return result + + +def group_by(data: List[Any], key_func: Any) -> Dict[str, List[Any]]: + data = sorted(data, key=key_func) + grouping = groupby(data, key=key_func) + result = {} + for k, g in grouping: + result[k] = list(g) + return result + + +def batched(iterable, n): + if n < 1: + return [] + it = iter(iterable) + while batch := list(islice(it, n)): + yield batch diff --git a/wheels/py3/tzlocal-5.2-py3-none-any.whl b/wheels/py3/tzlocal-5.2-py3-none-any.whl new file mode 100644 index 0000000..fee6193 Binary files /dev/null and b/wheels/py3/tzlocal-5.2-py3-none-any.whl differ diff --git a/wheels/py39/regex-2024.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl b/wheels/py39/regex-2024.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl new file mode 100644 index 0000000..031140f Binary files /dev/null and b/wheels/py39/regex-2024.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl differ diff --git a/wheels/shared/dateparser-1.1.7-py2.py3-none-any.whl b/wheels/shared/dateparser-1.1.7-py2.py3-none-any.whl new file mode 100644 index 0000000..3d4283e Binary files /dev/null and b/wheels/shared/dateparser-1.1.7-py2.py3-none-any.whl differ diff --git a/wheels/shared/pytz-2024.2-py2.py3-none-any.whl b/wheels/shared/pytz-2024.2-py2.py3-none-any.whl new file mode 100644 index 0000000..b464456 Binary files /dev/null and b/wheels/shared/pytz-2024.2-py2.py3-none-any.whl differ