FireEyeHelix
FireEye Helix is a security operations platform. FireEye Helix integrates security tools and augments them with next-generation SIEM, orchestration and threat intelligence tools such as alert management, search, analysis, investigations and reporting.
Analytics & SIEM · FireEye Helix
Details
| ID | FireEyeHelix |
|---|---|
| Provider | Trellix |
| Category | Analytics & SIEM |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Use the FireEye Helix integration to integrate security tools and arguments with next-generation SIEM, orchestration and threat intelligence tools such as alert management, search, analysis, investigations and reporting.
In order to configure this integration you must have a FireEye customer ID. Your customer ID will placed in the FireEye Helix URL of your FireEye Helix app after /helix/id/. e.g. for the following URL https://apps.fireeye.com/helix/id/"helixid" the customer ID is “helixid”.
The API key can be found and generated in the API KEYS section. You can navigate to it from your FireEye Helix app home page by clicking on the user icon on the top right, and choosing HELIX Settings. You’ll be redirected to the HELIX Settings page, where API KEYS can be found.
Configure FireEyeHelix on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for FireEyeHelix.
-
Click Add instance to create and configure a new integration instance.
Parameter Description Example Name A meaningful name for the integration instance. FireEyeHelix_instance_1 Server URL The URL to the FireEye server, including the scheme. https://apps.fireeye.com Customer ID The ID used by the customer to gain access to the integration. N/A API Token The private token granting access to the integration. N/A First Fetch Timestamp The time period for which to fetch incidents in \<number> \<time unit> format. 12 hours, 7 days, 3 months, 1 year Fetch Incident Query Whether to fetch the incidents or not. N/A Incident Type The type of incident to select. Phishing Trust any certificate (not secure) When selected, certificates are not checked. N/A Use System Proxy Settings Runs the integration instance using the proxy server (HTTP or HTTPS) that you defined in the server configuration. https://proxyserver.com - Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
Get all alerts
Returns all alerts.
Base Command
fireeye-helix-list-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| page_size | The maximum number of results to return per page. | Optional |
| offset | The initial index from which to return the results. | Optional |
| headers | The Output values to display in the command result (comma-separated values with no spaces) as they appear in the context. For example, “ID” , “Name”, or “Hostname”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Alert.ID | Number | The primary ID of the alert. |
| FireEyeHelix.Alert.AlertTypeID | Number | The ID of the alert type. |
| FireEyeHelix.Alert.AlertTypeName | String | The name of the alert type. |
| FireEyeHelix.Alert.AssigneeID | String | The ID of the assignee. |
| FireEyeHelix.Alert.AssigneeName | String | The display name of the assignee. |
| FireEyeHelix.Alert.CreatorID | String | The ID of the user who created the alert. |
| FireEyeHelix.Alert.CreatorName | String | The name of the user who created the alert. |
| FireEyeHelix.Alert.UpdaterID | String | The ID of the user who updated the alert. |
| FireEyeHelix.Alert.UpdaterName | String | The Name of the user who updated the alert. |
| FireEyeHelix.Alert.CreatedTime | Date | The time the alert was created. |
| FireEyeHelix.Alert.ModifiedTime | Date | The time the alert was modified. |
| FireEyeHelix.Alert.ProcessPath | String | The path of the process. |
| FireEyeHelix.Alert.Confidence | String | The FireEye Helix confidence with the result. |
| FireEyeHelix.Alert.SHA1 | String | The SHA1 hash of the file. |
| FireEyeHelix.Alert.MD5 | String | The MD5 hash of the file. |
| FireEyeHelix.Alert.Hostname | String | The hostname of the alert. |
| FireEyeHelix.Alert.PID | Number | The process ID. |
| FireEyeHelix.Alert.Size | Number | The size of the process in bytes. |
| FireEyeHelix.Alert.Virues | String | THe virus name. |
| FireEyeHelix.Alert.Result | String | The result of the alert. |
| FireEyeHelix.Alert.MalwareType | String | The malware type. |
| FireEyeHelix.Alert.Filename | String | The name of the file that contains the virus. |
| FireEyeHelix.Alert.RegPath | String | The registry key path. |
| FireEyeHelix.Alert.EventTime | Date | The time of the event. |
| FireEyeHelix.Alert.IOCNames | String | The indicator of the compromise names. |
| FireEyeHelix.Alert.Process | String | The name of the process that created the event. |
| FireEyeHelix.Alert.ParentProcess | String | The name of the parent process of the process that created the event. |
| FireEyeHelix.Alert.SourceIPv4 | String | The source IP address of the event (IPv4). |
| FireEyeHelix.Alert.SourceIPv6 | String | The source IP address of the event (IPv6). |
| FireEyeHelix.Alert.DestinationIPv4 | String | The destination IP address of the event (IPv4). |
| FireEyeHelix.Alert.DestinationIPv6 | String | The destination IP address of the event (IPv6). |
| FireEyeHelix.Alert.DestinationPort | String | The destination port of the event. |
| FireEyeHelix.Alert.URI | String | The URI address that created the event. |
| FireEyeHelix.Alert.HttpMethod | String | The HTTP method of the request that was called. |
| FireEyeHelix.Alert.Domain | String | The domain of the URI that created the event. |
| FireEyeHelix.Alert.UserAgent | String | The user agent related to the event. |
| FireEyeHelix.Alert.EventsCount | Number | The number of events in the alert. |
| FireEyeHelix.Alert.NotesCount | Number | The number of notes in the alert. |
| FireEyeHelix.Alert.ClosedState | String | The status of the alert in regards to it being closed. |
| FireEyeHelix.Alert.ClosedReason | String | The reason the alert was closed. |
| FireEyeHelix.Alert.Confidence | String | The Helix confidence level of the alert. |
| FireEyeHelix.Alert.Description | String | The description of the alert. |
| FireEyeHelix.Alert.FirstEventTime | Date | The time that the first event occurred. |
| FireEyeHelix.Alert.LastEventTime | Date | The time that the last event occurred. |
| FireEyeHelix.Alert.ExternalIP | String | The external IP addresses for the alert. |
| FireEyeHelix.Alert.InternalIP | String | The internal IP addresses for the alert. |
| FireEyeHelix.Alert.Message | String | The message of the alert. |
| FireEyeHelix.Alert.Products | String | The source of the alert. |
| FireEyeHelix.Alert.Risk | String | The risk of the events in the alert. |
| FireEyeHelix.Alert.Severity | String | The severity of the events in the alert. |
| FireEyeHelix.Alert.State | String | The state of the alert. Can be “Open”, “Suppressed”, “Closed”, or “Reopened”. |
| FireEyeHelix.Alert.Tag | String | The tag of the alert. |
| FireEyeHelix.Alert.Type | String | The alert type. |
| FireEyeHelix.Alert.Count | String | The number of alerts. |
Command Example
!fireeye-helix-list-alerts page_size=2
Human Readable Output
FireEye Helix - List alerts
Page 1/58
| ID | Name | Description | State | Severity | |
|---|---|---|---|---|---|
| 123 | HX | FireEye HX detected and quarantined malware on this system. | Open | Medium | |
| 32 | HX | This rule alerts on IOC. | Open | Medium |
Get alert details by ID
Returns alert details, by alert ID.
Base Command
fireeye-helix-get-alert-by-id
Input
| Argument Name | Description | Required |
|---|---|---|
| id | The ID of the alert. | Required |
| headers | A comma-separated list (no spaces) of output values to display in the command result. For example, “ID”, “Name” ,or “Hostname”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Alert.ID | Number | The primary ID of the alert. |
| FireEyeHelix.Alert.AlertTypeID | Number | The ID of the alert type. |
| FireEyeHelix.Alert.AlertTypeName | String | The name of the alert type. |
| FireEyeHelix.Alert.AssigneeID | String | The ID of the alert assignee. |
| FireEyeHelix.Alert.AssigneeName | String | The Assignee display name. |
| FireEyeHelix.Alert.CreatorID | String | The ID of the user who created the alert. |
| FireEyeHelix.Alert.CreatorName | String | The name of the user who created the alert. |
| FireEyeHelix.Alert.UpdaterID | String | The name of the user who updated the alert. |
| FireEyeHelix.Alert.UpdaterName | String | The name of the user who updated the alert. |
| FireEyeHelix.Alert.CreatedTime | Date | The time the alert was created. |
| FireEyeHelix.Alert.ModifiedTime | Date | The time the alert was last modified. |
| FireEyeHelix.Alert.ProcessPath | String | The path of the process. |
| FireEyeHelix.Alert.Confidence | String | The Helix confidence level of the alert. |
| FireEyeHelix.Alert.SHA1 | String | The SHA1 hash of the file. |
| FireEyeHelix.Alert.MD5 | String | The MD5 hash of the file. |
| FireEyeHelix.Alert.Hostname | String | The hostname of the alert. |
| FireEyeHelix.Alert.PID | Number | The process ID. |
| FireEyeHelix.Alert.Size | Number | The size of the process in bytes. |
| FireEyeHelix.Alert.Virus | String | The virus name. |
| FireEyeHelix.Alert.Result | String | The result of the alert. |
| FireEyeHelix.Alert.MalwareType | String | THe malware type. |
| FireEyeHelix.Alert.Filename | String | The name of the file that contains the virus. |
| FireEyeHelix.Alert.RegPath | String | The registry key path. |
| FireEyeHelix.Alert.EventTime | Date | The time that the event occurred. |
| FireEyeHelix.Alert.IOCNames | String | The Indicator of Compromise names. |
| FireEyeHelix.Alert.Process | String | The name of the process that created the event. |
| FireEyeHelix.Alert.ParentProcess | String | The name of the parent process to the process that created the event. |
| FireEyeHelix.Alert.SourceIPv4 | String | The source IP address of the event (IPv4). |
| FireEyeHelix.Alert.SourceIPv6 | String | THe source IP address of the event (IPv6). |
| FireEyeHelix.Alert.DestinationIPv4 | String | The destination IP address of the event (IPv4). |
| FireEyeHelix.Alert.DestinationIPv6 | String | The destination IP address of the event (IPv6). |
| FireEyeHelix.Alert.DestinationPort | String | The destination port of the event. |
| FireEyeHelix.Alert.URI | String | The URI address that created the event. |
| FireEyeHelix.Alert.HttpMethod | String | The HTTP method of the request that was called. |
| FireEyeHelix.Alert.Domain | String | The domain of the URI that created the event. |
| FireEyeHelix.Alert.UserAgent | String | The user agent related to the event. |
| FireEyeHelix.Alert.EventsCount | Number | The number of events in the alert. |
| FireEyeHelix.Alert.NotesCount | Number | The number of notes in the alert. |
| FireEyeHelix.Alert.ClosedState | String | The state the alert is in regards to it being closed. |
| FireEyeHelix.Alert.ClosedReason | String | The reason the alert was closed. |
| FireEyeHelix.Alert.Confidence | String | The Helix confidence level of the alert. |
| FireEyeHelix.Alert.Description | String | The description of the alert. |
| FireEyeHelix.Alert.FirstEventTime | Date | The time that the first event occurred. |
| FireEyeHelix.Alert.LastEventTime | Date | The time that the last event occurred. |
| FireEyeHelix.Alert.ExternalIP | String | The external IP addresses for the alert. |
| FireEyeHelix.Alert.InternalIP | String | The internal IP addresses for the alert. |
| FireEyeHelix.Alert.Message | String | The message of the alert. |
| FireEyeHelix.Alert.Products | String | The source of the alert. |
| FireEyeHelix.Alert.Risk | String | The risk of the events in the alert. |
| FireEyeHelix.Alert.Severity | String | The severity of the events in the alert. |
| FireEyeHelix.Alert.State | String | The state of the alert. Can be “Open”, “Suppressed”, “Closed”, or “Reopened”. |
| FireEyeHelix.Alert.Tag | String | The tag of the alert. |
| FireEyeHelix.Alert.Type | String | The alert type. |
| FireEyeHelix.Alert.Count | String | The number of alerts. |
Command Example
!fireeye-helix-get-alert-by-id id=3232
Human Readable Output
FireEye Helix - Alert 3232
| AlertTypeID | ClosedState | Confidence | CreatedTime | CreatorID | CreatorName | Description | EventsCount | FileName | FirstEventTime | Hostname | ID | LastEventTime | MD5 | MalwareType | Message | ModifiedTime | Name | NotesCount | PID | ProcessPath | Products | Result | Risk | SHA1 | Severity | State | Tags | Type | UpdaterID | UpdaterName | Virus |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1793 | Unknown | high | 2019-03-30T19:40:16.132456Z | id | System User | FireEye HX detected and quarantined malware on this system. | 2 | c:\users\demon\appdata\local\temp | 2019-03-30T14:07:34.132456ZZ | helix.apps.fireeye.com | 123 | 2019-03-31T14:08:07.132456ZZ | md5 | malware | FIREEYE H | 2019-10-20T12:35:02.132456Z | HX | 0 | 11 | c:\windows\microsoft.net\framework\v7.0.30319\csc.exe | hx: 2 | quarantined | Medium | sha1 | Medium | Open | fireeye | fireeye_rule | id | George | gen:variant.ursu |
Create an alert note
Creates an alert note.
Base Command
fireeye-helix-alert-create-note
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The ID of the alert for which the note is being created. | Required |
| note | The note to add to the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Note.ID | Number | The ID of the note. |
| FireEyeHelix.Note.CreatedTime | Date | The time the note was created. |
| FireEyeHelix.Note.UpdatedTime | Date | The time the note was updated. |
| FireEyeHelix.Note.Message | String | The message of the note. |
| FireEyeHelix.Note.CreatorID | String | The ID of the note creator. |
| FireEyeHelix.Note.CreatorName | String | The name of the note creator. |
| FireEyeHelix.Note.AlertID | Number | The ID of the related alert. |
Command Example
!fireeye-helix-alert-create-note note=This is a note test alert_id=3232
Human Readable Output
FireEye Helix - Created Note for Alert 3232
| ID | Creator Name | Message | Created Time |
|---|---|---|---|
| 9 | George | This is a note test | 2019-10-28T07:41:30.396000Z |
List event alerts
Lists events alerts for a specific alert.
Base Command
fireeye-helix-get-events-by-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The alert ID for which to get events. | Required |
| headers | A comma-separated list (no spaces) of output values to display in the command result. For example, “ID”, “Type” , “SourceIPv4”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Event.ID | String | The ID of the event. |
| FireEyeHelix.Event.Type | String | The event type. |
| FireEyeHelix.Event.Result | String | The result of the event. |
| FireEyeHelix.Event.MatchedAt | Date | The time that the event was matched. |
| FireEyeHelix.Event.Confidence | String | The confidence of the event. Can be “low”, “medium”, or “high”. |
| FireEyeHelix.Event.Status | String | The status of the event. |
| FireEyeHelix.Event.EventTime | Date | The time that the event occurred. |
| FireEyeHelix.Event.DetectedRuleID | String | The ID of the detected rule. |
| FireEyeHelix.Event.PID | String | The ID of the process. |
| FireEyeHelix.Event.Process | String | The process details. |
| FireEyeHelix.Event.ProcessPath | String | The process path. |
| FireEyeHelix.Event.FileName | String | The name of the file affected by the event. |
| FireEyeHelix.Event.FilePath | String | The path of the the file affected by the event. |
| FireEyeHelix.Event.DeviceName | String | The name of the device. |
| FireEyeHelix.Event.Size | String | The size of the file (in bytes) that created the event. |
| FireEyeHelix.Event.Virus | String | The virus that was detected in the event. |
| FireEyeHelix.Event.MalwareType | String | The malware type of the virus that was detected. |
| FireEyeHelix.Event.CreatedTime | Date | The time that the event was created. |
| FireEyeHelix.Event.Class | String | The event class. |
| FireEyeHelix.Event.MD5 | String | The MD5 hash of the affected file. |
| FireEyeHelix.Event.SHA1 | String | The SHA1 hash of the affected file. |
| FireEyeHelix.Event.Protocol | String | The protocol used in the event. |
| FireEyeHelix.Event.SourceIPv4 | String | The IPv4 address of the event source. |
| FireEyeHelix.Event.SourceIPv6 | String | The IPv6 address of the event source. |
| FireEyeHelix.Event.SourcePort | String | The port of the event source address. |
| FireEyeHelix.Event.SourceLongitude | String | The longitude of the event source address. |
| FireEyeHelix.Event.SourceLatitude | String | The latitude of the event source address. |
| FireEyeHelix.Event.DestinationIPv4 | String | The IPv4 address of the event destination. |
| FireEyeHelix.Event.DestinationIPv6 | String | The IPv6 address of the event destination. |
| FireEyeHelix.Event.DestinationPort | String | The port of the event destination address. |
| FireEyeHelix.Event.ReportTime | Date | The time that the event was reported. |
| FireEyeHelix.Event.FalsePositive | String | Whether the event is a false positive. |
| FireEyeHelix.Event.Domain | String | The domain of the recipient. |
| FireEyeHelix.Event.From | String | The source email address. |
| FireEyeHelix.Event.SourceDomain | String | The domain of the host that created the event. |
| FireEyeHelix.Event.SourceISP | String | The ISP of the source of the event. |
| FireEyeHelix.Event.DestinationISP | String | The ISP of the destination of the event. |
| FireEyeHelix.Event.To | String | The destination email address. |
| FireEyeHelix.Event.Attachment | Unknown | The email attachment. |
| FireEyeHelix.Event.Count | Number | The total number of events. |
Command Example
!fireeye-helix-get-events-by-alert alert_id=3232
Human Readable Output
FireEye Helix - Events for alert 3232
| Class | Detected Rule ID | Event Time | False Positive | ID | MD5 | Matched At | PID | Process | Process Path | Report Time | Result | Type |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| fireeye_hx_alert | 99 | 2019-09-13T06:51:59.000Z | false | 101 | md5 | 2019-08-11t06:51:40.000z | 404 | net1 | c:\windows\system32\et1.exe | 2019-09-13t06:53:08.000 | alert | processevent |
Get a specific alert
Retrieves a specific alert from an helix endpoint.
Base Command
fireeye-helix-get-endpoints-by-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The ID of an alert. | Required |
| offset | The offset to the result. The default is 0. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Endpoint.ID | Number | The ID of the endpoint. |
| FireEyeHelix.Endpoint.CustomerID | String | The ID of the customer. |
| FireEyeHelix.Endpoint.DeviceID | String | The ID of the device. |
| FireEyeHelix.Endpoint.Domain | String | The domain of the endpoint. |
| FireEyeHelix.Endpoint.Hostname | String | The hostname of the endpoint. |
| FireEyeHelix.Endpoint.MACAddress | String | The MAC address of the endpoint. |
| FireEyeHelix.Endpoint.OS | String | The operating system of the endpoint. |
| FireEyeHelix.Endpoint.IP | String | The IP address of the endpoint. |
| FireEyeHelix.Endpoint.UpdatedTime | Date | The time the endpoint was last updated. |
| FireEyeHelix.Endpoint.ContainmentState | String | The containment state of the endpoint. |
| FireEyeHelix.Endpoint.Count | Number | The total number of endpoints. |
Command Example
!fireeye-helix-get-endpoints-by-alert alert_id=3232 offset=0
Human Readable Output
FireEye Helix - Endpoints for alert 3232
| ID | Device ID | Hostname | IP | MAC Address | Updated Time |
|---|---|---|---|---|---|
| 191 | device_id | Demisto | primary_ip_address | mac_address | updated_at |
Get alert cases
Returns cases of an alert.
Base Command
fireeye-helix-get-cases-by-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The ID of an alert. | Required |
| page_size | The number of results to return per page. | Optional |
| offset | The initial index from which to return the results. | Optional |
| order_by | The field by which to order the results. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Case.AlertsCount | Number | The number of alerts related to the case. |
| FireEyeHelix.Case.AssigneeID | String | The ID of the assignee. |
| FireEyeHelix.Case.AssigneeName | String | The name of the assignee. |
| FireEyeHelix.Case.CreatorID | String | The ID of the case creator. |
| FireEyeHelix.Case.CreatorName | String | The name of the case creator. |
| FireEyeHelix.Case.UpdaterID | String | The ID of the user who last updated the case. |
| FireEyeHelix.Case.UpdaterName | String | The name of the user who last updated the case. |
| FireEyeHelix.Case.CreatedTime | Date | The time that the case was created. |
| FireEyeHelix.Case.ModifiedTime | Date | The time that the case was last modified. |
| FireEyeHelix.Case.Description | String | The case description. |
| FireEyeHelix.Case.EventsCount | Number | The number of events in the case. |
| FireEyeHelix.Case.ID | Number | The ID of the case. |
| FireEyeHelix.Case.InfoLinks | Unknown | The informational or reference links. |
| FireEyeHelix.Case.Name | String | The name of the case. |
| FireEyeHelix.Case.NotesCount | Number | The number of notes in the case. |
| FireEyeHelix.Case.Priority | String | Provides an indication of the order in which the case should be examined as compared to other cases. Can be, “Critical”, “High”, “Medium”, or “Low”. |
| FireEyeHelix.Case.PriorityOrder | Number | Provides an indication of the order in which the case should be examined as compared to other cases. Can be “4”, “3”, “2”, or “1”. |
| FireEyeHelix.Case.Severity | Number | The potential impact that the case could have on the organization if it is a true positive. This is calculated based on the risk of the alert. |
| FireEyeHelix.Case.State | String | The state of the case. |
| FireEyeHelix.Case.Status | String | The cases with the following statuses are considered open, “Declared”, “Scoped”, or “Contained”. |
| Cases with the following statuses are considered closed, “Recovered”, or “Improved”. | ||
| FireEyeHelix.Case.Tags | Unknown | The tags of the case. |
| FireEyeHelix.Case.TotalDaysUnresolved | Number | The number of days the case has been unresolved. |
| FireEyeHelix.Case.Count | Number | The total number of cases. |
Command Example
!fireeye-helix-get-cases-by-alert alert_id=3232 offset=0 page_size=1
Human Readable Output
FireEye Helix - Cases for alert 3232
| ID | Name | Priority | Severity | State | Status | ModifiedTime |
|---|---|---|---|---|---|---|
| 35 | demisto test case | Critical | 10 | Testing | Declared | updated_at |
Get lists
Returns lists.
Base Command
fireeye-helix-get-lists
Input
| Argument Name | Description | Required |
|---|---|---|
| page_size | The number of results to return per page. | Optional |
| offset | The initial index from which to return the results. | Optional |
| usage | The multiple values. May be separated by commas. | Optional |
| created_at | The date that the list was created. | Optional |
| description | The description of the list. | Optional |
| is_active | Whether the list is active. Can be, “true” or “false”. | Optional |
| is_internal | Whether the list is internal. Can be, “true” or “false”. | Optional |
| is_protected | Whether the list is protected. Can be, “true” or “false”. | Optional |
| name | The name of the list. | Optional |
| short_name | The short name of the list. | Optional |
| type | The list type. | Optional |
| updated_at | The time the list was last updated. | Optional |
| order_by | The field by which to order the results. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.List.ID | Number | The list of IDs. |
| FireEyeHelix.List.Description | Number | The list’s description. |
| FireEyeHelix.List.ShortName | String | The short name of the list. |
| FireEyeHelix.List.Name | String | The name of the list. |
| FireEyeHelix.List.ContentTypes | String | The content types of the list. Can be, “Email”, “FQDN”, “IPv4”, “Ipv6”, “SHA1”, “MD5”, or “Misc”. |
| FireEyeHelix.List.CreatorID | String | The ID of the creator. |
| FireEyeHelix.List.CreatorName | String | The name of the creator. |
| FireEyeHelix.List.UpdatedByID | String | The ID of the user who last updated the list. |
| FireEyeHelix.List.CreatedTime | Date | The time that the rule was created. |
| FireEyeHelix.List.UpdatedTime | Date | The time that the rule was last updated. |
| FireEyeHelix.List.Type | String | The list type. Can be “Default”, “Analytics Whitelist”, or “Intel Matching”. |
| FireEyeHelix.List.UpdatedByName | String | The user who last updated the list. |
| FireEyeHelix.List.Internal | Boolean | Whether the list is internal. Can be “true” or “false”. |
| FireEyeHelix.List.Protected | Boolean | Whether the list is protected. Can be “true” or “false”. |
| FireEyeHelix.List.Active | Unknown | Whether the list is active. Can be “true” or “false”. |
| FireEyeHelix.List.Count | Number | The total number of lists. |
Get a specific list by ID
Returns a specific list by list ID.
Base Command
fireeye-helix-get-list-by-id
Input
| Argument Name | Description | Required |
|---|---|---|
| id | The ID of the list. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.List.ID | Number | The ID of the list. |
| FireEyeHelix.List.Description | Number | The list description. |
| FireEyeHelix.List.ShortName | String | The short name of the list. |
| FireEyeHelix.List.Name | String | The name of the list. |
| FireEyeHelix.List.ContentTypes | String | The content types of the list. Can be “Email”, “FQDN”, “IPv4”, “Ipv6”, “SHA1”, “MD5”, or “Misc”. |
| FireEyeHelix.List.CreatorID | String | The ID of the creator. |
| FireEyeHelix.List.CreatorName | String | The name of the creator. |
| FireEyeHelix.List.UpdatedByID | String | The ID of the user who last updated the list. |
| FireEyeHelix.List.CreatedTime | Date | The time that the rule was created. |
| FireEyeHelix.List.UpdatedTime | Date | The time that the rule was last updated. |
| FireEyeHelix.List.Type | String | The list type. Can be “Default”, “Analytics Whitelist”, or “Intel Matching”. |
| FireEyeHelix.List.UpdatedByName | String | The name of the user who last updated the list. |
| FireEyeHelix.List.Internal | Boolean | Whether the list is internal. Can be “true” or “false”. |
| FireEyeHelix.List.Protected | Boolean | Whether the list is protected. Can be “true” or “false”. |
| FireEyeHelix.List.Active | Unknown | Whether the list is active. Can be “true” or “false”. |
Create a list
Creates a list.
Base Command
fireeye-helix-create-list
Input
| Argument Name | Description | Required |
|---|---|---|
| name | The name of the list. | Required |
| short_name | The short name of the list. | Optional |
| is_internal | Whether the list is internal. Can be “true” or “false”. | Optional |
| is_active | Whether the list is active. Can be “true” or “false”. | Optional |
| is_protected | Whether the list is protected. Can be “true” or “false”. | Optional |
| usage | A comma-separated list of list uses. | Optional |
| is_hidden | Whether the list is hidden. Can be “true” or “false”. | Optional |
| type | The list type. | Optional |
| description | The description of the list. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.List.ID | Number | The list ID. |
| FireEyeHelix.List.Description | Number | The list description. |
| FireEyeHelix.List.ShortName | String | The sShort name of the list. |
| FireEyeHelix.List.Name | String | The name of the list. |
| FireEyeHelix.List.ContentTypes | String | The content types of the list. Can be “Email”, “FQDN”, “IPv4”, “IPv6”, “SHA1”, “MD5”, or “Misc”. |
| FireEyeHelix.List.CreatorID | String | The ID of the list creator. |
| FireEyeHelix.List.CreatorName | String | The name of the list creator. |
| FireEyeHelix.List.UpdatedByID | String | The ID of the user who last updated the list. |
| FireEyeHelix.List.CreatedTime | Date | The time that the rule was created. |
| FireEyeHelix.List.UpdatedTime | Date | The time that the rule was last updated. |
| FireEyeHelix.List.Type | String | The list type. Can be “Default”, “Analytics Whitelist”, or “Intel Matching”. |
| FireEyeHelix.List.UpdatedByName | Unknown | The name of the user who last updated the list. |
| FireEyeHelix.List.Internal | Boolean | Whether the list is internal. Can be “true” or “false”. |
| FireEyeHelix.List.Protected | Boolean | Whether the list is protected. Can be “true” or “false”. |
| FireEyeHelix.List.Active | Unknown | Whether the list is active. Can be “true” or “false”. |
Update a list
Updates an existing list.
Base Command
fireeye-helix-update-list
Input
| Argument Name | Description | Required |
|---|---|---|
| name | The name of the list to update. | Optional |
| short_name | The short name of the list. | Optional |
| is_internal | Whether the list is internal. Can be “true” or “false”. | Optional |
| is_active | Whether the list is active. Can be “true” or “false”. | Optional |
| is_protected | Whether the list is protected. Can be “true” or “false”. | Optional |
| usage | A comma-separated list of list uses. | Optional |
| is_hidden | Whether the list is hidden. Can be “true” or “false”. | Optional |
| type | The list type. | Optional |
| description | The description of the list. | Optional |
| list_id | The ID of the list. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.List.ID | Number | The ID of the list. |
| FireEyeHelix.List.Description | Number | The list description. |
| FireEyeHelix.List.ShortName | String | The short name of the list. |
| FireEyeHelix.List.Name | String | The name of the list. |
| FireEyeHelix.List.ContentTypes | String | The content types of the list. Can be “Email”, “FQDN”, “IPv4”, “IPv6”, “SHA1”, “MD5”, or “Misc”. |
| FireEyeHelix.List.CreatorID | String | The ID of the creator. |
| FireEyeHelix.List.CreatorName | String | The name of the creator. |
| FireEyeHelix.List.UpdatedByID | String | The ID of the user who last updated the list. |
| FireEyeHelix.List.CreatedTime | Date | The time that the rule was created. |
| FireEyeHelix.List.UpdatedTime | Date | The time that the rule was last updated. |
| FireEyeHelix.List.Type | String | The list type. Can be “Default”, “Analytics Whitelist”, or “Intel Matching”. |
| FireEyeHelix.List.UpdatedByName | Unknown | The name of the user who last updated the list. |
| FireEyeHelix.List.Internal | Boolean | Whether the list is internal. Can be “true” or “false”. |
| FireEyeHelix.List.Protected | Boolean | Whether the list is protected. Can be “true” or “false”. |
| FireEyeHelix.List.Active | Unknown | Whether the list is active. Can be “true” or “false”. |
Delete a list
Deletes a single list by list ID.
Base Command
fireeye-helix-delete-list
Input
| Argument Name | Description | Required |
|---|---|---|
| list_id | The ID of the list to delete. | Required |
Context Output
There is no context output for this command.
Fetch all sensors
Fetches all sensors.
Base Command
fireeye-helix-list-sensors
Input
| Argument Name | Description | Required |
|---|---|---|
| page_size | The maximum number of results to return per page. | Optional |
| offset | The initial index from which to return the results. | Optional |
| hostname | The host name of the sensor. | Optional |
| status | The status of the sensor. | Optional |
Context Output
There is no context output for this command.
Get all rules
Returns all rules.
Base Command
fireeye-helix-list-rules
Input
| Argument Name | Description | Required |
|---|---|---|
| page_size | The maximum number of results to return per page. | Optional |
| offset | The initial index from which to return the results. | Optional |
| sort | A comma-separated list of field names by which to sort the results. For example, “createDate” or “-updateDate,riskOrder” | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Rule.ID | String | The rule ID. |
| FireEyeHelix.Rule.RulePack | String | The rule package version. |
| FireEyeHelix.Rule.Description | String | The rule description. |
| FireEyeHelix.Rule.Internal | Boolean | Whether the rule is internal. Can be “true” or “false”. |
| FireEyeHelix.Rule.Deleted | Boolean | Whether the rule was deleted. Can be “true” or “false”. |
| FireEyeHelix.Rule.Enabled | Boolean | Whether the rule is enabled. Can be “true” or “false”. |
| FireEyeHelix.Rule.Supported | Boolean | Whether the rule is supported. Can be “true” or “false”. |
| FireEyeHelix.Rule.CreatorID | String | The ID of the rule creator. |
| FireEyeHelix.Rule.CreatorName | String | The name of the rule creator. |
| FireEyeHelix.Rule.UpdatedByID | String | The ID of the user who updated the rule. |
| FireEyeHelix.Rule.UpdatedByName | String | The name of the user who updated the rule. |
| FireEyeHelix.Rule.Risk | String | The risk to your environment when an event matches this rule. Can be “low”, “medium”, “high”, or “critical”. |
| FireEyeHelix.Rule.Confidence | String | The confidence that indicates how likely it is that the rule will detect events that correspond to the type of activity anticipated. (The likelihood that the rule will produce true positives). Confidence and Severity combine to form the risk attribute of the alert. Can be “low”, “medium”, or “high”. |
| FireEyeHelix.Rule.Severity | String | The severity that indicates how much of an impact a hit with this rule could have on an organization if |
| verified to be a true positive. Confidence and Severity combine to form the risk attribute of the alert. Can be “low”, “medium”, or “high”. | ||
| FireEyeHelix.Rule.Tags | String | The tags of the rule. |
| FireEyeHelix.Rule.Type | String | The type of the rule. |
Command Example
!fireeye-helix-list-rules offset=1
Human Readable Output
FireEye Helix - List rules
| ID | Type | Description | Risk | Confidence | Severity | Enabled |
|---|---|---|---|---|---|---|
| 1.1.1 | alert | demisto | Medium | Medium | Medium | true |
Edit an existing rule
Modifies an existing rule.
Base Command
fireeye-helix-edit-rule
Input
| Argument Name | Description | Required |
|---|---|---|
| enabled | Whether the rule is enabled. Can be “true” or “false”. | Optional |
| rule_id | The ID of the rule. | Required |
Context Output
There is no context output for this command.
Command Example
!fireeye-helix-edit-rule rule_id=1.1.1 enabled=true
Human Readable Output
FireEye Helix - Successfully updated rule 1.1.1
| ID | Type | Description | Risk | Confidence | Severity |
|---|---|---|---|---|---|
| 1.1.1 | alert | demisto | Medium | Medium | Medium |
Get all notes related to an alert
Returns all notes related to an alert.
Base Command
fireeye-helix-alert-get-notes
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The ID of the alert. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelix.Note.ID | Number | The ID of the note. |
| FireEyeHelix.Note.CreatedTime | Date | The time that the note was created. |
| FireEyeHelix.Note.UpdatedTime | Date | The time that the note was updated. |
| FireEyeHelix.Note.Message | String | The message of the note. |
| FireEyeHelix.Note.CreatorID | String | The ID of the note creator. |
| FireEyeHelix.Note.CreatorName | String | The name of the note creator. |
| FireEyeHelix.Note.AlertID | Number | The ID of the related alert. |
| FireEyeHelix.Note.Count | Number | The total number of notes for the alert. |
Command Example
!fireeye-helix-alert-get-notes id=3232
Human Readable Output
FireEye Helix - Notes for Alert None
| ID | Creator Name | Message | Created Time |
|---|---|---|---|
| 9 | George | This is a note test | 2019-10-28T07:41:30.396000Z |
| 91 | George | What a great note this is | 2019-10-24T13:52:19.021299Z |
Delete a note’s alert
Deletes a note’s alert.
Base Command
fireeye-helix-alert-delete-note
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | The ID of the alert to delete. | Required |
| note_id | The ID of the note. | Required |
Context Output
There is no context output for this command.
Preform a search
Executes a search in FireEye Helix using MQL.
Base Command
fireeye-helix-search
Input
| Argument Name | Description | Required |
|---|---|---|
| start | The start time of the event in the format yyyy-mm-dd or yyyy-mm. | Optional |
| end | The end time of the event in the format yyyy-mm-dd or yyyy-mm. | Optional |
| page_size | The maximum number of results to return. | Optional |
| offset | The offset of the result. | Optional |
| groupby | Returns the unique values for the specified field and groups them based on the specified frequency. For example, groupby="srcipv4 5 100" will group the top five srcipv4 addresses that have at least 100 occurrences. Supports comma-separated values. |
Optional |
| sort_by | The field by which to sort the results. | Optional |
| sort_order | The order of the results sorted by the sort_by argument. Can be “asc” for ascending, or “desc” for descending. The default is “desc”. |
Optional |
| query | The query to execute. This is the search clause in an MQL. | Required |
| limit | The number of events to search. | Optional |
| headers | A comma-separated list (no spaces) of output values to display in the command result. For example, “ID”, “Type”, or “SourceIPv4”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelixSearch.Result.ID | String | The ID of the event. |
| FireEyeHelixSearch.Result.Type | String | The event type. |
| FireEyeHelixSearch.Result.Result | String | The event result. |
| FireEyeHelixSearch.Result.MatchedAt | Date | The time that the event was matched. |
| FireEyeHelixSearch.Result.Confidence | String | The confidence of the event. Can be “low”, “medium”, or “high”. |
| FireEyeHelixSearch.Result.Status | String | The status of the event. |
| FireEyeHelixSearch.Result.EventTime | Date | The time that the event occurred. |
| FireEyeHelixSearch.Result.DetectedRuleID | String | The ID of the detected rule. |
| FireEyeHelixSearch.Result.PID | String | The process ID. |
| FireEyeHelixSearch.Result.Process | String | The process details. |
| FireEyeHelixSearch.Result.ProcessPath | String | The process path. |
| FireEyeHelixSearch.Result.FileName | String | The name of the file affected by the event. |
| FireEyeHelixSearch.Result.FilePath | String | The path of the the file affected by the event. |
| FireEyeHelixSearch.Result.DeviceName | String | The device name. |
| FireEyeHelixSearch.Result.Size | String | The size of the file (in bytes) that created the event. |
| FireEyeHelixSearch.Result.Virus | String | The virus that was detected in the event. |
| FireEyeHelixSearch.Result.MalwareType | String | The malware type of the virus that was detected. |
| FireEyeHelixSearch.Result.CreatedTime | Date | The time that the event was created. |
| FireEyeHelixSearch.Result.Class | String | The event class. |
| FireEyeHelixSearch.Result.MD5 | String | The MD5 hash of the affected file. |
| FireEyeHelixSearch.Result.SHA1 | String | The SHA1 hash of the affected file. |
| FireEyeHelixSearch.Result.Protocol | String | The protocol used in the event. |
| FireEyeHelixSearch.Result.SourceIPv4 | String | The IPv4 address of the event source. |
| FireEyeHelixSearch.Result.SourceIPv6 | String | The IPv6 address of the event source. |
| FireEyeHelixSearch.Result.SourcePort | String | The port of the event source address. |
| FireEyeHelixSearch.Result.SourceLongitude | String | The longitude of the event source address. |
| FireEyeHelixSearch.Result.SourceLatitude | String | The latitude of the event source address. |
| FireEyeHelixSearch.Result.DestinationIPv4 | String | The IPv4 address of the event destination. |
| FireEyeHelixSearch.Result.DestinationIPv6 | String | The IPv6 address of the event destination. |
| FireEyeHelixSearch.Result.DestinationPort | String | The port of the event destination address. |
| FireEyeHelixSearch.Result.ReportTime | Date | The time that the event was reported. |
| FireEyeHelixSearch.Result.FalsePositive | String | Whether the event is a false positive. |
| FireEyeHelixSearch.Result.Domain | String | The domain of the recipient. |
| FireEyeHelixSearch.Result.From | String | The source email address. |
| FireEyeHelixSearch.Result.SourceDomain | String | The domain of the host that created the event. |
| FireEyeHelixSearch.Result.SourceISP | String | The ISP of the source of the event. |
| FireEyeHelixSearch.Result.DestinationISP | String | The ISP of the destination of the event. |
| FireEyeHelixSearch.Result.To | String | The destination email address. |
| FireEyeHelixSearch.Result.Attachment | Unknown | The email attachment. |
| FireEyeHelixSearch.MQL | String | The MQL query that created the result. |
| FireEyeHelixSearch.GroupBy | Unknown | The group by values. |
| FireEyeHelixSearch.GroupBy.DocCount | Number | The number of matches for the group. |
| FireEyeHelixSearch.Result.RcpTo | String | The recipient email address. |
| FireEyeHelixSearch.Result.InReplyTo | String | The reply email address. |
Command Example
!fireeye-helix-search query=domain:google.com start="4 days ago" groupby=subject limit=1 page_size=2
Human Readable Output
FireEye Helix - Search result for domain:google.com and meta_ts>=2019-10-25T09:07:43.810Z {page_size:2 offset:1 limit:1} | groupby subject sep=|%$,$%|
| Class | Domain | Event Time | From | ID | In Reply To | Source Domain | Source I Pv 4 | Source ISP | Source Latitude | Source Longitude | Status | To | Type |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| fireeye_etp | mx.google.com | 2019-10-28T10:43:11.000Z | de@demisto.com | demisto | demisto | google.com | 8.8.8.8 | google llc | 37.40599060058594 | -122.0785140991211 | delivered | demisto@demisto.com | trace |
| fireeye_etp | gmr-mx.google.com | 2019-10-29T05:08:39.000Z | dem@demisto.com | demisto | demisto@demisto.com | google.com | 8.8.8.8 | google llc | 37.40599060058594 | -122.0785140991211 | delivered | demisto@demisto.com | trace |
Group By
| subject | DocCount |
|---|---|
| google alert - gold | 3 |
| accepted: meeting | 1 |
| invitation: Declined | 1 |
Add an item to a list
Adds an item to a list.
Base Command
fireeye-helix-add-list-item
Input
| Argument Name | Description | Required |
|---|---|---|
| type | The item type. Can be, “email”, “fqdn”, “ipv4”, “ipv6”, “md5”, “misc”, or “sha-1”. | Required |
| value | The item value. | Required |
| list_id | The ID of the list. | Required |
| risk | The risk of the item. Can be, “Low”, “Medium”, “High”, or “Critical”. | Optional |
| notes | The item notes. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelixList.Item.ID | Number | The ID of the item. |
| FireEyeHelixList.Item.Value | String | The value of the item. |
| FireEyeHelixList.Item.Type | String | The type of the item. Can be “email”, “fqdn”, “ipv4”, “ipv6”, “md5”, “misc”, or “sha-1”. |
| FireEyeHelixList.Item.Risk | String | The risk of the item. Can be “Low”, “Medium”, “High”, or “Critical”. |
| FireEyeHelixList.Item.Notes | String | The notes of the item. |
| FireEyeHelixList.Item.ListID | String | The list ID with which the item is associated. |
Command Example
!fireeye-helix-add-list-item list_id=3232 value=test type=misc risk=Low
Human Readable Output
FireEye Helix - List item 163 was added successfully to 3232
| ID | ListID | Notes | Risk | Type | Value |
|---|---|---|---|---|---|
| 163 | 3232 | test ok | Medium | misc | aTest list |
Fetch list items
Fetches the items of a list.
Base Command
fireeye-helix-get-list-items
Input
| Argument Name | Description | Required |
|---|---|---|
| list_id | The ID of the list for which to fetch items. | Required |
| offset | THe item offset. The default is 0. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelixList.Item.ID | Number | The ID of the item. |
| FireEyeHelixList.Item.Value | String | The value of the item. |
| FireEyeHelixList.Item.Type | String | The type of the item. Can be “email”, “fqdn”, “ipv4”, “ipv6”, “md5”, “misc”, or “sha-1”. |
| FireEyeHelixList.Item.Risk | String | The risk of the item. Can be “Low”, “Medium”, “High”, or “Critical”. |
| FireEyeHelixList.Item.Notes | String | The notes of the item. |
| FireEyeHelixList.Item.ListID | String | The list ID with which the item is associated. |
| FireEyeHelixList.Item.Count | Number | The number of items in the list. |
Command Example
!fireeye-helix-get-list-items list_id=3232 offset=0
Human Readable Output
FireEye Helix - List items for list 3232
| ID | ListID | Notes | Risk | Type | Value |
|---|---|---|---|---|---|
| 163 | 3232 | Low | misc | Test list |
Update an item on a list
Updates a single list item.
Base Command
fireeye-helix-update-list-item
Input
| Argument Name | Description | Required |
|---|---|---|
| item_id | The ID of the item to update. | Required |
| type | The item type. Can be “email”, “fqdn”, “ipv4”, “ipv6”, “md5”, “misc”, or “sha-1”. | Optional |
| value | The value of the item. | Optional |
| list_id | The ID of the list. | Required |
| risk | The risk of the item. Can be “Low”, “Medium”, “High”, or “Critical”. | Optional |
| notes | The notes of the item. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelixList.Item.ID | Number | The ID of the item. |
| FireEyeHelixList.Item.Value | String | The value of the item. |
| FireEyeHelixList.Item.Type | String | The item type. Can be “email”, “fqdn”, “ipv4”, “ipv6”, “md5”, “misc”, or “sha-1”. |
| FireEyeHelixList.Item.Risk | String | The risk of the item. Can be, “Low”, “Medium”, “High”, or “Critical”. |
| FireEyeHelixList.Item.Notes | String | The notes of the item. |
| FireEyeHelixList.Item.ListID | String | The list ID with which the item is associated. |
Command Example
!fireeye-helix-update-list-item list_id=3232 value=test type=misc risk=Low item_id=163
Human Readable Output
FireEye Helix - List item 163 from list 3232 was updated successfully
| ID | ListID | Notes | Risk | Type | Value |
|---|---|---|---|---|---|
| 163 | 3232 | test ok | Medium | misc | aTest list |
Remove an item from a list
Removes an item from a list.
Base Command
fireeye-helix-remove-list-item
Input
| Argument Name | Description | Required |
|---|---|---|
| list_id | The ID of the list from which to remove an item. | Required |
| item_id | The ID of the item. | Required |
Context Output
There is no context output for this command.
Fetch archive search results
Fetches archive search results.
Base Command
fireeye-helix-archive-search-get-results
Input
| Argument Name | Description | Required |
|---|---|---|
| search_id | The ID of the search for which to return archive results. | Required |
| headers | A comma-separated list of output values to display in the command result. For example, “ID”, “Type”, and “SourceIPv4”. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelixSearch.Result.ID | String | The ID of the event. |
| FireEyeHelixSearch.Result.Type | String | The type of the event. |
| FireEyeHelixSearch.Result.Result | String | The result of the event. |
| FireEyeHelixSearch.Result.MatchedAt | Date | The time that the event was matched. |
| FireEyeHelixSearch.Result.Confidence | String | The confidence of the event. Can be “low”, “medium”, or “high”. |
| FireEyeHelixSearch.Result.Status | String | The status of the event. |
| FireEyeHelixSearch.Result.EventTime | Date | The time that the event occurred. |
| FireEyeHelixSearch.Result.DetectedRuleID | String | The ID of the detected rule. |
| FireEyeHelixSearch.Result.PID | String | The ID of the process. |
| FireEyeHelixSearch.Result.Process | String | The details of the process. |
| FireEyeHelixSearch.Result.ProcessPath | String | The path of the process. |
| FireEyeHelixSearch.Result.FileName | String | The name of the file affected by the event. |
| FireEyeHelixSearch.Result.FilePath | String | The path of the the file affected by the event. |
| FireEyeHelixSearch.Result.DeviceName | String | The name of the device. |
| FireEyeHelixSearch.Result.Size | String | The size of the file (in bytes) that created the event. |
| FireEyeHelixSearch.Result.Virus | String | The virus that was detected in the event. |
| FireEyeHelixSearch.Result.MalwareType | String | The malware type of the virus that was detected. |
| FireEyeHelixSearch.Result.CreatedTime | Date | The time that the event was created. |
| FireEyeHelixSearch.Result.Class | String | The class of the event. |
| FireEyeHelixSearch.Result.MD5 | String | The MD5 hash of the affected file. |
| FireEyeHelixSearch.Result.SHA1 | String | The SHA1 hash of the affected file. |
| FireEyeHelixSearch.Result.Protocol | String | The protocol used in the event. |
| FireEyeHelixSearch.Result.SourceIPv4 | String | The IPv4 address of the event source. |
| FireEyeHelixSearch.Result.SourceIPv6 | String | The IPv6 address of the event source. |
| FireEyeHelixSearch.Result.SourcePort | String | The port of the event source address. |
| FireEyeHelixSearch.Result.SourceLongitude | String | The longitude of the event source address. |
| FireEyeHelixSearch.Result.SourceLatitude | String | The latitude of the event source address. |
| FireEyeHelixSearch.Result.DestinationIPv4 | String | The IPv4 address of the event destination. |
| FireEyeHelixSearch.Result.DestinationIPv6 | String | The IPv6 address of the event destination. |
| FireEyeHelixSearch.Result.DestinationPort | String | The port of the event destination address. |
| FireEyeHelixSearch.Result.ReportTime | Date | The time that the event was reported. |
| FireEyeHelixSearch.Result.FalsePositive | String | Whether the event is a false positive. |
| FireEyeHelixSearch.Result.Domain | String | The domain of the recipient. |
| FireEyeHelixSearch.Result.From | String | The email address of the source. |
| FireEyeHelixSearch.Result.SourceDomain | String | The domain of the host that created the event. |
| FireEyeHelixSearch.Result.SourceISP | String | The ISP of the source of the event. |
| FireEyeHelixSearch.Result.DestinationISP | String | The ISP of the destination of the event. |
| FireEyeHelixSearch.Result.To | String | The destination email address. |
| FireEyeHelixSearch.Result.Attachment | Unknown | The email attachment. |
| FireEyeHelixSearch.MQL | String | The MQL query that created the result. |
| FireEyeHelixSearch.GroupBy | Unknown | The group by values. |
| FireEyeHelixSearch.GroupBy.DocCount | Number | The number of matches for the group. |
| FireEyeHelixSearch.Result.RcpTo | String | The recipient email address. |
| FireEyeHelixSearch.Result.InReplyTo | String | The reply email address. |
Command Example
!fireeye-helix-archive-search-get-results search_id=82
Human Readable Output
FireEye Helix - Search result for domain:[google,com] | groupby eventtype sep=|%$,$%|
| Class | Domain | Event Time | From | ID | In Reply To | Source Domain | Source I Pv 4 | Source ISP | Source Latitude | Source Longitude | Status | To | Type |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| fireeye_etp | domain.com | 2019-10-06T10:48:13.000Z | squidward@demisto.com | evenid | squidward squidward@demisto.com | 8.8.8.8 | 51.8594 | -0.12574 | delivered | demisto@demisto.com | trace | ||
| fireeye_etp | demisto.com | 2019-10-06T11:02:01.000Z | squidward@demisto.com | demisto | "squidward" <fsquidward@demisto.com> | squidward.com | 8.8.8.8 | squidward | 40.282958 | -75.19625 | delivered | squidward@demisto.com | trace |
| fireeye_etp | demisto.com | 2019-10-06T11:02:18.000Z | squidward@demisto.com | dwasdkffv | squidward <squidward@demisto.com> | demisto.com | 8.8.8.8 | demistos | 33.5 | -93.119 | delivered | squidward@demisto.com | trace |
| fireeye_etp | demisto.com | 2019-10-06T11:03:00.000Z | squidward@demisto.com | 93730 | geroge <hello@demisto.com> | demisto.com | 8.8.8.8 | the demisto group | 33.770843 | -84.377 | delivered | squidward@demisto.com | trace |
Create an archive from a query
Creates an archive search from a query.
Base Command
fireeye-helix-archive-search
Input
| Argument Name | Description | Required |
|---|---|---|
| start | The start time of the event in the format yyyy-mm-dd or yyyy-mm. | Optional |
| end | The end time of the event in the format yyyy-mm-dd or yyyy-mm. | Optional |
| offset | The offset of the result. | Optional |
| groupby | The unique values for the specified field. This groups them based on the specified frequency. For example, groupby="srcipv4 5 100" will group the top five srcipv4 addresses that have at least 100 occurrences. Supports comma-separated values. |
Optional |
| sort_by | Sorts results by this field. | Optional |
| sort_order | Controls the order of the results sorted by the sort_by argument. Can be “asc” for ascending, or “desc” for descending. The default is “desc”. |
Optional |
| query | The query to execute. This is the search clause in an MQL. | Required |
| limit | The number of events to search. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelixSearch.ID | Number | The ID of an archive search. |
| FireEyeHelixSearch.PercentComplete | String | The percentage of the search that was completed. |
| FireEyeHelixSearch.Query | String | The search query. |
| FireEyeHelixSearch.State | String | The state of the search. |
Command Example
!fireeye-helix-archive-search query=domain:google.com start="4 days ago" groupby=subject limit=1 offset=1
Human Readable Output
FireEye Helix - Successfully created archive search
| ID | Percent Complete | Query | State |
|---|---|---|---|
| 82 | 100.0 | domain:[google,com] | groupby eventtype | completed |
| 83 | 100.0 | domain:[google] | groupby eventtype | completed |
Get the status of an archive search
Gets the status of an archive search.
Base Command
fireeye-helix-archive-search-get-status
Input
| Argument Name | Description | Required |
|---|---|---|
| search_id | The archive search’s ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHelixSearch.ID | Number | The archive search’s ID. |
| FireEyeHelixSearch.PercentComplete | String | The percentage of the search that was completed. |
| FireEyeHelixSearch.Query | String | The search query. |
| FireEyeHelixSearch.State | String | The state of the search. |
Command Example
!fireeye-helix-archive-search-get-status search_id=82,83
Human Readable Output
FireEye Helix - Search status
| ID | Percent Complete | Query | State |
|---|---|---|---|
| 82 | 100.0 | domain:[google,com] | groupby eventtype | completed |
| 83 | 100.0 | domain:[google,com] | groupby eventtype | completed |
Configuration parameters
url— Server URL (e.g. https://apps.fireeye.com) (required)h_id— Customer IDtoken— API Tokenh_id_creds— Customer IDfetch_time— First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days, 3 months, 1 year)isFetch— Fetch incidentsincidentType— Incident typeincidentFetchInterval— Incidents Fetch Intervalinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (24)
-
fireeye-helix-add-list-itemAdds an item to a list.
-
fireeye-helix-alert-create-noteCreates an alert note.
-
fireeye-helix-alert-delete-noteDeletes an alert note.
-
fireeye-helix-alert-get-notesReturns all notes related to an alert.
-
fireeye-helix-archive-searchCreates an archive search from a query.
-
fireeye-helix-archive-search-get-resultsFetches archive search results.
-
fireeye-helix-archive-search-get-statusGets the status of an archive search.
-
fireeye-helix-create-listCreates a list.
-
fireeye-helix-delete-listDeletes a single list by list ID.
-
fireeye-helix-edit-ruleModifies an existing rule.
-
fireeye-helix-get-alert-by-idReturns alert details, by alert ID.
-
fireeye-helix-get-cases-by-alertReturns cases of an alert.
-
fireeye-helix-get-endpoints-by-alertRetrieves a specific alert from an helix endpoint.
-
fireeye-helix-get-events-by-alertLists alert events for a specific alert.
-
fireeye-helix-get-list-by-idReturns a specific list by list ID.
-
fireeye-helix-get-list-itemsFetches items of a list.
-
fireeye-helix-get-listsReturns lists.
-
fireeye-helix-list-alertsReturns all alerts.
-
fireeye-helix-list-rulesReturns all rules.
-
fireeye-helix-list-sensorsFetches all sensors.
-
fireeye-helix-remove-list-itemRemoves an item from a list.
-
fireeye-helix-searchExecutes a search in FireEye Helix using MQL.
-
fireeye-helix-update-listUpdates an existing list.
-
fireeye-helix-update-list-itemUpdates a single list item.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import math from CommonServerUserPython import * """ IMPORTS """ from typing import Any import urllib3 # Disable insecure warnings urllib3.disable_warnings() """GLOBALS/PARAMS Attributes: INTEGRATION_NAME: Name of the integration as shown in the integration UI. INTEGRATION_COMMAND_NAME: Command names prefix used for all commands. INTEGRATION_CONTEXT_NAME: Context output name used in most outputs. ALERTS_TRANS Transformation map for alerts to be used with create_context_result ARCHIVE_SEARCH_TRANS Transformation map for archive search to be used with create_context_result CASES_TRANS Transformation map for cases to be used with create_context_result ENDPOINTS_TRANS Transformation map for endpoints to be used with build_transformation_dict EVENTS_TRANS Transformation map for events to be used with build_transformation_dict LISTS_TRANS Transformation map for lists to be used with create_context_result LIST_ITEM_TRANS Transformation map for list items to be used with create_context_result NOTES_TRANS Transformation map for notes to be used with create_context_result RULES_TRANS Transformation map for rules to be used with create_context_result """ INTEGRATION_NAME = "FireEye Helix" INTEGRATION_COMMAND_NAME = "fireeye-helix" INTEGRATION_CONTEXT_NAME = "FireEyeHelix" DEFAULT_PAGE_SIZE = 30 ALERTS_TRANS = { "id": "ID", "alert_type.id": "AlertTypeID", "alert_type.name": "Name", "assigned_to.id": "AssigneeID", "assigned_to.name": "AssigneeName", "created_by.id": "CreatorID", "created_by.name": "CreatorName", "updated_by.id": "UpdaterID", "updated_by.name": "UpdaterName", "created_at": "CreatedTime", "updated_at": "ModifiedTime", "alert_type_details.detail.processpath": "ProcessPath", "alert_type_details.detail.process": "Process", "alert_type_details.detail.pprocess": "ParentProcess", "alert_type_details.detail.confidence": "Confidence", "alert_type_details.detail.sha1": "SHA1", "alert_type_details.detail.md5": "MD5", "alert_type_details.detail.hostname": "Hostname", "alert_type_details.detail.pid": "PID", "alert_type_details.detail.byte": "Size", "alert_type_details.detail.virus": "Virus", "alert_type_details.detail.result": "Result", "alert_type_details.detail.malwaretype": "MalwareType", "alert_type_details.detail.filename": "FileName", "alert_type_details.detail.regpath": "RegPath", "alert_type_details.detail.eventtime": "EventTime", "alert_type_details.detail.iocnames": "IOCNames", "alert_type_details.detail.srcipv4": "SourceIPv4", "alert_type_details.detail.srcipv6": "SourceIPv6", "alert_type_details.detail.dstipv4": "DestinationIPv4", "alert_type_details.detail.dstipv6": "DestinationIPv6", "alert_type_details.detail.dstport": "DestinationPort", "alert_type_details.detail.uri": "URI", "alert_type_details.detail.domain": "Domain", "alert_type_details.detail.useragent": "UserAgent", "alert_type_details.detail.httpmethod": "HttpMethod", "events_count": "EventsCount", "notes_count": "NotesCount", "closed_state": "ClosedState", "closed_reason": "ClosedReason", "description": "Description", "first_event_at": "FirstEventTime", "last_event_at": "LastEventTime", "external_ips": "ExternalIP", "internal_ips": "InternalIP", "message": "Message", "products": "Products", "risk": "Risk", "severity": "Severity", "state": "State", "tags": "Tags", "type": "Type", } ARCHIVE_SEARCH_TRANS = { "id": "ID", "percentComplete": "PercentComplete", "query": "Query", "state": "State", } CASES_TRANS = { "id": "ID", "name": "Name", "alerts_count": "AlertsCount", "assigned_to.id": "AssigneeID", "assigned_to.name": "AssigneeName", "created_by.id": "CreatorID", "created_by.name": "CreatorName", "updated_by.id": "UpdaterID", "updated_by.name": "UpdaterName", "created_at": "CreatedTime", "updated_at": "ModifiedTime", "description": "Description", "events_count": "EventsCount", "info_links": "InfoLinks", "notes_count": "NotesCount", "priority": "Priority", "priority_order": "PriorityOrder", "severity": "Severity", "state": "State", "status": "Status", "tags": "Tags", "total_days_unresolved": "TotalDaysUnresolved", } ENDPOINTS_TRANS = { "id": "ID", "customer_id": "CustomerID", "device_id": "DeviceID", "domain": "Domain", "hostname": "Hostname", "mac_address": "MACAddress", "operating_system": "OS", "primary_ip_address": "IP", "updated_at": "UpdatedTime", "containment_state": "ContainmentState", } EVENTS_TRANS = { "eventid": "ID", "eventtype": "Type", "result": "Result", "matched_at": "MatchedAt", "confidence": "Confidence", "status": "Status", "eventtime": "EventTime", "detect_ruleids": "DetectedRuleID", "pid": "PID", "process": "Process", "processpath": "ProcessPath", "filename": "FileName", "filepath": "FilePath", "devicename": "DeviceName", "bytes": "Size", "virus": "Virus", "malwaretype": "MalwareType", "createdtime": "CreatedTime", "class": "Class", "md5": "MD5", "sha1": "SHA1", "protocol": "Protocol", "srcipv4": "SourceIPv4", "srcipv6": "SourceIPv6", "srcport": "SourcePort", "srclongitude": "SourceLongitude", "dstipv4": "DestinationIPv4", "srclatitude": "SourceLatitude", "dstipv6": "DestinationIPv6", "dstport": "DestinationPort", "reported_at": "ReportTime", "is_false_positive": "FalsePositive", "domain": "Domain", "mailfrom": "From", "srcdomain": "SourceDomain", "srcisp": "SourceISP", "dstisp": "DestinationISP", "rcptto": "RcpTo", "to": "To", "inreplyto": "InReplyTo", "attachment": "Attachment", } LISTS_TRANS = { "id": "ID", "short_name": "ShortName", "name": "Name", "type": "Type", "description": "Description", "types": "ContentTypes", "created_by.id": "CreatorID", "created_by.name": "CreatorName", "updated_by.id": "UpdatedByID", "updated_by.name": "UpdatedByName", "created_at": "CreatedTime", "updated_at": "UpdatedTime", "is_internal": "Internal", "is_protected": "Protected", "is_active": "Active", } LIST_ITEM_TRANS = {"id": "ID", "value": "Value", "type": "Type", "risk": "Risk", "notes": "Notes", "list": "ListID"} NOTES_TRANS = { "id": "ID", "created_at": "CreatedTime", "updated_at": "UpdatedTime", "note": "Message", "created_by.id": "CreatorID", "created_by.name": "CreatorName", } RULES_TRANS = { "id": "ID", "_rulePack": "RulePack", "description": "Description", "internal": "Internal", "deleted": "Deleted", "enabled": "Enabled", "supported": "Supported", "_createdBy.id": "CreatorID", "_createdBy.name": "CreatorName", "_updatedBy.id": "UpdatedByID", "_updatedBy.name": "UpdatedByName", "risk": "Risk", "confidence": "Confidence", "severity": "Severity", "tags": "Tags", "type": "Type", } class Client(BaseClient): def test_module(self): """Performs basic GET request to check if the API is reachable and authentication is successful. Returns: Response content """ suffix = "/api/v3/alerts" self._http_request("GET", suffix, params={"limit": 1}) def list_alerts(self, limit: int = None, offset: int = None, created_at__gte: str = None) -> dict: """Returns all alerts by sending a GET request. Args: limit: The maximum number of alerts to return. offset: The initial index from which to return the results. created_at__gte: Date time string. Will fetch alerts with a create time greater or equal to this value Returns: Response from API. """ suffix = "/api/v3/alerts" # Dictionary of params for the request params = assign_params(limit=limit, offset=offset, created_at__gte=created_at__gte) # Send a request using our http_request wrapper return self._http_request("GET", suffix, params=params) def get_alert_by_id(self, _id: Any | None) -> dict: """Return a single alert by sending a GET request. Args: _id: ID of the alert to get. Returns: Response from API. """ suffix = f"/api/v3/alerts/{_id}" return self._http_request("GET", suffix) def search(self, query: str = None): """Searches for alerts based on query Args: query: Search query written in mql Returns: Response from API. """ suffix = "/api/v1/search" params = assign_params(query=query) return self._http_request("GET", suffix, params=params, timeout=DEFAULT_PAGE_SIZE) def archive_search_alert(self, query: str = None): """Searches for alerts based on query Args: query: Search query written in mql Returns: Response from API. """ suffix = "/api/v1/search/archive" params = assign_params(query=query) return self._http_request("GET", suffix, params=params) def archive_search(self, query: str = None) -> dict: """Searches for events using archive search Args: query: Search query written in mql Returns: Response from API. """ suffix = "/api/v1/search/archive" params = assign_params(query=query) return self._http_request("GET", suffix, params=params) def get_archive_search(self, search_id: int = None) -> dict: """Gets archive search Args: search_id: Search id Returns: Response from API. """ suffix = f"/api/v1/search/archive/{search_id}" return self._http_request("GET", suffix) def get_archive_search_results(self, search_id: int = None): """Searches for alerts based on query Args: search_id: Search ID to get Returns: Response from API. """ suffix = f"/api/v1/search/archive/{search_id}/results" return self._http_request("GET", suffix, timeout=DEFAULT_PAGE_SIZE) def update_alert_by_id(self, body: dict) -> dict: """Updates a single alert by sending a POST request. Args: body: Request body to update dictionary. Returns: Response from API. """ suffix = "/api/v3/alerts" return self._http_request("POST", suffix, json_data=body) def get_alert_notes(self, alert_id): """Get all notes related to alert by sending a GET request. Args: alert_id: Alert ID. Returns: Response from API. """ suffix = f"/api/v3/alerts/{alert_id}/notes" return self._http_request("GET", suffix) def create_alert_note(self, alert_id: Any | None, note: Any | None) -> dict: """Creates a single note for an alert by sending a POST request. Args: alert_id: Alert ID to create note for. note: Note to add to alert. Returns: Response from API. """ suffix = f"/api/v3/alerts/{alert_id}/notes" body = assign_params(note=note) return self._http_request("POST", suffix, json_data=body) def delete_alert_note(self, alert_id: Any | None, note_id: Any | None) -> dict: """Deletes a single note for an alert by sending a DELETE request. Args: alert_id: Alert ID to delete note for. note_id: Note ID. Returns: Response from API. """ suffix = f"/api/v3/alerts/{alert_id}/notes/{note_id}" return self._http_request("DELETE", suffix, resp_type="") def get_events_by_alert(self, alert_id: Any | None) -> dict: """Fetches events for an alert by sending a GET request. Args: alert_id: Alert ID to get events for. Returns: Response from API. """ suffix = f"/api/v3/alerts/{alert_id}/events" return self._http_request("GET", suffix) def get_endpoints_by_alert(self, alert_id: Any | None, offset: Any | None = None) -> dict: """Fetches endpoints for an alert by sending a GET request. Args: alert_id: Alert ID to get endpoints for. offset: Offset to the result Returns: Response from API. """ suffix = f"/api/v3/alerts/{alert_id}/endpoints" params = assign_params(offset=offset) return self._http_request("GET", suffix, params=params) def get_cases_by_alert( self, alert_id: Any | None, limit: Any | None = None, offset: Any | None = None, order_by: Any | None = None ) -> dict: """Fetches cases for an alert by sending a GET request. Args: alert_id: Alert ID to get endpoints for. limit: Number of results to return per page. offset: The initial index from which to return the results. order_by: Which field to use when ordering the results. Returns: Response from API. """ suffix = f"/api/v3/alerts/{alert_id}/cases" body = assign_params(limit=limit, offset=offset, order_by=order_by) body = body if body else None return self._http_request("GET", suffix, json_data=body) def get_event_by_id(self, event_id: Any | None) -> dict: """Fetches an event by id via a GET request. Args: event_id: ID of an event. Returns: Response from API. """ suffix = f"/api/v1/events/{event_id}" return self._http_request("GET", suffix) def get_lists( self, limit: int = None, offset: int = None, created_at: str = None, description: str = None, is_active: bool = None, is_internal: bool = None, is_protected: bool = None, name: str = None, short_name: str = None, type: str = None, updated_at: str = None, usage: str = None, order_by: str = None, ) -> dict: """Fetches lists by a GET request Args: limit: Number of results to return per page. offset: The initial index from which to return the results. created_at: Creation date of the list. description: Description of the list. is_active: Set to true if the list is active. is_internal: Set to true if the list is internal. is_protected: Set to true if list is protected. name: Name of the list. short_name: Short name of the list. type: Type of the list. updated_at: The time the list was last updated at. usage: Multiple values may be separated by commas. order_by: Which field to use when ordering the results. Returns: Response from API. """ suffix = "/api/v3/lists" params = assign_params( limit=limit, offset=offset, created_at=created_at, description=description, is_active=is_active, is_internal=is_internal, is_protected=is_protected, name=name, short_name=short_name, type=type, updated_at=updated_at, usage=usage, order_by=order_by, ) return self._http_request("GET", suffix, params=params) def get_list_by_id(self, list_id: Any | None) -> dict: """Get a list by id via a GET request Args: list_id: ID of the list Returns: Response from API. """ suffix = f"/api/v3/lists/{list_id}" return self._http_request("GET", suffix) def create_list( self, name: str | None, usage: str = None, short_name: str = None, is_internal: bool = None, is_active: bool = None, is_protected: bool = None, is_hidden: bool = None, type: str = None, description: str = None, ) -> dict: """Creates a list using a POST request Args: name: Name of the list. short_name: Short name of the list. is_internal: Boolean flag for is internal. is_active: Boolean flag for is active. is_protected: Boolean flag for is protected. is_hidden: Boolean flag for is hiddden. usage: Usage of the list. type: Type of the list. description: Description of the list. Returns: Response from API. """ suffix = "/api/v3/lists" body = assign_params( name=name, short_name=short_name, is_internal=is_internal, is_active=is_active, is_protected=is_protected, is_hidden=is_hidden, type=type, description=description, ) body["usage"] = argToList(usage) return self._http_request("POST", suffix, json_data=body) def update_list( self, list_id: int, name: str = None, usage: str = None, short_name: str = None, is_internal: bool = None, is_active: bool = None, is_protected: bool = None, is_hidden: bool = None, type: str = None, description: str = None, ) -> dict: """Creates a list using a POST request Args: list_id: ID of the list. name: Name of the list. short_name: Short name of the list. is_internal: Boolean flag for is internal. is_active: Boolean flag for is active. is_protected: Boolean flag for is protected. is_hidden: Boolean flag for is hiddden. usage: Usage of the list. type: Type of the list. description: Description of the list. Returns: Response from API. """ suffix = f"/api/v3/lists/{list_id}" body = assign_params( name=name, short_name=short_name, is_internal=is_internal != "false" if is_internal else is_internal, is_active=is_active != "false" if is_active else is_active, is_protected=is_protected != "false" if is_protected else is_protected, is_hidden=is_hidden != "false" if is_hidden else is_hidden, type=type, description=description, ) body["usage"] = argToList(usage) return self._http_request("PATCH", suffix, json_data=body) def delete_list(self, list_id: Any | None) -> dict: """Deletes a list using DELETE request Args: list_id: ID of a list. Returns: Response from API """ suffix = f"/api/v3/lists/{list_id}" return self._http_request("DELETE", suffix, resp_type="content") def list_sensors(self, limit: int = None, offset: int = None, hostname: str = None, status: str = None) -> dict: """Fetches sensors using GET request Args: limit: Number of results to return per page. offset: The initial index from which to return the results. hostname: Host name of the sensor. status: Status of the sensor. Returns: Response from API """ suffix = "/api/v3/sensors" params = assign_params(limit=limit, offset=offset, hostname=hostname, status=status) return self._http_request("GET", suffix, params=params) def list_rules(self, limit: int = None, offset: int = None, sort: str = None) -> dict: """Fetches rules using GET request Args: limit: Number of results to return per page. offset: The initial index from which to return the results. sort: Comma-separated list of field names to sort the results by. Returns: Response from API """ suffix = "/api/v1/rules" params = assign_params(limit=limit, offset=offset, sort=sort) return self._http_request("GET", suffix, params=params) def edit_rule(self, rule_id: str, enabled: bool = None) -> dict: """Edit a single rule using PATCH request Args: rule_id: ID of the rule. enabled: Is the rule enabled. Returns: Response from API """ suffix = f"/api/v1/rules/{rule_id}" body = assign_params(enabled=enabled) return self._http_request("PATCH", suffix, json_data=body) def add_list_item(self, list_id: int | None, type: str, value: str, risk: str = None, notes: str = None) -> dict: """Adds a single item list to a list Args: list_id: List id. type: Type of list item. value: Value of list item. risk: Risk of list item. notes: Notes for list item. Returns: Respone from API """ suffix = f"/api/v3/lists/{list_id}/items" body = assign_params(type=type, value=value, risk=risk, notes=notes) return self._http_request("POST", suffix, json_data=body) def update_list_item( self, list_id: int, item_id: int, type: str = None, value: str = None, risk: str = None, notes: str = None ) -> dict: """Updates a single item list Args: list_id: List id. item_id: Item id. type: Type of list item. value: Value of list item. risk: Risk of list item. notes: Notes for list item. Returns: Respone from API """ suffix = f"/api/v3/lists/{list_id}/items/{item_id}" body = assign_params(type=type, value=value, risk=risk, notes=notes) return self._http_request("PATCH", suffix, json_data=body) def get_list_items(self, list_id: Any | None, offset: Any | None) -> dict: """Gets items of a list Args: list_id: List ID. offset: Offset in database. Returns: Response from API """ suffix = f"/api/v3/lists/{list_id}/items" params = assign_params(offset=offset) return self._http_request("GET", suffix, params=params) def remove_list_item(self, list_id: Any | None, item_id: Any | None) -> dict: suffix = f"/api/v3/lists/{list_id}/items/{item_id}" return self._http_request("DELETE", suffix, resp_type="content") """ HELPER FUNCTIONS """ def create_context_result(src: dict | list, trans_dict: dict) -> dict | list: """Builds a dictionary according to a transformation map Args: src (dict): original dictionary to build from trans_dict (dict): dict in the format { 'OldKey': 'NewKey', ...} Returns: src copy with changed keys """ if isinstance(src, list): return [create_context_result(x, trans_dict) for x in src] res: dict[str, Any] = {} for key, val in trans_dict.items(): if isinstance(val, dict): # handle nested list sub_res = res item_val = [create_context_result(item, val) for item in (demisto.get(src, key) or [])] key = underscoreToCamelCase(key) for sub_key in key.split(".")[:-1]: if sub_key not in sub_res: sub_res[sub_key] = {} sub_res = sub_res[sub_key] sub_res[key.split(".")[-1]] = item_val elif "." in val: # handle nested vals update_nested_value(res, val, to_val=demisto.get(src, key)) else: res[val] = demisto.get(src, key) return res def update_nested_value(src_dict: dict[str, Any], to_key: str, to_val: Any) -> None: """ Updates nested value according to transformation dict structure where 'a.b' key will create {'a': {'b': val}} Args: src_dict (dict): The original dict to_key (str): Key to transform to (expected to contain '.' to mark nested) to_val (any): The value that'll be put under the nested key """ sub_res = src_dict to_key_lst = to_key.split(".") for sub_to_key in to_key_lst[:-1]: if sub_to_key not in sub_res: sub_res[sub_to_key] = {} sub_res = sub_res[sub_to_key] sub_res[to_key_lst[-1]] = to_val def alert_severity_to_dbot_score(severity_str): """Converts an severity string to DBot score representation alert severity. Can be one of: Low -> 1 Medium -> 2 High -> 3 Args: severity_str: String representation of severity. Returns: Dbot representation of severity """ severity_str = severity_str.lower() if severity_str == "low": return 1 if severity_str == "medium": return 2 elif severity_str == "high": return 3 return 0 def build_mql_query( query: str, start: str = None, end: str = None, page_size=None, limit=None, offset=None, groupby=None, sort_by=None, sort_order=None, ) -> str: """Builds MQL query from given arguments Args: query: Query to execute. This is the search clause in an MQL. start: Start time of the event in date format yyyy-mm-dd or yyyy-mm. end: End time of the event in date format yyyy-mm-dd or yyyy-mm. page_size: Max amount of results to return. limit: Number of events to search. offset: Offset of the result. groupby: Returns the unique values for the specified field and groups them together. sort_by: Sorts results by this field. sort_order: Controls the order of the results sorted. Returns: MQL query """ # Filter section if start: query += f' start="{start}"' if end: query += f' end="{end}"' if page_size or offset or limit: query += " {" if page_size: query += f" page_size={page_size}" if offset: query += f" offset={offset}" if limit: query += f" limit={limit}" query += "}" # Transform section if groupby: query += f"| groupby [{groupby}]" if sort_by: sort_order = ">" if sort_order != "asc" else "<" query += f"| sort {sort_order} {sort_by}" return query def build_search_groupby_result(aggregations: dict, separator: str) -> list: """Builds groupby result from search aggregations Args: aggregations: Group object separator: Separator used in query and result Returns: Groupby result """ res = [] for key, aggregation in aggregations.items(): if key.startswith("groupby"): groupby_fields = demisto.get(aggregation, "meta.field") or demisto.get(aggregation, "meta.fields") if groupby_fields: if isinstance(groupby_fields, str): groupby_fields = [groupby_fields] for bucket in aggregation.get("buckets", []): bucket_vals = bucket.get("key", "").split(separator) group_set = {groupby_field: bucket_vals[idx] for idx, groupby_field in enumerate(groupby_fields)} group_set["DocCount"] = bucket.get("doc_count") res.append(group_set) return res def build_search_result(raw_response: dict, search_id: str | int = "", headers: list = None): """Builds search result from search raw_response Args: raw_response: Search raw response search_id: Search ID (relevant for archive search) headers: Headers to show in hr table Returns: Search result """ results = raw_response.get("results") context = {"MQL": raw_response.get("mql")} if search_id: dt_query = "val.ID && val.ID === obj.ID" context["ID"] = search_id else: dt_query = "val.ID && val.ID === obj.ID" if search_id else "val.MQL && val.MQL === obj.MQL" if results: # Search results hits = demisto.get(results, "hits.hits") if hits: context["Result"] = [] for hit in hits: context["Result"].append(create_context_result(hit.get("_source"), EVENTS_TRANS)) # type: ignore # Human readable value is ok for both no result found and result found cases hr = tableToMarkdown( f'{INTEGRATION_NAME} - Search result for {context["MQL"]}', context.get("Result"), headers, headerTransform=pascalToSpace, removeNull=True, ) # Group by results aggregations = results.get("aggregations") if aggregations: separator = demisto.get(raw_response, "options.groupby.separator") or "|%$,$%|" context["GroupBy"] = build_search_groupby_result(aggregations, separator) if context["GroupBy"]: group_by_keys = list(context["GroupBy"][0].keys()) # type: ignore # move DocCount to tail group_by_keys.remove("DocCount") group_by_keys.append("DocCount") hr += tableToMarkdown("Group By", context["GroupBy"], headers=group_by_keys) return hr, {f"{INTEGRATION_CONTEXT_NAME}Search({dt_query})": context}, raw_response else: # API should not return an empty result matching this case, this is a fail safe return f"{INTEGRATION_NAME} - Search did not find any result.", {}, {} def build_title_with_page_numbers(title: str, count: int, limit: int, offset: int) -> str: """Tries to build a title with page numbers from raw response and given title Args: title: Title without page numbers count: Total number of entries limit: Max amount of entries returned offset: Returns: """ try: tot_pages = math.ceil(count / limit) page = math.floor((offset / count) * tot_pages) + 1 # In case offset > count if page > tot_pages: page = tot_pages return f"{title}\n### Page {page}/{tot_pages}" except (TypeError, ValueError, ZeroDivisionError): return title def build_single_list_result(raw_response): """Builds a list result from API response Args: raw_response: API response to alert call Returns: List result """ list_id = raw_response.get("id") title = f"{INTEGRATION_NAME} - List {list_id}:" context_entry = create_context_result(raw_response, LISTS_TRANS) context = {f"{INTEGRATION_CONTEXT_NAME}.List(val.ID && val.ID === obj.ID)": context_entry} # Creating human readable for War room human_readable = tableToMarkdown(title, context_entry, headerTransform=pascalToSpace) # Return data to Demisto return human_readable, context, raw_response """ COMMANDS """ def test_module( client: Client, test_fetch: bool = False, fetch_time: str | None = None, last_run: dict = None, *_ ) -> tuple[str, dict, dict]: """Performs a basic GET request to check if the API is reachable and authentication is successful. Args: client: Client object with request test_fetch: If set to true will test fetch_incidents fetch_time: If fetch is set, will pass to fetch_incidents to test last_run: Last fetch object. args: Usually demisto.args() Returns: 'ok' if test successful. Raises: DemistoException: If test failed. """ client.test_module() if test_fetch: fetch_incidents(client, fetch_time, last_run) # type: ignore return "ok", {}, {} def fetch_incidents(client: Client, fetch_time: str | None, last_run: dict) -> tuple[list, dict]: """Uses to fetch incidents into Demisto Documentation: https://github.com/demisto/content/tree/master/docs/fetching_incidents Args: client: Client object with request fetch_time: From when to fetch if first time, e.g. `3 days` last_run: Last fetch object. Returns: incidents, new last_run """ timestamp_format = "%Y-%m-%dT%H:%M:%S.%fZ" # Get incidents from API if not last_run: # if first time running new_last_run = {"time": parse_date_range(fetch_time, date_format=timestamp_format)[0]} else: new_last_run = last_run incidents = [] raw_response = client.list_alerts(created_at__gte=new_last_run.get("time")) alerts = raw_response.get("results") if alerts: last_incident_id = last_run.get("id", 0) # Creates incident entry incidents = [ { "name": f"{INTEGRATION_NAME}: {alert.get('id')}", "occurred": alert.get("created_at"), "severity": alert_severity_to_dbot_score(alert.get("severity")), "rawJSON": json.dumps(alert), } for alert in alerts if alert.get("id") > last_incident_id ] # New incidents fetched if incidents: last_incident_timestamp = incidents[-1].get("occurred") last_incident_id = alerts[-1].get("id") new_last_run = {"time": last_incident_timestamp, "id": last_incident_id} # Return results return incidents, new_last_run def list_alerts_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Lists all alerts and return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ limit = int(args.get("page_size") or DEFAULT_PAGE_SIZE) headers = argToList(args.get("headers")) # api response for limit=0 is equivalent to limit=30 if limit == 0: limit = DEFAULT_PAGE_SIZE offset = int(args.get("offset") or 0) raw_response = client.list_alerts(limit=limit, offset=offset) alerts = raw_response.get("results") if alerts: count = demisto.get(raw_response, "meta.count") title = f"{INTEGRATION_NAME} - List alerts:" try: count = int(count) title = build_title_with_page_numbers(title, count, limit, offset) except (TypeError, ValueError): # don't change title if count ins't an int pass context_entry = create_context_result(alerts, ALERTS_TRANS) context = { f"{INTEGRATION_CONTEXT_NAME}.Alert(val.ID && val.ID === obj.ID)": context_entry, f"{INTEGRATION_CONTEXT_NAME}.Alert(val.Count).Count": count, } if not headers: headers = ["ID", "Name", "Description", "State", "Severity"] human_readable = tableToMarkdown(title, context_entry, headers) return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any alerts.", {}, {} def get_alert_by_id_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Get alert by id and return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ _id = args.get("id") headers = argToList(args.get("headers")) raw_response = client.get_alert_by_id(_id=_id) if raw_response: title = f"{INTEGRATION_NAME} - Alert {_id}:" context_entry = create_context_result(raw_response, ALERTS_TRANS) context = {f"{INTEGRATION_CONTEXT_NAME}.Alert(val.ID && val.ID === obj.ID)": context_entry} human_readable = tableToMarkdown(title, context_entry, headers=headers, removeNull=True) return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any alerts.", {}, {} def get_alert_notes_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Get all notes related to alert Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ alert_id = args.get("alert_id") raw_response = client.get_alert_notes(alert_id=alert_id) raw_notes = raw_response.get("results") if raw_notes: title = f"{INTEGRATION_NAME} - Notes for Alert {alert_id}:" context_entry = create_context_result(raw_notes, NOTES_TRANS) if isinstance(context_entry, dict): context_entry["AlertID"] = alert_id else: for note in context_entry: note["AlertID"] = alert_id count = demisto.get(raw_response, "meta.count") context = { f"{INTEGRATION_CONTEXT_NAME}.Note(val.ID && val.ID === obj.ID)": context_entry, f"{INTEGRATION_CONTEXT_NAME}.Note(val.Count && val.AlertID === {alert_id}).Count": count, } # Creating human readable for War room human_readable = tableToMarkdown( title, context_entry, ["ID", "CreatorName", "Message", "CreatedTime"], headerTransform=pascalToSpace ) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - No notes were found for alert {alert_id}.", {}, {} def create_alert_note_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Create a note for an alert Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ alert_id = args.get("alert_id") note = args.get("note") raw_response = client.create_alert_note(alert_id=alert_id, note=note) if raw_response: title = f"{INTEGRATION_NAME} - Created Note for Alert {alert_id}:" context_entry = create_context_result(raw_response, NOTES_TRANS) if isinstance(context_entry, dict): context_entry["AlertID"] = alert_id context = {f"{INTEGRATION_CONTEXT_NAME}.Note(val.ID && val.ID === obj.ID)": context_entry} # Creating human readable for War room human_readable = tableToMarkdown( title, context_entry, ["ID", "CreatorName", "Message", "CreatedTime"], headerTransform=pascalToSpace ) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not create a note.", {}, {} def delete_alert_note_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Delete a note for an alert Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ alert_id = args.get("alert_id") note_id = args.get("note_id") client.delete_alert_note(alert_id=alert_id, note_id=note_id) return f"{INTEGRATION_NAME} - Deleted note {note_id} for Alert {alert_id} successfully.", {}, {} def get_events_by_alert_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Get events for a specific alert Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ alert_id = args.get("alert_id") headers = argToList(args.get("headers")) raw_response = client.get_events_by_alert(alert_id=alert_id) events = raw_response.get("results") if events: title = f"{INTEGRATION_NAME} - Events for alert {alert_id}:" context_entry = create_context_result(events, EVENTS_TRANS) count = demisto.get(raw_response, "meta.count") context = { f"{INTEGRATION_CONTEXT_NAME}.Event(val.ID && val.ID === obj.ID)": context_entry, f"{INTEGRATION_CONTEXT_NAME}.Event(val.Count).Count": count, } # Creating human readable for War room human_readable = tableToMarkdown(title, context_entry, headers, headerTransform=pascalToSpace, removeNull=True) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any events.", {}, {} def get_endpoints_by_alert_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Fetch endpoints of a specific alert Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ alert_id = args.get("alert_id") raw_response = client.get_endpoints_by_alert(alert_id=alert_id, offset=args.get("offset")) endpoints = demisto.get(raw_response, "results.endpoints") if endpoints: title = f"{INTEGRATION_NAME} - Endpoints for alert {alert_id}:" context_entry = create_context_result(endpoints, ENDPOINTS_TRANS) count = demisto.get(raw_response, "meta.count") context = { f"{INTEGRATION_CONTEXT_NAME}.Endpoint(val.ID && val.ID === obj.ID)": context_entry, f"{INTEGRATION_CONTEXT_NAME}.Endpoint(val.Count).Count": count, } # Creating human readable for War room human_readable = tableToMarkdown( title, context_entry, ["ID", "DeviceID", "Hostname", "IP", "MACAddress", "UpdatedTime"], headerTransform=pascalToSpace ) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any endpoints.", {}, {} def get_cases_by_alert_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Fetch cases of a specific alert Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ alert_id = args.get("alert_id") raw_response = client.get_cases_by_alert( alert_id=alert_id, limit=args.get("page_size"), offset=args.get("offset"), order_by=args.get("order_by") ) cases = raw_response.get("results") if cases: title = f"{INTEGRATION_NAME} - Cases for alert {alert_id}:" context_entry = create_context_result(cases, CASES_TRANS) context = {f"{INTEGRATION_CONTEXT_NAME}.Case(val.ID && val.ID === obj.ID)": context_entry} # Creating human readable for War room human_readable = tableToMarkdown( title, context_entry, ["ID", "Name", "AssigneeName", "Priority", "Severity", "State", "Status", "ModifiedTime"], removeNull=True, ) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any cases.", {}, {} def get_lists_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Get lists return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ is_active = args.get("is_active") is_internal = args.get("is_internal") is_protected = args.get("is_protected") raw_response = client.get_lists( limit=args.get("page_size"), offset=args.get("offset"), created_at=args.get("created_at"), description=args.get("description"), is_active=is_active and is_active != "false", is_internal=is_internal and is_internal != "false", is_protected=is_protected and is_protected != "false", name=args.get("name"), short_name=args.get("short_name"), type=args.get("type"), updated_at=args.get("updated_at"), usage=args.get("usage"), order_by=args.get("order_by"), ) lists = raw_response.get("results") if lists: title = f"{INTEGRATION_NAME} - Lists:" context_entry = create_context_result(lists, LISTS_TRANS) count = demisto.get(raw_response, "meta.count") context = { f"{INTEGRATION_CONTEXT_NAME}.List(val.ID && val.ID === obj.ID)": context_entry, f"{INTEGRATION_CONTEXT_NAME}.List(val.Count).Count": count, } # Creating human readable for War room human_readable = tableToMarkdown( title, context_entry, ["ID", "Name", "ContentTypes", "UpdatedTime"], headerTransform=pascalToSpace ) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any lists.", {}, {} def get_list_by_id_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Get a list by ID return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ list_id = args.get("id") raw_response = client.get_list_by_id(list_id) if raw_response: return build_single_list_result(raw_response) else: return f"{INTEGRATION_NAME} - Could not find the list.", {}, raw_response def create_list_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Create a list. return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ is_internal = args.get("is_internal") is_active = args.get("is_active") is_protected = args.get("is_protected") is_hidden = args.get("is_hidden") raw_response = client.create_list( name=args.get("name"), short_name=args.get("short_name"), is_internal=is_internal != "false" if is_internal else is_internal, is_active=is_active != "false" if is_active else is_active, is_protected=is_protected != "false" if is_protected else is_protected, is_hidden=is_hidden != "false" if is_hidden else is_hidden, type=args.get("type"), description=args.get("description"), ) if raw_response: return build_single_list_result(raw_response) else: return f"{INTEGRATION_NAME} - Created list successfully.", {}, raw_response def update_list_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Update a list. return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ is_internal = args.get("is_internal") is_active = args.get("is_active") is_protected = args.get("is_protected") is_hidden = args.get("is_hidden") raw_response = client.update_list( list_id=int(args.get("list_id")), # type: ignore name=args.get("name"), short_name=args.get("short_name"), is_internal=is_internal != "false" if is_internal else is_internal, is_active=is_active != "false" if is_active else is_active, is_protected=is_protected != "false" if is_protected else is_protected, is_hidden=is_hidden != "false" if is_hidden else is_hidden, type=args.get("type"), description=args.get("description"), ) if raw_response: return build_single_list_result(raw_response) else: return f"{INTEGRATION_NAME} - Updated list successfully.", {}, raw_response def delete_list_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Update a list. return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ list_id = args.get("list_id") raw_response = client.delete_list(list_id) return f"{INTEGRATION_NAME} - Deleted list successfully.", {}, raw_response def add_list_item_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Adds a list item. return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ list_id = args.get("list_id") raw_response = client.add_list_item( list_id=list_id, type=str(args.get("type")), value=str(args.get("value")), risk=args.get("risk"), notes=args.get("notes") ) if raw_response: item_id = raw_response.get("id") title = f"{INTEGRATION_NAME} - List item {item_id} was added successfully to {list_id}" context_entry = create_context_result(raw_response, LIST_ITEM_TRANS) context = {f"{INTEGRATION_CONTEXT_NAME}List(val.ID && val.ID === {list_id}).Item": context_entry} human_readable = tableToMarkdown(title, context_entry) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not create list item.", {}, raw_response def update_list_item_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Updates a list item. return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ list_id = int(args.get("list_id")) # type: ignore item_id = int(args.get("item_id")) # type: ignore raw_response = client.update_list_item( list_id=list_id, item_id=item_id, type=args.get("type"), value=args.get("value"), risk=args.get("risk"), notes=args.get("notes"), ) if raw_response: title = f"{INTEGRATION_NAME} - List item {item_id} from list {list_id} was updated successfully" context_entry = create_context_result(raw_response, LIST_ITEM_TRANS) context = {f"{INTEGRATION_CONTEXT_NAME}List(val.ID && val.ID === {list_id}).Item(val.ID === obj.ID)": context_entry} human_readable = tableToMarkdown(title, context_entry) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not update list item.", {}, raw_response def remove_list_item_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Updates a list item. return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ list_id = args.get("list_id") item_id = args.get("item_id") raw_response = client.remove_list_item(list_id=list_id, item_id=item_id) return f"{INTEGRATION_NAME} - Removed item {item_id} from list {list_id} successfully", {}, raw_response def get_list_items_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Fetches list items Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ list_id = args.get("list_id") raw_response = client.get_list_items(list_id, args.get("offset")) results = raw_response.get("results") if results: title = f"{INTEGRATION_NAME} - List items for list {list_id}" context_entry = create_context_result(results, LIST_ITEM_TRANS) count = demisto.get(raw_response, "meta.count") context = { f"{INTEGRATION_CONTEXT_NAME}List(val.ID && val.ID === {list_id}).Item(val.ID === obj.ID)": context_entry, f"{INTEGRATION_CONTEXT_NAME}List(val.ID && val.ID === {list_id}).Count(val.Count)": count, } human_readable = tableToMarkdown(title, context_entry) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - No items were found for list {list_id}.", {}, raw_response def list_sensors_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Lists all sensors and return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ raw_response = client.list_sensors( limit=int(args.get("page_size") or 0), offset=int(args.get("offset") or 0), hostname=args.get("hostname"), status=args.get("status"), ) sensors = raw_response.get("results") if sensors: title = f"{INTEGRATION_NAME} - List sensors:" context = {f"{INTEGRATION_CONTEXT_NAME}.Sensor(val.id && val.ID === obj.id)": sensors} # Creating human readable for War room human_readable = tableToMarkdown(title, sensors) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any sensors.", {}, {} def list_rules_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Lists all rules and return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ limit = int(args.get("page_size") or DEFAULT_PAGE_SIZE) offset = int(args.get("offset") or 0) raw_response = client.list_rules(limit=limit, offset=offset, sort=args.get("sort")) rules = raw_response.get("rules") if rules: count = demisto.get(raw_response, "meta.totalCount") title = f"{INTEGRATION_NAME} - List rules:" try: count = int(count) title = build_title_with_page_numbers(title, count, limit, offset) except (TypeError, ValueError): # don't change title if count ins't an int pass context_entry = create_context_result(rules, RULES_TRANS) context = { f"{INTEGRATION_CONTEXT_NAME}.Rule(val.ID && val.ID === obj.ID)": context_entry, f"{INTEGRATION_CONTEXT_NAME}.Rule(val.Count)": count, } # Creating human readable for War room human_readable = tableToMarkdown( title, context_entry, ["ID", "Type", "Description", "Risk", "Confidence", "Severity", "Enabled"] ) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find any rules.", {}, {} def edit_rule_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Edit a single rule and return outputs in Demisto's format Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ rule_id = str(args.get("rule_id")) enabled = args.get("enabled") raw_response = client.edit_rule(rule_id, enabled != "false" if enabled else None) rules = raw_response.get("rules") if rules: title = f"{INTEGRATION_NAME} - Successfully updated rule {rule_id}:" context_entry = create_context_result(rules, RULES_TRANS) context = {f"{INTEGRATION_CONTEXT_NAME}.Rule(val.ID && val.ID === obj.ID)": context_entry} # Creating human readable for War room human_readable = tableToMarkdown(title, context_entry, ["ID", "Type", "Description", "Risk", "Confidence", "Severity"]) # Return data to Demisto return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Could not find matching rule.", {}, {} def search_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Searches FireEye Helix database using MQL Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ query = build_mql_query( query=args.get("query", ""), start=args.get("start"), end=args.get("end"), page_size=args.get("page_size"), limit=args.get("limit"), offset=args.get("offset"), groupby=args.get("groupby"), sort_by=args.get("sort_by"), sort_order=args.get("sort_order"), ) raw_response = client.search(query) headers = argToList(args.get("headers")) return build_search_result(raw_response, headers=headers) def archive_search_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Searches FireEye Helix database using MQL Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ query = build_mql_query(**args) raw_response = client.archive_search(query) data = raw_response.get("data") if data: title = f"{INTEGRATION_NAME} - Successfully created archive search" context_entry = create_context_result(data, ARCHIVE_SEARCH_TRANS) context = {f"{INTEGRATION_CONTEXT_NAME}Search(val.ID === obj.ID)": context_entry} human_readable = tableToMarkdown(title, context_entry, headerTransform=pascalToSpace) return human_readable, context, raw_response else: return f"{INTEGRATION_NAME} - Failed to create archive search", {}, raw_response def archive_search_status_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Fetches the status of an archive search Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ search_ids = argToList(args.get("search_id")) raw_res_lst = [] context_entry = [] for s_id in search_ids: i_s_id = int(s_id) raw_res = client.get_archive_search(i_s_id) if raw_res: data = raw_res.get("data") if isinstance(data, list): context_entry.append(create_context_result(data[0], ARCHIVE_SEARCH_TRANS)) raw_res_lst.append(raw_res) if raw_res_lst: title = f"{INTEGRATION_NAME} - Search status" human_readable = tableToMarkdown(title, context_entry, headerTransform=pascalToSpace) context = {f"{INTEGRATION_CONTEXT_NAME}Search(val.ID === obj.ID)": context_entry} return human_readable, context, raw_res_lst # type: ignore else: return f"{INTEGRATION_NAME} - Failed to get archive search details", {}, {} def archive_search_results_command(client: Client, args: dict) -> tuple[str, dict, dict]: """Fetches an archive search result Args: client: Client object with request args: Usually demisto.args() Returns: Outputs """ search_id = int(args.get("search_id")) # type: ignore raw_response = client.get_archive_search_results(search_id) return build_search_result(raw_response.get("results"), search_id) """ COMMANDS MANAGER / SWITCH PANEL """ def main(): # pragma: no cover params = demisto.params() base_url = f"{params.get('url', '').rstrip('/')}" if not base_url.endswith("/helix/id"): base_url += "/helix/id" base_url += f"/{params.get('h_id_creds', {}).get('identifier') or params.get('h_id')}" verify_ssl = not params.get("insecure", False) proxy = params.get("proxy", False) headers = { "accept": "application/json", "x-fireeye-api-key": params.get("h_id_creds", {}).get("password") or params.get("token"), } client = Client(base_url=base_url, verify=verify_ssl, proxy=proxy, headers=headers) command = demisto.command() demisto.info(f"Command being called is {command}") # Switch case commands = { f"{INTEGRATION_COMMAND_NAME}-list-alerts": list_alerts_command, f"{INTEGRATION_COMMAND_NAME}-get-alert-by-id": get_alert_by_id_command, f"{INTEGRATION_COMMAND_NAME}-alert-get-notes": get_alert_notes_command, f"{INTEGRATION_COMMAND_NAME}-alert-create-note": create_alert_note_command, f"{INTEGRATION_COMMAND_NAME}-alert-delete-note": delete_alert_note_command, f"{INTEGRATION_COMMAND_NAME}-get-events-by-alert": get_events_by_alert_command, f"{INTEGRATION_COMMAND_NAME}-get-endpoints-by-alert": get_endpoints_by_alert_command, f"{INTEGRATION_COMMAND_NAME}-get-cases-by-alert": get_cases_by_alert_command, f"{INTEGRATION_COMMAND_NAME}-get-lists": get_lists_command, f"{INTEGRATION_COMMAND_NAME}-get-list-by-id": get_list_by_id_command, f"{INTEGRATION_COMMAND_NAME}-create-list": create_list_command, f"{INTEGRATION_COMMAND_NAME}-update-list": update_list_command, f"{INTEGRATION_COMMAND_NAME}-delete-list": delete_list_command, f"{INTEGRATION_COMMAND_NAME}-get-list-items": get_list_items_command, f"{INTEGRATION_COMMAND_NAME}-add-list-item": add_list_item_command, f"{INTEGRATION_COMMAND_NAME}-update-list-item": update_list_item_command, f"{INTEGRATION_COMMAND_NAME}-remove-list-item": remove_list_item_command, f"{INTEGRATION_COMMAND_NAME}-list-sensors": list_sensors_command, f"{INTEGRATION_COMMAND_NAME}-list-rules": list_rules_command, f"{INTEGRATION_COMMAND_NAME}-edit-rule": edit_rule_command, f"{INTEGRATION_COMMAND_NAME}-search": search_command, f"{INTEGRATION_COMMAND_NAME}-archive-search": archive_search_command, f"{INTEGRATION_COMMAND_NAME}-archive-search-get-status": archive_search_status_command, f"{INTEGRATION_COMMAND_NAME}-archive-search-get-results": archive_search_results_command, } try: if command == "test-module": fetch_time = params.get("fetch_time", "3 days") is_fetch = params.get("isFetch", False) last_run = demisto.getLastRun() readable_output, outputs, raw_response = test_module(client, bool(is_fetch), fetch_time, last_run) return_outputs(readable_output, outputs, raw_response) elif command == "fetch-incidents": fetch_time = params.get("fetch_time", "3 days") incidents, last_run = fetch_incidents(client, fetch_time, last_run=demisto.getLastRun()) # type: ignore demisto.incidents(incidents) demisto.setLastRun(last_run) elif command in commands: readable_output, outputs, raw_response = commands[command](client, demisto.args()) # type: ignore return_outputs(readable_output, outputs, raw_response) # Log exceptions except Exception as e: err_msg = str(e) if "[401]" in err_msg: return_error("Encountered an issue accessing the API. Please make sure you entered the right Helix ID and API Token.") elif "requests.exceptions" in err_msg: return_error( "Encountered an error reaching the endpoint, please verify that the server URL parameter" " is correct and that you have access to the server from your host." ) else: return_error(f"Error in {INTEGRATION_NAME} Integration [{e}]", error=e) if __name__ == "builtins": # pragma: no cover main()