VaronisSaaS
Streamline alerts and related forensic information from Varonis SaaS.
Analytics & SIEM · Varonis SaaS
Details
| ID | VaronisSaaS |
|---|---|
| Provider | Varonis |
| Category | Analytics & SIEM |
| From Version | 6.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Streamline alerts and related forensic information from Varonis SaaS
Configure Varonis SaaS in Cortex
| Parameter | Description | Required |
|---|---|---|
| Fetch incidents | False | |
| Incident type | False | |
| The FQDN/IP the integration should connect to | True | |
| X-API-Key | True | |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | False | |
| Maximum number of incidents per fetch | False | |
| First fetch time | False | |
| Minimum severity of alerts to fetch | False | |
| Varonis threat model name | Pipe-separated list of threat model names of alerts to fetch. Use “varonis-get-threat-models” command to retrieve the full list | False |
| Varonis alert status | False | |
| Incident Mirroring Direction | Choose the direction to mirror the incident: Outgoing (from Cortex XSOAR to Varonis SaaS). Cortex XSOAR only parameter. | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
varonis-get-threat-models
Get Varonis threat models
Base Command
varonis-get-threat-models
Input
| Argument Name | Description | Required |
|---|---|---|
| name | List of requested threat model names. Pipe (\|) separated and wildcards (*) supported. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| ID | Number | ID of the threat model |
| Name | String | Name of the threat model |
Command example
```!varonis-get-threat-models name="*access to*|Domain controller*"```
#### Context Example
```json
[
{
"ThreatModel.Name": "Abnormal service behavior: access to atypical folders",
"ThreatModel.Category": "Exfiltration",
"ThreatModel.Severity": "3 - Error",
"ThreatModel.Source": "Predefined",
"ThreatModel.ID": 1
},
{
"ThreatModel.Name": "Abnormal service behavior: access to atypical files",
"ThreatModel.Category": "Exfiltration",
"ThreatModel.Severity": "3 - Error",
"ThreatModel.Source": "Predefined",
"ThreatModel.ID": 2
}
]
Human Readable Output
Varonis Alerts
ID Name Category Severity Source 1 Abnormal service behavior: access to atypical folders Exfiltration 3 - Error Predefined \n 2 Abnormal service behavior: access to atypical files Exfiltration 3 - Error Predefined
varonis-get-alerts
Get alerts from Varonis DA
Base Command
varonis-get-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| threat_model_name | List of requested threat models to retrieve. | Optional |
| start_time | Start time (UTC) of alert range. | Optional |
| end_time | End time (UTC) of alert range. | Optional |
| alert_status | List of required alerts status. | Optional |
| alert_severity | List of required alerts severity. | Optional |
| device_name | List of required alerts device name. | Optional |
| user_name | User domain name (cannot be provided without user_name). | Optional |
| last_days | Number of days you want the search to go back to. | Optional |
| extra_fields | Extra fields. | Optional |
| descending_order | Indicates whether alerts should be ordered in newest to oldest order. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Varonis.Alert.ID | Number | Varonis ID for alert |
| Varonis.Alert.Rule.Name | String | Name of retrieved alert |
| Varonis.Alert.TimeUTC | Date | When was the alert triggered |
| Varonis.Alert.Rule.Severity.Name | String | Alert severity |
| Varonis.Alert.Rule.Category.Name | String | Alert category. Options are: - Reconnaissance - Intrusion - Exploitation - Privilege Escalation - Lateral Movement |
| Varonis.Alert.Location.CountryName | String | Name of the country from which the event occurred |
| Varonis.Alert.Location.SubdivisionName | String | Name of the state or regional subdivision from which the event occurred |
| Varonis.Alert.Status.Name | String | Alert state. Options are: - New - Under investigation - Closed |
| Varonis.Alert.CloseReason.Name | String | Reason the alert was closed. Options are: - Other - Benign activity - True positive - Environment misconfiguration - Alert recently customized - Inaccurate alert logic - Authorized activity |
| Varonis.Alert.Location.BlacklistedLocation | Boolean | Whether any of the geographical locations from which an alerted activity originated was on the blacklist at the time the activity occurred |
| Varonis.Alert.Location.AbnormalLocation | Boolean | Whether any of the geographical locations from which an alerted activity originated is new or abnormal to the organization, the user and peers, or only the user |
| Varonis.Alert.EventsCount | Number | Number of events with alerts |
| Varonis.Alert.User.Name | String | Name of the users triggered alerts |
| Varonis.Alert.User.SamAccountName | String | Logon name used to support clients and servers running earlier versions of Windows operating system, such as Windows NT 4.0. In the dashboards (other than the Alert dashboard), this is the SAM account name of the user or group |
| Varonis.Alert.User.AccountType.Name | String | Privileged account associated with the user in the alert. Options are: - Service accounts - Admin accounts - Executive accounts |
| Varonis.Alert.Data.IsFlagged | Boolean | Whether the data affected by the alerted events has global flags |
| Varonis.Alert.Data.IsSensitive | Boolean | Filters according to whether the resource on which the event was performed is sensitive (including subfolders) |
| Varonis.Alert.Filer.Platform.Name | String | Type of platform on which the server resides. For example, Windows, Exchange, or SharePoint |
| Varonis.Alert.Asset.Path | String | Path of the alerted asset |
| Varonis.Alert.Filer.Name | String | Associated file server/domain |
| Varonis.Alert.Device.HostName | String | Name of the device from which the user generated the event |
| Varonis.Alert.Device.IsMaliciousExternalIP | Boolean | Whether the alert contains IPs known to be malicious |
| Varonis.Alert.Device.ExternalIPThreatTypesName | String | Whether the alert contains IPs known to be malicious |
| Varonis.Alert.Status.ID | String | Id for the status of the alert |
| Varonis.Alert.Rule.ID | String | Id for the rule that triggered the alert |
| Varonis.Alert.Rule.Severity.ID | String | Severity level identifier |
| Varonis.Alert.Initial.Event.TimeUTC | Date | UTC time of the initial event that triggered the alert |
| Varonis.Alert.User.SidID | String | Security Identifier (SID) of the user associated with the alert |
| Varonis.Alert.IngestTime | Date | Time when the alert was ingested into the system |
Command example
!varonis-get-alerts start_time="2023-12-01T09:58:00" end_time="2023-12-07T04:16:00" alert_status="New" alert_severity="High" device_name="intfc35adh" threat_model_name="Deletion: Active Directory containers, Foreign Security Principal, or GPO" extra_fields="Alert.MitreTactic.*"
Context Example
[
{
"Alert.Rule.Name": "Deletion: Multiple directory service objects",
"Alert.Rule.Severity.Name": "Medium",
"Alert.TimeUTC": "2023-12-11T03:50:00",
"Alert.Rule.Category.Name": "Denial of Service",
"Alert.User.Name": "varadm (intaf6fb.com)",
"Alert.Status.Name": "New",
"Alert.ID": "A5F4B69A-F5C0-494F-B5B4-185185BC3FBE",
"Alert.Rule.ID": "140",
"Alert.Rule.Severity.ID": "1",
"Alert.Location.CountryName": "",
"Alert.Location.SubdivisionName": "",
"Alert.Status.ID": "1",
"Alert.EventsCount": "14",
"Alert.Initial.Event.TimeUTC": "2023-12-11T03:41:00",
"Alert.User.SamAccountName": "varadm",
"Alert.User.AccountType.Name": "Admin,Executive",
"Alert.Device.HostName": "intaf6fbdh",
"Alert.Device.IsMaliciousExternalIP": "",
"Alert.Device.ExternalIPThreatTypesName": "",
"Alert.Data.IsFlagged": "0",
"Alert.Data.IsSensitive": "0",
"Alert.Filer.Platform.Name": "Active Directory",
"Alert.Asset.Path": "intaf6fb.com(AD-intaf6fb.com)",
"Alert.Filer.Name": "AD-intaf6fb.com",
"Alert.CloseReason.Name": "",
"Alert.Location.BlacklistedLocation": "",
"Alert.Location.AbnormalLocation": "",
"Alert.User.SidID": "971",
"Alert.IngestTime": "2023-12-11T03:52:46",
"Url": "/#/app/analytics/entity/Alert/A5F4B69A-F5C0-494F-B5B4-185185BC3FBE"
}
]
Human Readable Output
Varonis Alerts
Alert.Rule.Name Alert.Rule.Severity.Name Alert.TimeUTC Alert.Rule.Category.Name Alert.User.Name Alert.Status.Name Alert.ID Deletion: Multiple directory service objects Medium 2023-12-11T03:50:00 Denial of Service varadm (intaf6fb.com) New A5F4B69A-F5C0-494F-B5B4-185185BC3FBE
varonis-get-alerted-events
Get events applied to specific alerts
Base Command
varonis-get-alerted-events
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | List of alert IDs. | Required |
| start_time | Start UTC time of alert range. | Optional |
| end_time | End UTC time of alert range. | Optional |
| last_days | Number of days you want the search to go back to. | Optional |
| extra_fields | Extra fields. | Optional |
| descending_order | Indicates whether events should be ordered in newest to oldest order. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Varonis.Event.ID | String | Event ID |
| Varonis.Event.Alert.ID | String | Alert ID |
| Varonis.Event.Type.Name | String | Event type |
| Varonis.Event.TimeUTC | Date | Event time in UTC format |
| Varonis.Event.Status.Name | String | Filters according to the status of the event. Options are: - Fail - Success |
| Varonis.Event.Description | String | Description of the activity |
| Varonis.Event.Location.Country.Name | String | Name of the country from which the event occurred |
| Varonis.Event.Location.Subdivision.Name | String | Name of the state or regional subdivision from which the event occurred |
| Varonis.Event.Device.ExternalIP.IP | String | Device external IP address |
| Varonis.Event.Location.BlacklistedLocation | Boolean | Indicates whether the geographical location from which the event originated was blacklisted |
| Varonis.Event.Operation.Name | String | Type of operation that occurred during the event. Options are: - Accessed - Added - Changed - Removed - Sent - Received - Requested |
| Varonis.Event.ByAccount.Identity.Name | String | Name of the user that triggered the event |
| Varonis.Event.ByAccount.Type.Name | String | Type of account, i.e., user or computer |
| Varonis.Event.ByAccount.SamAccountName | String | SAM account name of the user or group for clients and servers running earlier versions of Windows |
| Varonis.Event.ByAccount.Domain.Name | String | Domain of the user that triggered the event |
| Varonis.Event.ByAccount.IsDisabled | Boolean | Indicates whether the account is disabled |
| Varonis.Event.ByAccount.IsStale | Boolean | Indicates whether the account is stale |
| Varonis.Event.ByAccount.IsLockout | Boolean | Indicates whether the account is locked out |
| Varonis.Event.IP | String | Source IP address of the device that triggered the event |
| Varonis.Event.Device.ExternalIP.IsMalicious | Boolean | Indicates whether the external IP is known to be malicious |
| Varonis.Event.Device.ExternalIP.Reputation.Name | Number | Reputation score of the external IP, a numeric value from 1-100 |
| Varonis.Event.Device.ExternalIP.ThreatTypes.Name | String | List of threat types associated with the external IP |
| Varonis.Event.OnObjectName | String | Name of the object on which the event was performed |
| Varonis.Event.OnResource.ObjectType.Name | String | Type of the object on which the event was performed |
| Varonis.Event.Filer.Platform.Name | String | Type of platform on which the server resides, like Windows, Exchange, SharePoint |
| Varonis.Event.OnResource.IsSensitive | Boolean | Indicates whether the resource on which the event was performed is sensitive |
| Varonis.Event.Filer.Name | String | File server of the object on which the event was performed |
| Varonis.Event.OnAccount.IsDisabled | Boolean | Indicates whether the account is disabled |
| Varonis.Event.OnAccount.IsLockout | Boolean | Indicates whether the account is locked out |
| Varonis.Event.OnAccount.SamAccountName | Boolean | SAM account name of the user or group for clients and servers running earlier versions of Windows |
| Varonis.Event.Destination.IP | String | Destination IP address within the organization |
| Varonis.Event.Device.Name | String | Name of the device that triggered the event |
| Varonis.Event.Destination.DeviceName | String | Destination host name for relevant services |
| Varonis.Event.OnResource.Path | String | Path of the resource |
Command example
varonis-get-alerted-events alert_id="C98A3E72-99E9-4E5C-A560-7D04FA60686E,C83D55F0-EC63-41FC-B8C6-A5A66CB51372" last_days=7 extra_fields="Event.ByAccount.DistinguishedName"
Context Example
[
{
"Event.Type.Name": "DS object deleted",
"Event.Description": "Organizational Unit \"CommitOu_a9c42\" was deleted",
"Event.Filer.Platform.Name": "Active Directory",
"Event.Filer.Name": "AD-intaf6fb.com",
"Event.ByAccount.SamAccountName": "varadm",
"Event.OnObjectName": "CommitOu_a9c42",
"Event.Alert.ID": "A5F4B69A-F5C0-494F-B5B4-185185BC3FBE",
"Event.ID": "7D87B6A2-C9C2-4859-A076-DD4D0EFC8276",
"Event.TimeUTC": "2023-12-11T03:41:08.000Z",
"Event.Status.Name": "Success",
"Event.Location.Country.Name": "",
"Event.Location.Subdivision.Name": "",
"Event.Location.BlacklistedLocation": "",
"Event.Operation.Name": "Deleted",
"Event.ByAccount.Type.Name": "User",
"Event.ByAccount.Domain.Name": "intaf6fb.com",
"Event.ByAccount.Identity.Name": "varadm",
"Event.IP": "",
"Event.Device.ExternalIP.IP": "",
"Event.Destination.IP": "",
"Event.Device.Name": "intaf6fbdh",
"Event.Destination.DeviceName": "",
"Event.ByAccount.IsDisabled": "No",
"Event.ByAccount.IsStale": "No",
"Event.ByAccount.IsLockout": "No",
"Event.Device.ExternalIP.ThreatTypes.Name": "",
"Event.Device.ExternalIP.IsMalicious": "",
"Event.Device.ExternalIP.Reputation.Name": "",
"Event.OnResource.ObjectType.Name": "Organizational unit",
"Event.OnAccount.SamAccountName": "51d4ee86-db4a-4d4a-baaa-1b84e02afd59",
"Event.OnResource.IsSensitive": "",
"Event.OnAccount.IsDisabled": "",
"Event.OnAccount.IsLockout": "",
"Event.OnResource.Path": "intaf6fb.com\\CommitOu_a9c42"
}
]
Human Readable Output
Varonis Alerted Events
Event.Type.Name Event.Description Event.Filer.Platform.Name Event.Filer.Name Event.ByAccount.SamAccountName Event.OnObjectName Event.Alert.ID Event.ID Event.TimeUTC Event.Status.Name Event.Location.Country.Name Event.Location.Subdivision.Name Event.Location.BlacklistedLocation Event.Operation.Name Event.ByAccount.Type.Name Event.ByAccount.Domain.Name Event.ByAccount.Identity.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.OnResource.ObjectType.Name Event.OnAccount.SamAccountName Event.OnResource.IsSensitive Event.OnAccount.IsDisabled Event.OnAccount.IsLockout Event.OnResource.Path DS object deleted Organizational Unit “CommitOu_a9c42” was deleted Active Directory AD-intaf6fb.com varadm CommitOu_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE 7D87B6A2-C9C2-4859-A076-DD4D0EFC8276 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No Organizational unit 51d4ee86-db4a-4d4a-baaa-1b84e02afd59 intaf6fb.com\CommitOu_a9c42 \n DS object deleted User “intaf6fb.com\PolWinRolU_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\PolWinRolU_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE B75C4ECE-48BA-4172-BBB1-68B85E3ABB6F 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User PolWinRolU_a9c42 No No intaf6fb.com\Users\PolWinRolU_a9c42 \n DS object deleted User “intaf6fb.com\Add_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\Add_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE 4800A52F-F8C2-483A-BC39-A68D1AF13D98 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User Add_a9c42 No No intaf6fb.com\Users\Add_a9c42 \n DS object deleted Organizational Unit “CommitOu_a9c42” was deleted Active Directory AD-intaf6fb.com varadm CommitOu_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE,0AB569DA-B58E-4DC5-9FC2-8793BA118C88 DFEE2A16-E0DF-4777-BA8A-390DD869D413 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No Organizational unit 51d4ee86-db4a-4d4a-baaa-1b84e02afd59 intaf6fb.com\CommitOu_a9c42 \n DS object deleted “intaf6fb.com\CommitAdGroup_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\CommitAdGroup_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE FA2F5005-6EFC-46B9-BC95-E88CD3838D1A 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No Group CommitAdGroup_a9c42 intaf6fb.com\Users\CommitAdGroup_a9c42 \n DS object deleted User “intaf6fb.com\RollbackRemove_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\RollbackRemove_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE 0A5A616D-D3CA-4623-A248-18DC0E7AB67A 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User RollbackRemove_a9c42 No No intaf6fb.com\Users\RollbackRemove_a9c42 \n DS object deleted User “intaf6fb.com\Remove_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\Remove_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE 59E8DE00-7F0F-4637-B5DA-BC8842B2533F 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User Remove_a9c42 No No intaf6fb.com\Users\Remove_a9c42 \n DS object deleted “CommitNewGroup_a9c42” was deleted Active Directory AD-intaf6fb.com varadm CommitNewGroup_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE 5CC0C582-C5D6-4ED2-8596-BBBFD0ABB746 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No Group a9dde0e5-1346-4d15-a9dc-0c1337ddab2f intaf6fb.com\CommitOu_a9c42\CommitNewGroup_a9c42 \n DS object deleted User “intaf6fb.com\CommitAdUser_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\CommitAdUser_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE AD3642A0-B90B-4349-ADB1-206749BF18E8 2023-12-11T03:41:08.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User CommitAdUser_a9c42 No No intaf6fb.com\Users\CommitAdUser_a9c42 \n DS object deleted User “intaf6fb.com\RollbackRemove_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\RollbackRemove_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE 015579AF-E357-4D16-AAC0-50B76E7D7104 2023-12-11T03:41:05.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User RollbackRemove_a9c42 No No intaf6fb.com\Users\RollbackRemove_a9c42 \n DS object deleted User “intaf6fb.com\Add_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\Add_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE B38D714B-8D20-4E68-8EFC-709C128C136C 2023-12-11T03:41:05.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User Add_a9c42 No No intaf6fb.com\Users\Add_a9c42 \n DS object deleted User “intaf6fb.com\Remove_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\Remove_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE E5F15080-A7C0-42CF-A911-05627FF26179 2023-12-11T03:41:05.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User Remove_a9c42 No No intaf6fb.com\Users\Remove_a9c42 \n DS object deleted User “intaf6fb.com\CommitAdUser_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\CommitAdUser_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE A9673047-6CDD-4404-805F-38B5CACAC047 2023-12-11T03:41:05.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User CommitAdUser_a9c42 No No intaf6fb.com\Users\CommitAdUser_a9c42 \n DS object deleted User “intaf6fb.com\PolWinRolU_a9c42” was deleted Active Directory AD-intaf6fb.com varadm intaf6fb.com\PolWinRolU_a9c42 A5F4B69A-F5C0-494F-B5B4-185185BC3FBE 967A5AA4-391C-4AB6-BB33-592AACCFB4D2 2023-12-11T03:41:04.000Z Success Deleted User intaf6fb.com varadm intaf6fbdh No No No User PolWinRolU_a9c42 No No intaf6fb.com\Users\PolWinRolU_a9c42
varonis-alert-add-note
Add note to alerts
Base Command
varonis-alert-add-note
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | Requested alerts. | Required |
| note | Note. | Required |
Context Output
There is no context output for this command.
Command example
!varonis-alert-add-note alert_id=C98A3E72-99E9-4E5C-A560-7D04FA60686E note="This needs to be invested ASAP"
varonis-update-alert-status
Update alert status
Base Command
varonis-update-alert-status
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | Requested alerts. | Required |
| status | Alert new status. Possible values are: New, Under Investigation. | Required |
| note | Note. | Optional |
Context Output
There is no context output for this command.
Command example
!varonis-update-alert-status alert_id=C98A3E72-99E9-4E5C-A560-7D04FA60686E status="Under Investigation" note="Waiting for feedback from security team"
varonis-close-alert
Close the alert
Base Command
varonis-close-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | Requested alerts. | Required |
| close_reason | The reason the alert was closed. Possible values are: Other, Benign activity, True positive, Environment misconfiguration, Alert recently customized, Inaccurate alert logic, Authorized activity. | Required |
| note | Note. | Optional |
Context Output
There is no context output for this command.
Command example
!varonis-close-alert alert_id=C98A3E72-99E9-4E5C-A560-7D04FA60686E close_reason="Inaccurate alert logic" note="Alert is irrelevant. Closed"
get-mapping-fields
Returns the list of fields to map in outgoing mirroring. This command is only used for debugging purposes.
Base Command
get-mapping-fields
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
Incident Mirroring
You can enable outgoing incident mirroring between Cortex XSOAR incidents and Varonis alerts (available from Cortex XSOAR version 6.0.0).
To set up the mirroring:
- Enable Fetching incidents in your instance configuration.
-
In the Mirroring Direction integration parameter, select in which direction the incidents should be mirrored (currently only outgoing mirroring is available):
Option Description None Turns off incident mirroring. Outgoing Any changes in Cortex XSOAR incidents will be reflected in Varonis SaaS service (outgoing mirrored fields).
Newly fetched incidents will be mirrored in the chosen direction. However, this selection does not affect existing incidents.
Mirroring Out Notes
The supported fields in the mirroring out process are:
- Varonis Alert Status.
- Varonis Close Reason
- Incident Close Notes
Important Note:
You have two options how to close Varonis Alert:
- The first option is to change the Varonis Alert Status field in the XSOAR incident. In this case, the status of the alert in Varonis SaaS service will be change by the mirroring functionality, but the Incident in XSOAR won’t be closed.
- The second one is to close the incident in XSOAR. In this case, the Varonis Alert will be closed on the Varonis side by the post-processing script.
Configuration parameters
isFetch— Fetch incidentsincidentType— Incident typeincidentFetchInterval— Incidents Fetch Intervalurl— The FQDN/IP the integration should connect to (required)apiKey— (required)proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)max_fetch— Maximum number of incidents per fetchfirst_fetch— First fetch timeseverity— Minimum severity of alerts to fetchthreat_model— Varonis threat model namestatus— Varonis alert statusmirror_direction— Incident Mirroring Direction
Commands (8)
-
get-mapping-fieldsReturns the list of fields to map in outgoing mirroring. This command is only used for debugging purposes.
-
update-remote-systemUpdates the remote incident with local incident changes. This method is only used for debugging purposes and will not update the current incident.
-
varonis-alert-add-noteAdd note to alerts.
-
varonis-close-alertClose the alert.
-
varonis-get-alerted-eventsGet events applied to specific alerts.
-
varonis-get-alertsGet alerts from Varonis DA.
-
varonis-get-threat-modelsGet Varonis threat models.
-
varonis-update-alert-statusUpdate alert status.
import fnmatch import json import traceback from typing import Any import demistomock as demisto from CommonServerPython import * from CommonServerUserPython import * MAX_USERS_TO_SEARCH = 5 MAX_DAYS_BACK = 180 THREAT_MODEL_ENUM_ID = 5821 ALERT_STATUSES = {"new": 1, "under investigation": 2, "closed": 3} ALERT_SEVERITIES = {"high": 0, "medium": 1, "low": 2, "informational": 3} 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, } INCIDENT_FIELDS = [ "ID", "Category", "Name", "Status", "severity", "IPThreatTypes", "CloseReason", "CloseNotes", "NumOfAlertedEvents", "ContainsFlaggedData", "ContainMaliciousExternalIP", "ContainsSensitiveData", "Locations", "Devices", "Users", ] MIRROR_DIRECTION_MAPPING = { "None": None, "Outgoing": "Out", } class AlertAttributes: Alert_ID = "Alert.ID" Alert_Rule_Name = "Alert.Rule.Name" Alert_Rule_ID = "Alert.Rule.ID" Alert_TimeUTC = "Alert.TimeUTC" Alert_Rule_Severity_Name = "Alert.Rule.Severity.Name" Alert_Rule_Severity_ID = "Alert.Rule.Severity.ID" Alert_Rule_Category_Name = "Alert.Rule.Category.Name" Alert_Rule_Category_ID = "Alert.Rule.Category.ID" Alert_Location_CountryName = "Alert.Location.CountryName" Alert_Location_CountryID = "Alert.Location.CountryID" Alert_Location_SubdivisionName = "Alert.Location.SubdivisionName" Alert_Location_SubdivisionID = "Alert.Location.SubdivisionID" Alert_Status_Name = "Alert.Status.Name" Alert_Status_ID = "Alert.Status.ID" Alert_EventsCount = "Alert.EventsCount" Alert_Initial_Event_TimeUTC = "Alert.Initial.Event.TimeUTC" Alert_Initial_Event_TimeLocal = "Alert.Initial.Event.TimeLocal" Alert_User_Name = "Alert.User.Name" Alert_User_SidID = "Alert.User.SidID" Alert_User_Identity_ID = "Alert.User.Identity.ID" Alert_User_Identity_Name = "Alert.User.Identity.Name" Alert_User_IsFlagged = "Alert.User.IsFlagged" Alert_User_AccountType_ID = "Alert.User.AccountType.ID" Alert_User_AccountType_Name = "Alert.User.AccountType.Name" Alert_User_AccountType_AggregatedName = "Alert.User.AccountType.AggregatedName" Alert_User_AccountType_AggregatedID = "Alert.User.AccountType.AggregatedID" Alert_User_SamAccountName = "Alert.User.SamAccountName" Alert_Device_HostName = "Alert.Device.HostName" Alert_Device_IsMaliciousExternalIP = "Alert.Device.IsMaliciousExternalIP" Alert_Device_ExternalIPThreatTypesName = "Alert.Device.ExternalIPThreatTypesName" Alert_Device_ExternalIPThreatTypesID = "Alert.Device.ExternalIPThreatTypesID" Alert_Data_IsFlagged = "Alert.Data.IsFlagged" Alert_Data_IsSensitive = "Alert.Data.IsSensitive" Alert_Filer_Name = "Alert.Filer.Name" Alert_Filer_ID = "Alert.Filer.ID" Alert_Filer_Platform_Name = "Alert.Filer.Platform.Name" Alert_Filer_Platform_ID = "Alert.Filer.Platform.ID" Alert_Asset_Path = "Alert.Asset.Path" Alert_Asset_ID = "Alert.Asset.ID" Alert_CloseReason_Name = "Alert.CloseReason.Name" Alert_CloseReason_ID = "Alert.CloseReason.ID" Alert_Location_AbnormalLocation = "Alert.Location.AbnormalLocation" Alert_Location_AbnormalLocationID = "Alert.Location.AbnormalLocationID" Alert_Location_BlacklistedLocation = "Alert.Location.BlacklistedLocation" Alert_MitreTactic_Name = "Alert.MitreTactic.Name" Alert_MitreTactic_ID = "Alert.MitreTactic.ID" Alert_Time = "Alert.Time" Alert_AggregationFilter = "Alert.AggregationFilter" Alert_IngestTime = "Alert.IngestTime" Columns = [ Alert_Rule_Name, Alert_Rule_Severity_Name, Alert_TimeUTC, Alert_Rule_Category_Name, Alert_User_Name, Alert_Status_Name, Alert_ID, Alert_Rule_ID, Alert_Rule_Severity_ID, Alert_Location_CountryName, Alert_Location_SubdivisionName, Alert_Status_ID, Alert_EventsCount, Alert_Initial_Event_TimeUTC, 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, ] ExtraColumns = [ Alert_Location_CountryID, Alert_Location_SubdivisionID, Alert_User_Identity_ID, Alert_User_Identity_Name, Alert_User_IsFlagged, Alert_User_AccountType_ID, Alert_Device_ExternalIPThreatTypesID, Alert_Filer_ID, Alert_Filer_Platform_ID, Alert_User_AccountType_AggregatedName, Alert_User_AccountType_AggregatedID, Alert_Asset_ID, Alert_CloseReason_ID, Alert_Location_AbnormalLocationID, Alert_MitreTactic_Name, Alert_MitreTactic_ID, Alert_Time, ] def get_fields(self, extra_fields: Optional[list[str]]) -> list[str]: output = self.Columns.copy() if extra_fields: for pattern in extra_fields: match_columns = fnmatch.filter(self.ExtraColumns, pattern) output.extend([item for item in match_columns if item not in output]) return output class AlertItem: def __init__(self, row: dict): self.row = row def __getitem__(self, key: str) -> Any: if hasattr(self.row, key): return getattr(self.row, key) raise KeyError(f"{key} not found in AlertItem") def to_dict(self) -> dict[str, Any]: return self.row class BaseMapper: @staticmethod def convert_json_to_key_value(json_data) -> list[dict[str, Any]]: data = json_data result = [] for row in data["rows"]: obj = {} for col, val in zip(data["columns"], row): obj[col] = val result.append(obj) return result class Client(BaseClient): """Client class to interact with the service API This Client implements API calls, and does not contain any Demisto logic. Should only do requests and return data. It inherits from BaseClient defined in CommonServer Python. Most calls use _http_request() that handles proxy, SSL verification, etc. For this HelloWorld implementation, no special attributes defined """ def __init__(self, base_url, verify=True, proxy=False, ok_codes=(), headers=None, auth=None): super().__init__(base_url, verify, proxy, ok_codes, headers, auth) self._session.verify = verify if not verify and self._session.adapters["https://"] and hasattr(self._session.adapters["https://"], "context"): self._session.adapters["https://"].context.check_hostname = verify self.headers: dict[str, Any] = {} self.headers["authorization"] = None self.headers["content-type"] = "application/json" self.headers["varonis-integration"] = "XSOAR Cortex" def varonis_authenticate(self, apiKey: str) -> dict[str, Any]: headers = {"x-api-key": apiKey, "content-type": "application/x-www-form-urlencoded"} response = self._http_request( "POST", url_suffix="/api/authentication/api_keys/token", data="grant_type=varonis_custom", headers=headers ) token = response["access_token"] token_type = response["token_type"] self._expires_in = response["expires_in"] demisto.debug(f"Token expires in {self._expires_in}") self.headers["authorization"] = f"{token_type} {token}" return response def varonis_search(self, search_query: str, max_fetch: Optional[int] = 1000): create_search = self._http_request("POST", "/app/dataquery/api/search/v2/search", data=search_query, headers=self.headers) url = create_search[0]["location"] url_suffix = f"/app/dataquery/api/search/{url}" if max_fetch: url_suffix += f"?from=0&to={max_fetch - 1}" json_data = self._http_request( method="GET", url_suffix=url_suffix, headers=self.headers, status_list_to_retry=[304, 405, 206], retries=10 ) return json_data def varonis_get_alerts( self, threat_model_names: Optional[list[str]], alertIds: Optional[list[str]], start_time: Optional[datetime], end_time: Optional[datetime], ingest_time_from: Optional[datetime], ingest_time_to: Optional[datetime], device_names: Optional[list[str]], user_names: Optional[list[str]], last_days: Optional[int], alert_statuses: Optional[list[str]], alert_severities: Optional[list[str]], extra_fields: Optional[list[str]], descending_order: bool, max_fetch: Optional[int] = 1000, ) -> list[dict[str, Any]]: """Get alerts :type threat_model_names: ``Optional[List[str]]`` :param threat_model_names: List of threat models to filter by :type alertIds: ``Optional[List[str]]`` :param alertIds: List of alertIds 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 ingest_time_from: ``Optional[datetime]`` :param ingest_time_from: Start ingest time of the range of alerts :type ingest_time_to: ``Optional[datetime]`` :param ingest_time_to: End ingest time of the range of alerts :type device_names: ``Optional[List[str]]`` :param device_names: List of device names to filter by :type user_names: ``Optional[List[str]]`` :param user_names: List of user 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 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 extra_fields: ``Optional[List[str]]`` :param extra_fields: List of extra fields to include in the response :type descendingOrder: ``bool`` :param descendingOrder: Indicates whether alerts should be ordered in newest to oldest order :type max_fetch: ``Optional[int]`` :param max_fetch: Maximum number of items :return: Alerts :rtype: ``List[Dict[str, Any]]`` """ search_request = ( SearchRequest() .set_query(Query().set_entity_name("Alert").set_filter(Filters().set_filter_operator(0))) .set_rows(Rows().set_grouping("")) .set_request_params(RequestParams().set_search_source(1).set_search_source_name("MainTab")) ) alert_attributes = AlertAttributes() for column in alert_attributes.get_fields(extra_fields): search_request.rows.add_column(column) filter_condition = ( FilterCondition().set_path("Alert.AggregationFilter").set_operator("Equals").add_value({"Alert.AggregationFilter": 1}) ) search_request.query.filter.add_filter(filter_condition) if ingest_time_from and ingest_time_to: ingest_time_condition = ( FilterCondition() .set_path(alert_attributes.Alert_IngestTime) .set_operator("Between") .add_value( { alert_attributes.Alert_IngestTime: ingest_time_from.isoformat(), f"{alert_attributes.Alert_IngestTime}0": ingest_time_to.isoformat(), } ) ) search_request.query.filter.add_filter(ingest_time_condition) else: days_back = MAX_DAYS_BACK if start_time is None and end_time is None and last_days is None: last_days = days_back elif 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) time_condition = FilterCondition().set_path(alert_attributes.Alert_TimeUTC) if start_time and end_time: time_condition = time_condition.set_operator("Between").add_value( { alert_attributes.Alert_TimeUTC: start_time.isoformat(), f"{alert_attributes.Alert_TimeUTC}0": end_time.isoformat(), } ) # "displayValue": start_time.isoformat(), if last_days: time_condition.set_operator("LastDays").add_value( {alert_attributes.Alert_TimeUTC: last_days, "displayValue": last_days} ) search_request.query.filter.add_filter(time_condition) if threat_model_names: rule_condition = FilterCondition().set_path(alert_attributes.Alert_Rule_Name).set_operator("In") for threat_model_name in threat_model_names: rule_condition.add_value({alert_attributes.Alert_Rule_Name: threat_model_name, "displayValue": "New"}) search_request.query.filter.add_filter(rule_condition) if alertIds: alert_condition = FilterCondition().set_path(alert_attributes.Alert_ID).set_operator("In") for alertId in alertIds: alert_condition.add_value({alert_attributes.Alert_ID: alertId, "displayValue": "New"}) search_request.query.filter.add_filter(alert_condition) if device_names: device_condition = FilterCondition().set_path(alert_attributes.Alert_Device_HostName).set_operator("In") for device_name in device_names: device_condition.add_value({alert_attributes.Alert_Device_HostName: device_name, "displayValue": device_name}) search_request.query.filter.add_filter(device_condition) if user_names: user_condition = FilterCondition().set_path(alert_attributes.Alert_User_Identity_Name).set_operator("In") for user_name in user_names: user_condition.add_value({alert_attributes.Alert_User_Identity_Name: user_name, "displayValue": user_name}) search_request.query.filter.add_filter(user_condition) if alert_statuses: status_condition = FilterCondition().set_path(alert_attributes.Alert_Status_ID).set_operator("In") for status in alert_statuses: status_id = ALERT_STATUSES[status.lower()] status_condition.add_value({alert_attributes.Alert_Status_ID: status_id, "displayValue": status}) search_request.query.filter.add_filter(status_condition) if alert_severities: severity_condition = FilterCondition().set_path(alert_attributes.Alert_Rule_Severity_ID).set_operator("In") for severity in alert_severities: severity_id = ALERT_SEVERITIES[severity.lower()] severity_condition.add_value({alert_attributes.Alert_Rule_Severity_ID: severity_id, "displayValue": severity}) search_request.query.filter.add_filter(severity_condition) if descending_order: search_request.rows.add_ordering({"path": "Alert.TimeUTC", "sortOrder": "Desc"}) else: search_request.rows.add_ordering({"path": "Alert.TimeUTC", "sortOrder": "Asc"}) dataJSON = search_request.to_json() json_data = self.varonis_search(dataJSON, max_fetch) mapper = SearchAlertObjectMapper() alerts = mapper.map(json_data) return alerts def varonis_get_alerted_events( self, alertIds: list[str], start_time: Optional[datetime], end_time: Optional[datetime], last_days: Optional[int], extra_fields: Optional[list[str]], descending_order: bool, max_fetch: Optional[int] = 1000, ) -> list[dict[str, Any]]: """Get alerted events :type alertIds: ``List[str]`` :param alertIds: List of alert ids :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 count: ``int`` :param count: Alerted events count :type extra_fields: ``Optional[List[str]]`` :param extra_fields: List of extra fields to include in the response :type extra_fields: ``Optional[List[str]]`` :param extra_fields: List of extra fields to include in the response :type descending_order: ``bool`` :param descending_order: Indicates whether events should be ordered in newest to oldest order :type max_fetch: ``Optional[int]`` :param max_fetch: Maximum number of items :return: Alerted events :rtype: ``List[Dict[str, Any]]`` """ days_back = MAX_DAYS_BACK if start_time is None and end_time is None and last_days is None: last_days = days_back elif 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) search_request = ( SearchRequest() .set_query(Query().set_entity_name("Event").set_filter(Filters().set_filter_operator(0))) .set_rows(Rows().set_grouping("")) .set_request_params(RequestParams().set_search_source(1).set_search_source_name("MainTab")) ) event_attributes = EventAttributes() for column in event_attributes.get_fields(extra_fields): search_request.rows.add_column(column) if alertIds and len(alertIds) > 0: time_condition = FilterCondition().set_path(event_attributes.Event_Alert_ID).set_operator("In") for alertId in alertIds: time_condition.add_value({event_attributes.Event_Alert_ID: alertId, "displayValue": alertId}) search_request.query.filter.add_filter(time_condition) time_condition = FilterCondition().set_path(event_attributes.Event_TimeUTC) if start_time and end_time: time_condition = time_condition.set_operator("Between").add_value( { event_attributes.Event_TimeUTC: start_time.isoformat(), f"{event_attributes.Event_TimeUTC}0": end_time.isoformat(), } ) # "displayValue": start_time.isoformat(), (this line seems to be commented out) if last_days: time_condition.set_operator("LastDays").add_value( {event_attributes.Event_TimeUTC: last_days, "displayValue": last_days} ) search_request.query.filter.add_filter(time_condition) if descending_order: search_request.rows.add_ordering({"path": event_attributes.Event_TimeUTC, "sortOrder": "Desc"}) else: search_request.rows.add_ordering({"path": event_attributes.Event_TimeUTC, "sortOrder": "Asc"}) dataJSON = search_request.to_json() json_data = self.varonis_search(dataJSON, max_fetch) mapper = SearchEventObjectMapper() events = mapper.map(json_data) return events def varonis_get_enum(self, enum_id: int) -> list[Any]: """Gets an enum by enum_id. Usually needs for retrieving object required for a search :type enum_id: ``int`` :param enum_id: Id of enum stored in database :return: The list of objects required for a search filter :rtype: ``List[Any]`` """ response = self._http_request("GET", f"/api/entitymodel/enum/{enum_id}", headers=self.headers) return response def varonis_update_alert_status(self, 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._http_request("POST", "/api/alert/alert/SetStatusToAlerts", json_data=query, headers=self.headers) def varonis_add_note_to_alerts(self, query: dict[str, Any]) -> bool: """Update alert status :type query: ``Dict[str, Any]`` :param query: "add notes" request body :return: Result of execution :rtype: ``bool`` """ return self._http_request("POST", "/api/alert/alert/AddNoteToAlerts", json_data=query, headers=self.headers) class EventAttributes: Event_StatusReason_Name = "Event.StatusReason.Name" Event_StatusReason_ID = "Event.StatusReason.ID" Event_Location_BlacklistedLocation = "Event.Location.BlacklistedLocation" Event_Location_Subdivision_Name = "Event.Location.Subdivision.Name" Event_Location_Subdivision_ID = "Event.Location.Subdivision.ID" Event_Location_Country_Name = "Event.Location.Country.Name" Event_Location_Country_ID = "Event.Location.Country.ID" Event_Filer_Platform_Name = "Event.Filer.Platform.Name" Event_Filer_Platform_ID = "Event.Filer.Platform.ID" Event_OnResource_Stats_ExposureLevel_Name = "Event.OnResource.Stats.ExposureLevel.Name" Event_OnResource_Stats_ExposureLevel_ID = "Event.OnResource.Stats.ExposureLevel.ID" Event_ByAccount_Identity_Followup_Flag_Name = "Event.ByAccount.Identity.Followup.Flag.Name" Event_ByAccount_Identity_Followup_Flag_ID = "Event.ByAccount.Identity.Followup.Flag.ID" Event_ByAccount_SamAccountName = "Event.ByAccount.SamAccountName" Event_ByAccount_SidID = "Event.ByAccount.SidID" Event_ByAccount_Type_Name = "Event.ByAccount.Type.Name" Event_ByAccount_Type_ID = "Event.ByAccount.Type.ID" Event_ByAccount_DistinguishedName = "Event.ByAccount.DistinguishedName" Event_OnAccount_Domain_Name = "Event.OnAccount.Domain.Name" Event_OnAccount_Domain_ID = "Event.OnAccount.Domain.ID" Event_OnAccount_Identity_Followup_Flag_Name = "Event.OnAccount.Identity.Followup.Flag.Name" Event_OnAccount_Identity_Followup_Flag_ID = "Event.OnAccount.Identity.Followup.Flag.ID" Event_Time = "Event.Time" Event_Operation_Name = "Event.Operation.Name" Event_Operation_ID = "Event.Operation.ID" Event_EndTime = "Event.EndTime" Event_Type_Name = "Event.Type.Name" Event_Type_ID = "Event.Type.ID" Event_ByAccount_Identity_Name = "Event.ByAccount.Identity.Name" Event_ByAccount_Identity_ID = "Event.ByAccount.Identity.ID" Event_OnAccount_DNSDomain_Name = "Event.OnAccount.DNSDomain.Name" Event_OnAccount_DNSDomain_ID = "Event.OnAccount.DNSDomain.ID" Event_OnAccount_Identity_Name = "Event.OnAccount.Identity.Name" Event_OnAccount_Identity_ID = "Event.OnAccount.Identity.ID" Event_OnObjectName = "Event.OnObjectName" Event_OnResource_Path = "Event.OnResource.Path" Event_OnResource_EntityIdx = "Event.OnResource.EntityIdx" Event_ByAccount_Domain_Name = "Event.ByAccount.Domain.Name" Event_ByAccount_Domain_ID = "Event.ByAccount.Domain.ID" Event_ByAccount_DNSDomain_Name = "Event.ByAccount.DNSDomain.Name" Event_ByAccount_DNSDomain_ID = "Event.ByAccount.DNSDomain.ID" Event_OnResource_IsSensitive = "Event.OnResource.IsSensitive" Event_Status_Name = "Event.Status.Name" Event_Status_ID = "Event.Status.ID" Event_Filer_Name = "Event.Filer.Name" Event_Filer_ID = "Event.Filer.ID" Event_OnResource_ObjectType_Name = "Event.OnResource.ObjectType.Name" Event_OnResource_ObjectType_ID = "Event.OnResource.ObjectType.ID" Event_Device_UserAgent = "Event.Device.UserAgent" Event_CorrelationId = "Event.CorrelationId" Event_ByAccount_Identity_Followup_Notes = "Event.ByAccount.Identity.Followup.Notes" Event_OnAccount_Identity_Followup_Notes = "Event.OnAccount.Identity.Followup.Notes" Event_OnResource_Followup_Flag_Name = "Event.OnResource.Followup.Flag.Name" Event_OnResource_Followup_Flag_ID = "Event.OnResource.Followup.Flag.ID" Event_ByAccount_Identity_Department = "Event.ByAccount.Identity.Department" Event_OnAccount_Identity_Department = "Event.OnAccount.Identity.Department" Event_IP = "Event.IP" Event_ByAccount_Identity_Manager_Name = "Event.ByAccount.Identity.Manager.Name" Event_ByAccount_Identity_Manager_ID = "Event.ByAccount.Identity.Manager.ID" Event_OnAccount_Identity_Manager_Name = "Event.OnAccount.Identity.Manager.Name" Event_OnAccount_Identity_Manager_ID = "Event.OnAccount.Identity.Manager.ID" Event_ByAccount_IsDisabled = "Event.ByAccount.IsDisabled" Event_ByAccount_IsStale = "Event.ByAccount.IsStale" Event_OnAccount_IsStale = "Event.OnAccount.IsStale" Event_Device_Name = "Event.Device.Name" Event_ByAccount_LastLogonTime = "Event.ByAccount.LastLogonTime" Event_OnAccount_LastLogonTime = "Event.OnAccount.LastLogonTime" Event_OnResource_File_Type = "Event.OnResource.File.Type" Event_OnResource_AccessDate = "Event.OnResource.AccessDate" Event_OnResource_ModifyDate = "Event.OnResource.ModifyDate" Event_OnResource_FSOwner_Name = "Event.OnResource.FSOwner.Name" Event_OnResource_FSOwner_SidID = "Event.OnResource.FSOwner.SidID" Event_OnResource_Classification_TotalHitCount = "Event.OnResource.Classification.TotalHitCount" Event_OnMail_ItemType_Name = "Event.OnMail.ItemType.Name" Event_OnMail_ItemType_ID = "Event.OnMail.ItemType.ID" Event_OnMail_Recipient = "Event.OnMail.Recipient" Event_OnResource_CreateDate = "Event.OnResource.CreateDate" Event_OnMail_Source = "Event.OnMail.Source" Event_OnResource_PathDepth = "Event.OnResource.PathDepth" Event_OnResource_NumberOfNestedFiles = "Event.OnResource.NumberOfNestedFiles" Event_Alert_Rule_Name = "Event.Alert.Rule.Name" Event_Alert_Rule_ID = "Event.Alert.Rule.ID" Event_OnResource_SizeFolder = "Event.OnResource.SizeFolder" Event_Alert_Rule_Category_Name = "Event.Alert.Rule.Category.Name" Event_Alert_Rule_Category_ID = "Event.Alert.Rule.Category.ID" Event_OnResource_SizeFolderAndSubFolders = "Event.OnResource.SizeFolderAndSubFolders" Event_Alert_Rule_Severity_Name = "Event.Alert.Rule.Severity.Name" Event_Alert_Rule_Severity_ID = "Event.Alert.Rule.Severity.ID" Event_OnResource_NumberOfFiles = "Event.OnResource.NumberOfFiles" Event_Alert_Time = "Event.Alert.Time" Event_Alert_TimeUTC = "Event.Alert.TimeUTC" Event_TimeUTC = "Event.TimeUTC" Event_OnResource_NumberOfFilesInSubFolders = "Event.OnResource.NumberOfFilesInSubFolders" Event_Alert_ID = "Event.Alert.ID" Event_OnResource_NumberOfNestedFolders = "Event.OnResource.NumberOfNestedFolders" Event_Description = "Event.Description" Event_OnResource_SizePhysicalSDTFile = "Event.OnResource.SizePhysicalSDTFile" Event_EventsCount = "Event.EventsCount" Event_OnResource_SizePhysicalNestedFoldersFiles = "Event.OnResource.SizePhysicalNestedFoldersFiles" Event_ByAccount_PasswordStatus_Name = "Event.ByAccount.PasswordStatus.Name" Event_ByAccount_PasswordStatus_ID = "Event.ByAccount.PasswordStatus.ID" Event_OnResource_SizePhysicalFiles = "Event.OnResource.SizePhysicalFiles" Event_ByAccount_AccountExpirationDate = "Event.ByAccount.AccountExpirationDate" Event_OnResource_SizeSubFolders = "Event.OnResource.SizeSubFolders" Event_OnAccount_IsDisabled = "Event.OnAccount.IsDisabled" Event_OnResource_NumberOfNestedObjects = "Event.OnResource.NumberOfNestedObjects" Event_OnAccount_IsLockout = "Event.OnAccount.IsLockout" Event_UploadSize = "Event.UploadSize" Event_DownloadSize = "Event.DownloadSize" Event_OnAccount_PasswordStatus_Name = "Event.OnAccount.PasswordStatus.Name" Event_OnAccount_PasswordStatus_ID = "Event.OnAccount.PasswordStatus.ID" Event_SessionDuration = "Event.SessionDuration" Event_OnAccount_AccountExpirationDate = "Event.OnAccount.AccountExpirationDate" Event_ConnectionType_Name = "Event.ConnectionType.Name" Event_ConnectionType_ID = "Event.ConnectionType.ID" Event_ClientType_Name = "Event.ClientType.Name" Event_ClientType_ID = "Event.ClientType.ID" Event_AgentVersion = "Event.AgentVersion" Event_ByAccount_VPNGroups = "Event.ByAccount.VPNGroups" Event_ByAccount_IsLockout = "Event.ByAccount.IsLockout" Event_DC_HostName = "Event.DC.HostName" Event_Direction_Name = "Event.Direction.Name" Event_Direction_ID = "Event.Direction.ID" Event_OnAccount_SamAccountName = "Event.OnAccount.SamAccountName" Event_OnAccount_SidID = "Event.OnAccount.SidID" Event_ByAccount_PrivilegedAccountType_Name = "Event.ByAccount.PrivilegedAccountType.Name" Event_ByAccount_PrivilegedAccountType_ID = "Event.ByAccount.PrivilegedAccountType.ID" Event_DNSFlags = "Event.DNSFlags" Event_CollectionMethod_Name = "Event.CollectionMethod.Name" Event_CollectionMethod_ID = "Event.CollectionMethod.ID" Event_OnAccount_AccountType_Name = "Event.OnAccount.AccountType.Name" Event_OnAccount_AccountType_ID = "Event.OnAccount.AccountType.ID" Event_DNSRecordType = "Event.DNSRecordType" Event_OnResource_Classification_CategorySummary = "Event.OnResource.Classification.CategorySummary" Event_ByAccount_Identity_Affiliation_Name = "Event.ByAccount.Identity.Affiliation.Name" Event_ByAccount_Identity_Affiliation_ID = "Event.ByAccount.Identity.Affiliation.ID" Event_OnAccount_Application_ID = "Event.OnAccount.Application.ID" Event_TransportLayer_Name = "Event.TransportLayer.Name" Event_TransportLayer_ID = "Event.TransportLayer.ID" Event_OnAccount_Application_Name = "Event.OnAccount.Application.Name" Event_OnAccount_Identity_Affiliation_Name = "Event.OnAccount.Identity.Affiliation.Name" Event_OnAccount_Identity_Affiliation_ID = "Event.OnAccount.Identity.Affiliation.ID" Event_Destination_URL_Reputation_Name = "Event.Destination.URL.Reputation.Name" Event_Destination_URL_Reputation_ID = "Event.Destination.URL.Reputation.ID" Event_HttpMethod_Name = "Event.HttpMethod.Name" Event_HttpMethod_ID = "Event.HttpMethod.ID" Event_OnAccount_PublisherName = "Event.OnAccount.PublisherName" Event_Destination_IP = "Event.Destination.IP" Event_Destination_URL_Categorization_Name = "Event.Destination.URL.Categorization.Name" Event_Destination_URL_Categorization_ID = "Event.Destination.URL.Categorization.ID" Event_OnAccount_IsPublisherVerified = "Event.OnAccount.IsPublisherVerified" Event_Destination_DeviceName = "Event.Destination.DeviceName" Event_ByAccount_Application_ID = "Event.ByAccount.Application.ID" Event_Destination_Domain = "Event.Destination.Domain" Event_ByAccount_Application_Name = "Event.ByAccount.Application.Name" Event_Device_ExternalIP_IP = "Event.Device.ExternalIP.IP" Event_ByAccount_PublisherName = "Event.ByAccount.PublisherName" Event_ByAccount_IsPublisherVerified = "Event.ByAccount.IsPublisherVerified" Event_Device_OperatingSystem = "Event.Device.OperatingSystem" Event_SourcePort = "Event.SourcePort" Event_SourceZone = "Event.SourceZone" Event_App = "Event.App" Event_Device_ExternalIP_ThreatTypes_Name = "Event.Device.ExternalIP.ThreatTypes.Name" Event_Device_ExternalIP_ThreatTypes_ID = "Event.Device.ExternalIP.ThreatTypes.ID" Event_Destination_Port = "Event.Destination.Port" Event_Destination_Zone = "Event.Destination.Zone" Event_NAT_Source_Address = "Event.NAT.Source.Address" Event_NAT_Destination_Address = "Event.NAT.Destination.Address" Event_NAT_Source_Port = "Event.NAT.Source.Port" Event_NAT_Destination_Port = "Event.NAT.Destination.Port" Event_Protocol_Name = "Event.Protocol.Name" Event_Protocol_ID = "Event.Protocol.ID" Event_ApplicationProtocol_Name = "Event.ApplicationProtocol.Name" Event_ApplicationProtocol_ID = "Event.ApplicationProtocol.ID" Event_Device_ExternalIP_IsMalicious = "Event.Device.ExternalIP.IsMalicious" Event_Device_ExternalIP_Reputation_Name = "Event.Device.ExternalIP.Reputation.Name" Event_Device_ExternalIP_Reputation_ID = "Event.Device.ExternalIP.Reputation.ID" Event_ByAccount_IsMailboxOwner = "Event.ByAccount.IsMailboxOwner" Event_StatusReasonCodeName = "Event.StatusReasonCodeName" Event_StatusReasonCode = "Event.StatusReasonCode" Event_Authentication_TicketEncryption_Name = "Event.Authentication.TicketEncryption.Name" Event_Authentication_TicketEncryption_ID = "Event.Authentication.TicketEncryption.ID" Event_OnGPO_NewVersion = "Event.OnGPO.NewVersion" Event_Authentication_PreAuthenticationType = "Event.Authentication.PreAuthenticationType" Event_OnGPO_Settings_NewValue = "Event.OnGPO.Settings.NewValue" Event_Authentication_Protocol_Name = "Event.Authentication.Protocol.Name" Event_Authentication_Protocol_ID = "Event.Authentication.Protocol.ID" Event_OnGPO_Settings_OldValue = "Event.OnGPO.Settings.OldValue" Event_OrgOpCode = "Event.OrgOpCode" Event_OnGPO_Settings_Name = "Event.OnGPO.Settings.Name" Event_ByAccount_ExpirationStatus_Name = "Event.ByAccount.ExpirationStatus.Name" Event_ByAccount_ExpirationStatus_ID = "Event.ByAccount.ExpirationStatus.ID" Event_OnGPO_Settings_Path = "Event.OnGPO.Settings.Path" Event_OnAccount_ExpirationStatus_Name = "Event.OnAccount.ExpirationStatus.Name" Event_OnAccount_ExpirationStatus_ID = "Event.OnAccount.ExpirationStatus.ID" Event_OnGPO_ConfigurationType_Name = "Event.OnGPO.ConfigurationType.Name" Event_OnGPO_ConfigurationType_ID = "Event.OnGPO.ConfigurationType.ID" Event_Trustee_Identity_Name = "Event.Trustee.Identity.Name" Event_Trustee_Identity_ID = "Event.Trustee.Identity.ID" Event_OnMail_Mailbox_Type_Name = "Event.OnMail.Mailbox.Type.Name" Event_OnMail_Mailbox_Type_ID = "Event.OnMail.Mailbox.Type.ID" Event_Trustee_DNSDomain_Name = "Event.Trustee.DNSDomain.Name" Event_Trustee_DNSDomain_ID = "Event.Trustee.DNSDomain.ID" Event_Trustee_Type_Name = "Event.Trustee.Type.Name" Event_Trustee_Type_ID = "Event.Trustee.Type.ID" Event_Trustee_Application_ID = "Event.Trustee.Application.ID" Event_Trustee_Application_Name = "Event.Trustee.Application.Name" Event_Trustee_PublisherName = "Event.Trustee.PublisherName" Event_Trustee_IsPublisherVerified = "Event.Trustee.IsPublisherVerified" Event_Permission_IsDirectChange = "Event.Permission.IsDirectChange" Event_Permission_ChangedPermissionFlags = "Event.Permission.ChangedPermissionFlags" Event_Trustee_Identity_Affiliation_Name = "Event.Trustee.Identity.Affiliation.Name" Event_Trustee_Identity_Affiliation_ID = "Event.Trustee.Identity.Affiliation.ID" Event_LogonType = "Event.LogonType" Event_Authentication_Package = "Event.Authentication.Package" Event_ImpersonationLevel = "Event.ImpersonationLevel" Event_OnMail_AttachmentName = "Event.OnMail.AttachmentName" Event_OnMail_WithAttachments = "Event.OnMail.WithAttachments" Event_OnResource_ClassificationLabels_Summary = "Event.OnResource.ClassificationLabels.Summary" Event_OnMail_HasOutOfOrganizationReciever = "Event.OnMail.HasOutOfOrganizationReciever" Event_Type_Activity_Name = "Event.Type.Activity.Name" Event_Type_Activity_ID = "Event.Type.Activity.ID" Event_InfoTags_Name = "Event.InfoTags.Name" Event_InfoTags_ID = "Event.InfoTags.ID" Event_Authentication_TicketOptions = "Event.Authentication.TicketOptions" Event_OnMail_Headers_SentDate = "Event.OnMail.Headers.SentDate" Event_OnMail_Headers_AuthenticationResults_Spf_Passed = "Event.OnMail.Headers.AuthenticationResults.Spf.Passed" Event_OnMail_Headers_AuthenticationResults_Dkim_Passed = "Event.OnMail.Headers.AuthenticationResults.Dkim.Passed" Event_OnMail_Headers_AuthenticationResults_Dmarc_Passed = "Event.OnMail.Headers.AuthenticationResults.Dmarc.Passed" Event_OnMail_Headers_XOriginalSender = "Event.OnMail.Headers.XOriginalSender" Event_OnMail_Headers_ReceivedServerIP = "Event.OnMail.Headers.ReceivedServerIP" Event_OnResource_Classification_Summary = "Event.OnResource.Classification.Summary" Event_OnMail_Date = "Event.OnMail.Date" Event_OnResource_ShareAccessPaths = "Event.OnResource.ShareAccessPaths" Event_Permission_Before = "Event.Permission.Before" Event_Permission_After = "Event.Permission.After" Event_Permission_Type = "Event.Permission.Type" Event_OnResource_LocalMappedPath = "Event.OnResource.LocalMappedPath" Event_Session_BrowserType = "Event.Session.BrowserType" Event_Session_TrustDomain_Type = "Event.Session.TrustDomain.Type" Event_Session_AzureAuthentication_Requirement = "Event.Session.AzureAuthentication.Requirement" Event_Session_AzureAuthentication_ConditionalAccessStatus = "Event.Session.AzureAuthentication.ConditionalAccessStatus" Event_Session_AzureAuthentication_TokenIssuerType = "Event.Session.AzureAuthentication.TokenIssuerType" Event_Session_AzureAuthentication_Method = "Event.Session.AzureAuthentication.Method" Event_Session_AzureAuthentication_MethodDetail = "Event.Session.AzureAuthentication.MethodDetail" Event_Session_AzureAuthentication_Step = "Event.Session.AzureAuthentication.Step" Event_Session_AzureAuthentication_ResultDetail = "Event.Session.AzureAuthentication.ResultDetail" Event_Session_AzureAuthentication_ReasonDetails = "Event.Session.AzureAuthentication.ReasonDetails" Event_Device_TrustType = "Event.Device.TrustType" Event_Session_AzureAuthentication_Status_Name = "Event.Session.AzureAuthentication.Status.Name" Event_Session_AzureAuthentication_Status_ID = "Event.Session.AzureAuthentication.Status.ID" Event_Device_ManagedStatus_Name = "Event.Device.ManagedStatus.Name" Event_Device_ManagedStatus_ID = "Event.Device.ManagedStatus.ID" Event_ID = "Event.ID" Event_IsAlerted = "Event.IsAlerted" Columns = [ Event_Type_Name, Event_Description, Event_Filer_Platform_Name, Event_Filer_Name, Event_ByAccount_SamAccountName, Event_OnObjectName, Event_Alert_ID, Event_ID, Event_TimeUTC, Event_Status_Name, Event_Location_Country_Name, Event_Location_Subdivision_Name, Event_Location_BlacklistedLocation, Event_Operation_Name, Event_ByAccount_Type_Name, Event_ByAccount_Domain_Name, Event_ByAccount_Identity_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_OnResource_ObjectType_Name, Event_OnAccount_SamAccountName, Event_OnResource_IsSensitive, Event_OnAccount_IsDisabled, Event_OnAccount_IsLockout, Event_OnResource_Path, ] ExtraColumns = [ Event_StatusReason_Name, Event_StatusReason_ID, Event_Location_Subdivision_ID, Event_Location_Country_ID, Event_Filer_Platform_ID, Event_OnResource_Stats_ExposureLevel_Name, Event_OnResource_Stats_ExposureLevel_ID, Event_ByAccount_Identity_Followup_Flag_Name, Event_ByAccount_Identity_Followup_Flag_ID, Event_ByAccount_SidID, Event_ByAccount_Type_ID, Event_ByAccount_DistinguishedName, Event_OnAccount_Domain_Name, Event_OnAccount_Domain_ID, Event_OnAccount_Identity_Followup_Flag_Name, Event_OnAccount_Identity_Followup_Flag_ID, Event_Time, Event_Operation_ID, Event_EndTime, Event_Type_ID, Event_ByAccount_Identity_ID, Event_OnAccount_DNSDomain_Name, Event_OnAccount_DNSDomain_ID, Event_OnAccount_Identity_Name, Event_OnAccount_Identity_ID, Event_OnResource_EntityIdx, Event_ByAccount_Domain_ID, Event_ByAccount_DNSDomain_Name, Event_ByAccount_DNSDomain_ID, Event_Status_ID, Event_Filer_ID, Event_OnResource_ObjectType_ID, Event_Device_UserAgent, Event_CorrelationId, Event_ByAccount_Identity_Followup_Notes, Event_OnAccount_Identity_Followup_Notes, Event_OnResource_Followup_Flag_Name, Event_OnResource_Followup_Flag_ID, Event_ByAccount_Identity_Department, Event_OnAccount_Identity_Department, Event_ByAccount_Identity_Manager_Name, Event_ByAccount_Identity_Manager_ID, Event_OnAccount_Identity_Manager_Name, Event_OnAccount_Identity_Manager_ID, Event_OnAccount_IsStale, Event_ByAccount_LastLogonTime, Event_OnAccount_LastLogonTime, Event_OnResource_File_Type, Event_OnResource_AccessDate, Event_OnResource_ModifyDate, Event_OnResource_FSOwner_Name, Event_OnResource_FSOwner_SidID, Event_OnResource_Classification_TotalHitCount, Event_OnMail_ItemType_Name, Event_OnMail_ItemType_ID, Event_OnMail_Recipient, Event_OnResource_CreateDate, Event_OnMail_Source, Event_OnResource_PathDepth, Event_OnResource_NumberOfNestedFiles, Event_Alert_Rule_Name, Event_Alert_Rule_ID, Event_OnResource_SizeFolder, Event_Alert_Rule_Category_Name, Event_Alert_Rule_Category_ID, Event_OnResource_SizeFolderAndSubFolders, Event_Alert_Rule_Severity_Name, Event_Alert_Rule_Severity_ID, Event_OnResource_NumberOfFiles, Event_Alert_Time, Event_Alert_TimeUTC, Event_OnResource_NumberOfFilesInSubFolders, Event_OnResource_NumberOfNestedFolders, Event_OnResource_SizePhysicalSDTFile, Event_EventsCount, Event_OnResource_SizePhysicalNestedFoldersFiles, Event_ByAccount_PasswordStatus_Name, Event_ByAccount_PasswordStatus_ID, Event_OnResource_SizePhysicalFiles, Event_ByAccount_AccountExpirationDate, Event_OnResource_SizeSubFolders, Event_OnResource_NumberOfNestedObjects, Event_UploadSize, Event_DownloadSize, Event_OnAccount_PasswordStatus_Name, Event_OnAccount_PasswordStatus_ID, Event_SessionDuration, Event_OnAccount_AccountExpirationDate, Event_ConnectionType_Name, Event_ConnectionType_ID, Event_ClientType_Name, Event_ClientType_ID, Event_AgentVersion, Event_ByAccount_VPNGroups, Event_DC_HostName, Event_Direction_Name, Event_Direction_ID, Event_OnAccount_SidID, Event_ByAccount_PrivilegedAccountType_Name, Event_ByAccount_PrivilegedAccountType_ID, Event_DNSFlags, Event_CollectionMethod_Name, Event_CollectionMethod_ID, Event_OnAccount_AccountType_Name, Event_OnAccount_AccountType_ID, Event_DNSRecordType, Event_OnResource_Classification_CategorySummary, Event_ByAccount_Identity_Affiliation_Name, Event_ByAccount_Identity_Affiliation_ID, Event_OnAccount_Application_ID, Event_TransportLayer_Name, Event_TransportLayer_ID, Event_OnAccount_Application_Name, Event_OnAccount_Identity_Affiliation_Name, Event_OnAccount_Identity_Affiliation_ID, Event_Destination_URL_Reputation_Name, Event_Destination_URL_Reputation_ID, Event_HttpMethod_Name, Event_HttpMethod_ID, Event_OnAccount_PublisherName, Event_Destination_URL_Categorization_Name, Event_Destination_URL_Categorization_ID, Event_OnAccount_IsPublisherVerified, Event_ByAccount_Application_ID, Event_Destination_Domain, Event_ByAccount_Application_Name, Event_ByAccount_PublisherName, Event_ByAccount_IsPublisherVerified, Event_Device_OperatingSystem, Event_SourcePort, Event_SourceZone, Event_App, Event_Device_ExternalIP_ThreatTypes_ID, Event_Destination_Port, Event_Destination_Zone, Event_NAT_Source_Address, Event_NAT_Destination_Address, Event_NAT_Source_Port, Event_NAT_Destination_Port, Event_Protocol_Name, Event_Protocol_ID, Event_ApplicationProtocol_Name, Event_ApplicationProtocol_ID, Event_Device_ExternalIP_Reputation_ID, Event_ByAccount_IsMailboxOwner, Event_StatusReasonCodeName, Event_StatusReasonCode, Event_Authentication_TicketEncryption_Name, Event_Authentication_TicketEncryption_ID, Event_OnGPO_NewVersion, Event_Authentication_PreAuthenticationType, Event_OnGPO_Settings_NewValue, Event_Authentication_Protocol_Name, Event_Authentication_Protocol_ID, Event_OnGPO_Settings_OldValue, Event_OrgOpCode, Event_OnGPO_Settings_Name, Event_ByAccount_ExpirationStatus_Name, Event_ByAccount_ExpirationStatus_ID, Event_OnGPO_Settings_Path, Event_OnAccount_ExpirationStatus_Name, Event_OnAccount_ExpirationStatus_ID, Event_OnGPO_ConfigurationType_Name, Event_OnGPO_ConfigurationType_ID, Event_Trustee_Identity_Name, Event_Trustee_Identity_ID, Event_OnMail_Mailbox_Type_Name, Event_OnMail_Mailbox_Type_ID, Event_Trustee_DNSDomain_Name, Event_Trustee_DNSDomain_ID, Event_Trustee_Type_Name, Event_Trustee_Type_ID, Event_Trustee_Application_ID, Event_Trustee_Application_Name, Event_Trustee_PublisherName, Event_Trustee_IsPublisherVerified, Event_Permission_IsDirectChange, Event_Permission_ChangedPermissionFlags, Event_Trustee_Identity_Affiliation_Name, Event_Trustee_Identity_Affiliation_ID, Event_LogonType, Event_Authentication_Package, Event_ImpersonationLevel, Event_OnMail_AttachmentName, Event_OnMail_WithAttachments, Event_OnResource_ClassificationLabels_Summary, Event_OnMail_HasOutOfOrganizationReciever, Event_Type_Activity_Name, Event_Type_Activity_ID, Event_InfoTags_Name, Event_InfoTags_ID, Event_Authentication_TicketOptions, Event_OnMail_Headers_SentDate, Event_OnMail_Headers_AuthenticationResults_Spf_Passed, Event_OnMail_Headers_AuthenticationResults_Dkim_Passed, Event_OnMail_Headers_AuthenticationResults_Dmarc_Passed, Event_OnMail_Headers_XOriginalSender, Event_OnMail_Headers_ReceivedServerIP, Event_OnResource_Classification_Summary, Event_OnMail_Date, Event_OnResource_ShareAccessPaths, Event_Permission_Before, Event_Permission_After, Event_Permission_Type, Event_OnResource_LocalMappedPath, Event_Session_BrowserType, Event_Session_TrustDomain_Type, Event_Session_AzureAuthentication_Requirement, Event_Session_AzureAuthentication_ConditionalAccessStatus, Event_Session_AzureAuthentication_TokenIssuerType, Event_Session_AzureAuthentication_Method, Event_Session_AzureAuthentication_MethodDetail, Event_Session_AzureAuthentication_Step, Event_Session_AzureAuthentication_ResultDetail, Event_Session_AzureAuthentication_ReasonDetails, Event_Device_TrustType, Event_Session_AzureAuthentication_Status_Name, Event_Session_AzureAuthentication_Status_ID, Event_Device_ManagedStatus_Name, Event_Device_ManagedStatus_ID, Event_IsAlerted, ] def get_fields(self, extra_fields: Optional[list[str]]) -> list[str]: output = self.Columns.copy() if extra_fields: for pattern in extra_fields: match_columns = fnmatch.filter(self.ExtraColumns, pattern) output.extend([item for item in match_columns if item not in output]) return output class EventItem: def __init__(self, row: dict): self.row = row def __getitem__(self, key: str) -> Any: if hasattr(self.row, key): return getattr(self.row, key) raise KeyError(f"{key} not found in AlertItem") def to_dict(self) -> dict[str, Any]: return self.row class FilterCondition: def __init__(self): self.path = None self.operator = None self.values = [] def set_path(self, path): self.path = path return self def set_operator(self, operator): self.operator = operator return self def add_value(self, value): self.values.append(value) # FilterValue(value) return self def __repr__(self): return f"{self.path} {self.operator} {self.values}" class FilterValue: def __init__(self, value): self.value = value # self.displayValue = value.get("displayValue", None) def __repr__(self): return f"{self.value}" class Filters: def __init__(self): self.filterOperator = None self.filters = [] def set_filter_operator(self, filter_operator): self.filterOperator = filter_operator return self def add_filter(self, filter_): self.filters.append(filter_) return self def __repr__(self): return f"Filter Operator: {self.filterOperator}, Filters: {self.filters}" class Query: def __init__(self): self.entityName = None self.filter = Filters() def set_entity_name(self, entity_name): self.entityName = entity_name return self def set_filter(self, filter_): self.filter = filter_ return self def __repr__(self): return f"Entity Name: {self.entityName}, Filter: {self.filter}" class RequestParams: def __init__(self): self.searchSource = None self.searchSourceName = None def set_search_source(self, search_source): self.searchSource = search_source return self def set_search_source_name(self, search_source_name): self.searchSourceName = search_source_name return self def __repr__(self): return f"Search Source: {self.searchSource}, Search Source Name: {self.searchSourceName}" class Rows: def __init__(self): self.columns = [] self.filter = [] self.grouping = None self.ordering = [] def add_column(self, column): self.columns.append(column) return self def add_filter(self, filter_): self.filter.append(filter_) return self def set_grouping(self, grouping): self.grouping = grouping return self def add_ordering(self, ordering): self.ordering.append(ordering) return self def __repr__(self): return f"Columns: {self.columns}, Filter: {self.filter}, Grouping: {self.grouping}, Ordering: {self.ordering}" class SearchAlertObjectMapper(BaseMapper): def map(self, json_data): key_valued_objects = self.convert_json_to_key_value(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) -> AlertItem: alert_item = AlertItem(row) return alert_item class SearchEventObjectMapper(BaseMapper): def map(self, json_data): key_valued_objects = self.convert_json_to_key_value(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]) -> EventItem: event_item = EventItem(row) return event_item def multi_value_to_guid_array(self, row: dict[str, str], field: str) -> Optional[list[str]]: value = row.get(field) if value: return list(value.split(",")) return None def get_bool_value(self, row: dict[str, str], name: str) -> Optional[bool]: value = row.get(name) 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 return None def get_date_value(self, row: dict[str, str], name: str) -> Optional[datetime]: value = row.get(name) if value: try: return datetime.fromisoformat(value) except ValueError: return None return None def multi_value_to_array(self, multi_value: str) -> Optional[list[str]]: if multi_value: return [v.strip() for v in multi_value.split(",") if v.strip()] return None class SearchRequest: def __init__(self): self.query = Query() self.rows = Rows() self.requestParams = RequestParams() def set_query(self, query): self.query = query return self def set_rows(self, rows): self.rows = rows return self def set_request_params(self, request_params): self.requestParams = request_params return self def __repr__(self): return f"Query: {self.query}, Rows: {self.rows}, Request Params: {self.requestParams}" def to_json(self): dataJSON = json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) return dataJSON class ThreatModelAttributes: Id = "ruleID" Name = "ruleName" Category = "ruleArea" Source = "ruleSource" Severity = "severity" Columns = [Id, Name, Category, Source, Severity] class ThreatModelItem: def __init__(self): self.ID: Optional[str] = None self.Name: Optional[list[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} class ThreatModelObjectMapper(BaseMapper): def map(self, json_data): 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) -> ThreatModelItem: threat_model_item = ThreatModelItem() threat_model_item.ID = row.get(ThreatModelAttributes.Id, row.get("dataField")) threat_model_item.Name = row.get(ThreatModelAttributes.Name, row.get("displayField")) return threat_model_item """Varonis SaaS integration """ def convert_to_demisto_severity(severity: Optional[str]) -> float: """Maps Varonis severity to Cortex XSOAR severity Converts the Varonis alert severity level ('Informational', 'Low', 'Medium', 'High') to Cortex XSOAR incident severity (0.5 to 4) for mapping. :type severity: ``str`` :param severity: severity as returned from the Varonis API (str) :return: Cortex XSOAR Severity value (may be fractional for INFO) :rtype: ``float`` """ if severity is None: return IncidentSeverity.LOW return { "Informational": IncidentSeverity.INFO, "Low": IncidentSeverity.LOW, "Medium": IncidentSeverity.MEDIUM, "High": IncidentSeverity.HIGH, }[severity] def get_included_severitires(severity: Optional[str]) -> list[str]: """Return list of severities that is equal or higher then provided :type severity: ``Optional[str]`` :param severity: Severity :return: List of severities :rtype: ``List[str]`` """ if not severity: return [] # Normalize and validate severity sev_key = severity.lower() if sev_key not in ALERT_SEVERITIES: return [] # ALERT_SEVERITIES maps severity -> numeric priority (lower number == higher severity) # We want to return severities that are equal or higher than the requested severity. requested_priority = ALERT_SEVERITIES[sev_key] # Sort severities by priority (high -> medium -> low -> informational) and include those # whose priority is <= requested_priority (i.e., equal or higher severity). sorted_severities = sorted(ALERT_SEVERITIES.items(), key=lambda kv: kv[1]) return [name for name, pr in sorted_severities if pr <= requested_priority] 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 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 enrich_with_url(output: dict[str, Any], baseUrl: str, id: str) -> dict[str, Any]: """Enriches result with alert url :type output: ``Dict[str, Any]`` :param output: Output to enrich :type baseUrl: ``str`` :param baseUrl: Varonis UI based url :type id: ``str`` :param id: Alert it :return: Enriched output :rtype: ``Dict[str, Any]`` """ output["Url"] = urljoin(baseUrl, f"/analytics/entity/Alert/{id}") return output def varonis_update_alert(client: Client, close_reason_id: Optional[int], status_id: Optional[int], alert_ids: list, note) -> bool: """Update Varonis alert. It creates request and pass it to http client :type client: ``Client`` :param client: Http client :type close_reason_id: ``int`` :param close_reason_id: close reason enum id :type status_id: ``int`` :param status_id: status id enum id :type alert_ids: ``list`` :param alert_ids: list of alert id(s) :type note: ``str`` :param note: alert note :return: Result of execution :rtype: ``bool`` """ if len(alert_ids) == 0: raise ValueError("alert id(s) not specified") if not note and not status_id: raise ValueError("To update update alert you must specify status or note") update_status_result = False add_note_result = False if note: add_note_query: dict[str, Any] = {"AlertGuids": alert_ids, "Note": note} add_note_result = client.varonis_add_note_to_alerts(add_note_query) if status_id: update_status_query: dict[str, Any] = {"AlertGuids": alert_ids, "CloseReasonId": close_reason_id, "StatusId": status_id} demisto.debug(f"update_status_query: {json.dumps(update_status_query)}") update_status_result = client.varonis_update_alert_status(update_status_query) return bool(update_status_result or add_note_result) def convert_incident_alert_to_onprem_format(alert_saas_format): output = alert_saas_format output["Category"] = alert_saas_format.get(AlertAttributes.Alert_Rule_Category_Name) output["ID"] = alert_saas_format.get(AlertAttributes.Alert_ID) output["Name"] = alert_saas_format.get(AlertAttributes.Alert_Rule_Name) output["Status"] = alert_saas_format.get(AlertAttributes.Alert_Status_Name) output["IPThreatTypes"] = alert_saas_format.get(AlertAttributes.Alert_Device_ExternalIPThreatTypesName) output["CloseReason"] = alert_saas_format.get(AlertAttributes.Alert_CloseReason_Name) output["NumOfAlertedEvents"] = alert_saas_format.get(AlertAttributes.Alert_EventsCount) output["ContainsFlaggedData"] = alert_saas_format.get(AlertAttributes.Alert_Data_IsFlagged) output["ContainMaliciousExternalIP"] = alert_saas_format.get(AlertAttributes.Alert_Device_IsMaliciousExternalIP) output["ContainsSensitiveData"] = alert_saas_format.get(AlertAttributes.Alert_Data_IsSensitive) output["Locations"] = [] countries = ( [] if alert_saas_format.get(AlertAttributes.Alert_Location_CountryName) is None else alert_saas_format.get(AlertAttributes.Alert_Location_CountryName).split(",") ) states = ( [] if alert_saas_format.get(AlertAttributes.Alert_Location_SubdivisionName) is None else alert_saas_format.get(AlertAttributes.Alert_Location_SubdivisionName).split(",") ) blacklist_locations = ( [] if alert_saas_format.get(AlertAttributes.Alert_Location_BlacklistedLocation) is None else alert_saas_format.get(AlertAttributes.Alert_Location_BlacklistedLocation).split(",") ) abnormal_locations = ( [] if alert_saas_format.get(AlertAttributes.Alert_Location_AbnormalLocation) is None else alert_saas_format.get(AlertAttributes.Alert_Location_AbnormalLocation).split(",") ) for i in range(len(countries)): entry = { "Country": "" if len(countries) <= i else countries[i], "State": "" if len(states) <= i else states[i], "BlacklistLocation": "" if len(blacklist_locations) <= i else blacklist_locations[i], "AbnormalLocation": "" if len(abnormal_locations) <= i else abnormal_locations[i], } output["Locations"].append(entry) output["Sources"] = [] platforms = ( [] if alert_saas_format.get(AlertAttributes.Alert_Filer_Platform_Name) is None else alert_saas_format.get(AlertAttributes.Alert_Filer_Platform_Name).split(",") ) file_server_or_Domain = ( [] if alert_saas_format.get(AlertAttributes.Alert_Filer_Name) is None else alert_saas_format.get(AlertAttributes.Alert_Filer_Name).split(",") ) for i in range(len(platforms)): entry = { "Platform": "" if len(platforms) <= i else platforms[i], "FileServerOrDomain": "" if len(file_server_or_Domain) <= i else file_server_or_Domain[i], } output["Sources"].append(entry) output["Devices"] = [] device_names = ( [] if alert_saas_format.get(AlertAttributes.Alert_Device_HostName) is None else alert_saas_format.get(AlertAttributes.Alert_Device_HostName).split(",") ) assets = ( [] if alert_saas_format.get(AlertAttributes.Alert_Asset_Path) is None else alert_saas_format.get(AlertAttributes.Alert_Asset_Path).split(",") ) for i in range(len(device_names)): entry = {"Name": "" if len(device_names) <= i else device_names[i], "Asset": "" if len(assets) <= i else assets[i]} output["Devices"].append(entry) output["Users"] = [] user_names = ( [] if alert_saas_format.get(AlertAttributes.Alert_User_Name) is None else alert_saas_format[AlertAttributes.Alert_User_Name].split(",") ) sam_account_names = ( [] if alert_saas_format.get(AlertAttributes.Alert_User_SamAccountName) is None else alert_saas_format[AlertAttributes.Alert_User_SamAccountName].split(",") ) privileged_account_types = ( [] if alert_saas_format.get(AlertAttributes.Alert_User_AccountType_Name) is None else alert_saas_format[AlertAttributes.Alert_User_AccountType_Name].split(",") ) departments = [] if alert_saas_format.get("Department") is None else alert_saas_format["Department"].split(",") for i in range(len(user_names)): entry = { "Name": "" if len(user_names) <= i else user_names[i], "SamAccountName": "" if len(sam_account_names) <= i else sam_account_names[i], "PrivilegedAccountType": "" if len(privileged_account_types) <= i else privileged_account_types[i], "Department": "" if len(departments) <= i else departments[i], } output["Users"].append(entry) return output """ COMMAND FUNCTIONS """ def check_module_command(client: Client) -> CommandResults: """Tests API connectivity and authentication' Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. Raises exceptions if something goes wrong. :type client: ``Client`` :param client: client to use :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ message: str = "" try: client.varonis_get_enum(THREAT_MODEL_ENUM_ID) message = "ok" except DemistoException as e: if "Unauthorized" in str(e): message = "Authorization Error: token is incorrect or expired." else: raise e return CommandResults(readable_output=message) def varonis_get_threat_models_command(client: Client, args: dict[str, Any]) -> CommandResults: """Get threat models from Varonis DA :type client: ``Client`` :param client: Http client :type args: ``Dict[str, Any]`` :param args: all command arguments, usually passed from ``demisto.args()``. ``args['name'] = None # List of requested threat model names :return: A ``CommandResults`` object :rtype: ``CommandResults`` """ name = argToList(args.get("name"), separator="|") threat_models = client.varonis_get_enum(THREAT_MODEL_ENUM_ID) mapper = ThreatModelObjectMapper() mapped_items = mapper.map(threat_models) def filter_threat_model_items(items, criteria): filtered_items = [] # criteria is a dict of key: value or key: list of values keys = criteria.keys() for item in items: isMatch = True for key in keys: criteria_match = False if criteria[key] and len(criteria[key]) > 0: for value in criteria[key]: if isinstance(value, str) and fnmatch.filter([str(item[key])], value): criteria_match = True break if not criteria_match: isMatch = False break if isMatch: filtered_items.append(item) return filtered_items filtered_items = filter_threat_model_items(mapped_items, {"Name": name}) outputs = {} outputs["ThreatModel"] = filtered_items readable_output = tableToMarkdown("Varonis Threat Models", filtered_items, headers=["ID", "Name"]) return CommandResults(readable_output=readable_output, outputs_prefix="Varonis", outputs_key_field="ID", outputs=outputs) def fetch_incidents_command( client: Client, last_run: dict[str, datetime], first_fetch_time: Optional[datetime], alert_status: Optional[str], threat_model: Optional[str], severity: Optional[str], max_fetch: Optional[int] = 1000, ) -> tuple[dict[str, Optional[datetime]], list[dict]]: """This function retrieves new alerts every interval (default is 1 minute). :type client: ``Client`` :param client: Http client :type last_run: ``Dict[str, datetime]`` :param last_run: A dict with a key containing the latest alert ingest time we got from last fetch :type first_fetch_time: ``Optional[datetime]`` :param first_fetch_time: If last_run is None (first time we are fetching), it contains the datetime on when to start fetching incidents :type alert_status: ``Optional[str]`` :param alert_status: status of the alert to search for. Options are 'New', 'Under investigation' or 'Closed' :type threat_model: ``Optional[str]`` :param threat_model: Comma-separated list of threat model names of alerts to fetch :type severity: ``Optional[str]`` :param severity: severity of the alert to search for. Options are 'High', 'Medium' or 'Low' :type max_fetch: ``Optional[int]`` :param max_fetch: Maximum number of incidents per fetch :return: A tuple containing two elements: next_run (``Dict[str, Optional[int]]``): Contains last fetched id. incidents (``List[dict]``): List of incidents that will be created in XSOAR :rtype: ``Tuple[Dict[str, int], List[dict]]`` """ threat_model_names = argToList(threat_model, separator="|") params = demisto.params() incidents: list[dict[str, Any]] = [] if first_fetch_time is None: raise ValueError("first_fetch_time can't be None") last_fetched_ingest_time_str = last_run.get("last_fetched_ingest_time", first_fetch_time.isoformat()) last_fetched_ingest_time = try_convert( last_fetched_ingest_time_str, lambda x: datetime.fromisoformat(x), ValueError(f"last_fetched_ingest_time should be in iso format, but it is {last_fetched_ingest_time_str}."), ) ingest_time_to = datetime.now() demisto.debug(f"Fetching incidents. Last fetched ingest time: {last_fetched_ingest_time}") statuses = [] if alert_status: statuses.append(alert_status) severities = get_included_severitires(severity) if last_fetched_ingest_time is None: raise ValueError("last_fetched_ingest_time cannot be None") max_window = timedelta(days=7) if ingest_time_to - last_fetched_ingest_time > max_window: last_fetched_ingest_time = ingest_time_to - max_window alerts = client.varonis_get_alerts( threat_model_names=threat_model_names, alertIds=None, start_time=None, end_time=None, device_names=None, user_names=None, last_days=None, ingest_time_from=last_fetched_ingest_time, ingest_time_to=ingest_time_to, alert_statuses=statuses, alert_severities=severities, extra_fields=None, descending_order=False, max_fetch=max_fetch, ) demisto.debug(f"varonis_get_alerts returned: {len(alerts)} alerts") for alert in alerts: ingestTime_str = alert[AlertAttributes.Alert_IngestTime] ingestTime = try_convert( alert[AlertAttributes.Alert_IngestTime], lambda x: datetime.fromisoformat(x), ValueError(f"IngestTime should be in iso format, but it is {ingestTime_str}."), ) if not last_fetched_ingest_time or ingestTime > last_fetched_ingest_time: last_fetched_ingest_time = ingestTime + timedelta(seconds=1) guid = alert[AlertAttributes.Alert_ID] name = alert[AlertAttributes.Alert_Rule_Name] alert_time = alert[AlertAttributes.Alert_TimeUTC] enrich_with_url(alert, client._base_url, guid) alert_converted = convert_incident_alert_to_onprem_format(alert) alert_converted.update( { "mirror_direction": MIRROR_DIRECTION_MAPPING.get(params.get("mirror_direction")), "mirror_instance": demisto.integrationInstance(), } ) incident = { "name": f"Varonis alert {name}", "occurred": f"{alert_time}Z", "rawJSON": json.dumps(alert_converted), "type": "Varonis SaaS Incident", "severity": convert_to_demisto_severity(alert_converted[AlertAttributes.Alert_Rule_Severity_Name]), } incidents.append(incident) demisto.debug(f"New incident: {json.dumps(alert, indent=4, sort_keys=True, default=str)}") next_run = {"last_fetched_ingest_time": last_fetched_ingest_time.isoformat()} return next_run, incidents def varonis_get_alerts_command(client: Client, args: dict[str, Any]) -> CommandResults: """Get alerts from Varonis DA :type client: ``Client`` :param client: Http client :type args: ``Dict[str, Any]`` :param args: all command arguments, usually passed from ``demisto.args()``. ``args['threat_model_name']`` List of requested threat models to retrieve ``args['ingest_time_from']`` Start ingest time of the range of alerts ``args['ingest_time_to']`` End ingest time of the range of alerts ``args['start_time']`` Start time of the range of alerts ``args['end_time']`` End time of the range of alerts ``args['alert_status']`` List of required alerts status ``args['alert_severity']`` List of alerts severity ``args['device_name']`` List of device names ``args['last_days']`` Number of days you want the search to go back to ``args['extra_fields']`` Extra fields ``args['descending_order']`` Indicates whether alerts should be ordered in newest to oldest order :return: A ``CommandResults`` object :rtype: ``CommandResults`` """ threat_model_names = args.get("threat_model_name") alert_ids = args.get("alert_ids") start_time = args.get("start_time") end_time = args.get("end_time") ingest_time_from = args.get("ingest_time_from") ingest_time_to = args.get("ingest_time_to") alert_statuses = args.get("alert_status") alert_severities = args.get("alert_severity") device_names = args.get("device_name") user_names = args.get("user_name") last_days = args.get("last_days") extra_fields = args.get("extra_fields") descending_order = argToBoolean(args.get("descending_order", "True")) if last_days: last_days = 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") alert_severities = try_convert(alert_severities, lambda x: argToList(x, separator="|")) device_names = try_convert(device_names, lambda x: argToList(x, separator="|")) threat_model_names = try_convert(threat_model_names, lambda x: argToList(x, separator="|")) user_names = try_convert(user_names, lambda x: argToList(x, separator="|")) extra_fields = try_convert(extra_fields, lambda x: argToList(x, separator="|")) start_time = 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 = try_convert( end_time, lambda x: datetime.fromisoformat(x), ValueError(f"end_time should be in iso format, but it is {start_time}.") ) ingest_time_from = try_convert( ingest_time_from, lambda x: datetime.fromisoformat(x), ValueError(f"ingest_time_from should be in iso format, but it is {ingest_time_from}."), ) ingest_time_to = try_convert( ingest_time_to, lambda x: datetime.fromisoformat(x), ValueError(f"ingest_time_to should be in iso format, but it is {ingest_time_to}."), ) alert_statuses = try_convert(alert_statuses, lambda x: argToList(x, separator="|")) if alert_severities: for severity in alert_severities: if severity.lower() not in ALERT_SEVERITIES: raise ValueError(f"There is no severity {severity}.") if alert_statuses: for status in alert_statuses: if status.lower() not in ALERT_STATUSES: raise ValueError(f"There is no status {status}.") alerts = client.varonis_get_alerts( threat_model_names, alert_ids, start_time, end_time, ingest_time_from, ingest_time_to, device_names, user_names, last_days, alert_statuses, alert_severities, extra_fields, descending_order, ) outputs = {} outputs["Alert"] = alerts alert_attributes = AlertAttributes() if outputs: for alert in alerts: enrich_with_url(alert, client._base_url, alert[alert_attributes.Alert_ID]) readable_output = tableToMarkdown("Varonis Alerts", alerts, headers=alert_attributes.get_fields(extra_fields)) return CommandResults( readable_output=readable_output, outputs_prefix="Varonis", outputs_key_field="Alert.ID", outputs=outputs ) def varonis_get_alerted_events_command(client: Client, args: dict[str, Any]) -> CommandResults: """Get alerted events from Varonis DA :type client: ``Client`` :param client: Http client :type args: ``Dict[str, Any]`` :param args: all command arguments, usually passed from ``demisto.args()``. ``args['alert_id']`` List of alert ids ``args['start_time']`` Start time of the range of events ``args['end_time']`` End time of the range of events ``args['last_days']`` Number of days you want the search to go back to ``args['extra_fields']`` Extra fields ``args['descending_order']`` Indicates whether events should be ordered in newest to oldest order :return: A ``CommandResults`` object :rtype: ``CommandResults`` """ start_time = args.get("start_time") end_time = args.get("end_time") last_days = args.get("last_days") descending_order = argToBoolean(args.get("descending_order", "True")) alertIds = try_convert(args.get("alert_id"), lambda x: argToList(x, separator="|")) start_time = 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 = try_convert( end_time, lambda x: datetime.fromisoformat(x), ValueError(f"end_time should be in iso format, but it is {end_time}.") ) extra_fields = try_convert(args.get("extra_fields"), lambda x: argToList(x, separator="|")) events = client.varonis_get_alerted_events( alertIds=alertIds, start_time=start_time, end_time=end_time, last_days=last_days, extra_fields=extra_fields, descending_order=descending_order, ) outputs = {} outputs["Event"] = events event_attributes = EventAttributes() readable_output = tableToMarkdown("Varonis Alerted Events", events, headers=event_attributes.get_fields(extra_fields)) return CommandResults( readable_output=readable_output, outputs_prefix="Varonis", outputs_key_field="Event.ID", outputs=outputs ) def varonis_alert_add_note_command(client: Client, args: dict[str, Any]) -> bool: """Update Varonis alert status command :type client: ``Client`` :param client: Http client :type args: ``Dict[str, Any]`` :param args: all command arguments, usually passed from ``demisto.args()``. ``args['alert_id']`` Array of alert ids to be updated ``args['note']`` Note for alert :return: Result of execution :rtype: ``bool`` """ note = str(args.get("note")) return varonis_update_alert( client, close_reason_id=None, status_id=None, alert_ids=argToList(args.get("alert_id"), separator="|"), note=note ) def varonis_update_alert_status_command(client: Client, args: dict[str, Any]) -> bool: """Update Varonis alert status command :type client: ``Client`` :param client: Http client :type args: ``Dict[str, Any]`` :param args: all command arguments, usually passed from ``demisto.args()``. ``args['status']`` Alert's new status ``args['alert_id']`` Array of alert ids to be updated ``args['note']`` Note for alert :return: Result of execution :rtype: ``bool`` """ status_id = None status = args.get("status") statuses = list(filter(lambda name: name != "closed", ALERT_STATUSES.keys())) if status: if status.lower() not in statuses: raise ValueError(f"status must be one of {statuses}.") else: status_id = ALERT_STATUSES[status.lower()] note = args.get("note") return varonis_update_alert( client, close_reason_id=None, status_id=status_id, alert_ids=argToList(args.get("alert_id"), separator="|"), note=note ) def varonis_close_alert_command(client: Client, args: dict[str, Any]) -> bool: """Close Varonis alert command :type client: ``Client`` :param client: Http client :type args: ``Dict[str, Any]`` :param args: all command arguments, usually passed from ``demisto.args()``. ``args['close_reason']`` Alert's close reason ``args['alert_id']`` Array of alert ids to be closed ``args['note']`` Note for alert :return: Result of execution :rtype: ``bool`` """ close_reason = str(args.get("close_reason")).lower() close_reason_id = CLOSE_REASONS.get(close_reason) if not close_reason_id: raise ValueError(f"Close reason must be one of {list(CLOSE_REASONS.keys())}") note = args.get("note") return varonis_update_alert( client, close_reason_id, ALERT_STATUSES["closed"], argToList(args.get("alert_id"), separator="|"), note ) def update_remote_system_command(client: Client, args: Dict[str, Any]) -> str: """update-remote-system command: pushes local changes to the remote system :type client: ``Client`` :param client: XSOAR client to use :type args: ``Dict[str, Any]`` :param args: all command arguments, usually passed from ``demisto.args()``. ``args['data']`` the data to send to the remote system ``args['entries']`` the entries to send to the remote system ``args['incidentChanged']`` boolean telling us if the local incident indeed changed or not ``args['remoteId']`` the remote incident id :return: ``str`` containing the remote incident id - really important if the incident is newly created remotely :rtype: ``str`` """ parsed_args = UpdateRemoteSystemArgs(args) alert_id = parsed_args.remote_incident_id if not parsed_args.incident_changed or not alert_id: return alert_id if parsed_args.delta: demisto.debug(f"Got the following delta keys {list(parsed_args.delta)}.") demisto.debug(f"Sending incident with remote ID [{alert_id}] to remote system. Status {parsed_args.inc_status}.") demisto.debug(f"Got the following data {parsed_args.data}.") if ("Status" in parsed_args.delta or "CloseReason" in parsed_args.delta) and ( parsed_args.data.get("Status", "").lower() == "closed" or parsed_args.inc_status == IncidentStatus.DONE ): demisto.debug(f"Closing remote incident {alert_id}") note = parsed_args.data.get("CloseNotes", "Closed from XSOAR") close_reason = parsed_args.data.get("CloseReason", "").lower() close_reason_id = CLOSE_REASONS.get(close_reason, CLOSE_REASONS["other"]) if not close_reason_id: close_reason_id = CLOSE_REASONS["other"] varonis_update_alert(client, close_reason_id, ALERT_STATUSES["closed"], argToList(alert_id), note) elif ( "Status" in parsed_args.delta and parsed_args.data.get("Status").lower() != "closed" ) or parsed_args.inc_status == IncidentStatus.ACTIVE: demisto.debug(f"Update remote incident {alert_id}") note = "Status changed from XSOAR" status = parsed_args.data.get("Status", "under investigation").lower() status_id = ALERT_STATUSES.get(status) close_reason_id = CLOSE_REASONS["none"] varonis_update_alert(client, close_reason_id, status_id, argToList(alert_id), note) return alert_id def get_mapping_fields_command() -> GetMappingFieldsResponse: """ Returns the list of fields for an incident type. Args: client: XSOAR client to use Returns: Dictionary with keys as field names """ demisto.debug("Start getting SchemeTypeMapping.") incident_type_scheme = SchemeTypeMapping(type_name="Varonis SaaS Incident") # If the type is sn_si_incident then add it specific fields else use the snow args as is. out_fields = INCIDENT_FIELDS for field in out_fields: incident_type_scheme.add_field(field) mapping_response = GetMappingFieldsResponse() mapping_response.add_scheme_type(incident_type_scheme) return mapping_response """' MAIN FUNCTION """ def main() -> None: """Main function, parses params and runs command functions :return: :rtype: """ params = demisto.params() command = demisto.command() args = demisto.args() base_url = params["url"] apiKey = params.get("apiKey", {}).get("password") # if your Client class inherits from BaseClient, SSL verification is # handled out of the box by it, just pass ``verify_certificate`` to # the Client constructor verify_certificate = params.get("insecure", False) # if your Client class inherits from BaseClient, system proxy is handled # out of the box by it, just pass ``proxy`` to the Client constructor proxy = params.get("proxy", False) demisto.debug(f"Command being called is {demisto.command()}") try: client = Client(base_url=base_url, verify=verify_certificate, proxy=proxy) client.varonis_authenticate(apiKey) if command == "varonis-get-threat-models": result = varonis_get_threat_models_command(client, args) return_results(result) elif command == "test-module": # This is the call made when pressing the integration Test button. result = check_module_command(client) return_results("ok") elif command == "varonis-get-alerts": return_results(varonis_get_alerts_command(client, args)) elif command == "varonis-get-alerted-events": return_results(varonis_get_alerted_events_command(client, args)) elif command == "varonis-alert-add-note": return_results(varonis_alert_add_note_command(client, args)) elif command == "varonis-update-alert-status": return_results(varonis_update_alert_status_command(client, args)) elif command == "varonis-close-alert": return_results(varonis_close_alert_command(client, args)) elif command == "update-remote-system": return_results(update_remote_system_command(client, args)) elif demisto.command() == "get-mapping-fields": return_results(get_mapping_fields_command()) elif command == "fetch-incidents": alert_status = params.get("status") threat_model = params.get("threat_model") severity = params.get("severity") max_fetch = arg_to_number(params.get("max_fetch")) first_fetch_time = arg_to_datetime( arg=params.get("first_fetch", "1 week"), arg_name="First fetch time", required=True ) next_run, incidents = fetch_incidents_command( client=client, last_run=demisto.getLastRun(), first_fetch_time=first_fetch_time, alert_status=alert_status, threat_model=threat_model, severity=severity, max_fetch=max_fetch, ) demisto.setLastRun(next_run) demisto.incidents(incidents) # Log exceptions and return errors except Exception as e: demisto.error(traceback.format_exc()) # print the traceback return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()