FireEyeHX v2
FireEye Endpoint Security is an integrated solution that detects and protects endpoints against known and unknown threats. This integration provides access to information about endpoints, acquisitions, alerts, indicators, and containment. You can extract critical data and effectively operate the security operations automated playbook.
Endpoint · FireEye HX
Details
| ID | FireEyeHX v2 |
|---|---|
| Provider | Trellix |
| Category | Endpoint |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM EDR Cortex Cloud Cloud Runtime Security |
README
FireEye Endpoint Security is an integrated solution that detects what others miss and protects endpoint against known and unknown threats. This integration provides access to information about endpoints, acquisitions, alerts, indicators, and containment. Customers can extract critical data and effectively operate security operations automated playbook
Some changes have been made that might affect your existing content.
If you are upgrading from a previous of this integration, see Breaking Changes.
Configure FireEye Endpoint Security (HX) v2 in Cortex
| Parameter | Required |
|---|---|
| Server URL (e.g. https://192.168.0.1:3000) | True |
| User Name | True |
| Password | True |
| Trust any certificate (not secure) | False |
| Use system proxy settings | False |
| Fetch incidents | False |
| Incident type | False |
| Fetch limit | False |
| First fetch timestamp (<number> <time unit>, e.g., 12 hours, 3 days) | False |
| Incidents Fetch Interval | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
fireeye-hx-get-host-information
Returns information on a host associated with an agent.
Base Command
fireeye-hx-get-host-information
Input
| Argument Name | Description | Required |
|---|---|---|
| agentId | The agent ID. If the agent ID is not specified, the hostName must be specified. | Optional |
| hostName | The host name. If the hostName is not specified, the agent ID must be specified. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Hosts._id | String | The ID of the FireEye HX Agent. |
| FireEyeHX.Hosts.agent_version | String | The version of the agent. |
| FireEyeHX.Hosts.excluded_from_containment | Boolean | Determines whether the host is excluded from containment. |
| FireEyeHX.Hosts.containment_missing_software | Boolean | Whether there is containment missing software. |
| FireEyeHX.Hosts.containment_queued | Boolean | Determines whether the host is queued for containment. |
| FireEyeHX.Hosts.containment_state | String | The containment state of the host. Possible values normal,contain,contain_fail,containing,contained,uncontain,uncontaining,wtfc,wtfu |
| FireEyeHX.Hosts.stats.alerting_conditions | Number | The number of conditions that have alerted for the host. |
| FireEyeHX.Hosts.stats.alerts | Number | The total number of alerts, including exploit-detection alerts. |
| FireEyeHX.Hosts.stats.exploit_blocks | Number | The number of blocked exploits on the host. |
| FireEyeHX.Hosts.stats.malware_alerts | Number | The number of malware alerts associated with the host. |
| FireEyeHX.Hosts.hostname | String | The name of the host. |
| FireEyeHX.Hosts.domain | String | The name of the domain. |
| FireEyeHX.Hosts.timezone | String | The time zone of the host. |
| FireEyeHX.Hosts.primary_ip_address | String | The IP address of the host. |
| FireEyeHX.Hosts.last_poll_timestamp | String | The timestamp of the last system poll preformed on the host. |
| FireEyeHX.Hosts.initial_agent_checkin | String | The timestamp of the initial agent check-in. |
| FireEyeHX.Hosts.last_alert_timestamp | String | The time stamp of the last alert for the host. |
| FireEyeHX.Hosts.last_exploit_block_timestamp | Unknown | The time when the last exploit was blocked on the host. The value is null if no exploits have been blocked. |
| FireEyeHX.Hosts.os.product_name | String | The operating system of the host. |
| FireEyeHX.Hosts.os.bitness | String | The bitness of the operating system. |
| FireEyeHX.Hosts.os.platform | Unknown | The list of operating systems. Valid values are win, osx, and linux. |
| FireEyeHX.Hosts.primary_mac | String | The MAC address of the host. |
Command example
!fireeye-hx-get-host-information hostName=XXX
Context Example
{
"FireEyeHX": {
"Hosts": {
"_id": "YYYXXXYYY",
"agent_version": "31.28.17",
"containment_missing_software": false,
"containment_queued": false,
"containment_state": "normal",
"domain": "WORKGROUP",
"excluded_from_containment": false,
"gmt_offset_seconds": -28800,
"hostname": "XXX",
"initial_agent_checkin": "2021-03-21T13:27:48.058Z",
"last_alert": {
"_id": 365,
"url": "/hx/api/v3/alerts/365"
},
"last_alert_timestamp": "2022-02-23T07:28:34.043+00:00",
"last_audit_timestamp": "2022-02-23T07:28:33.969Z",
"last_exploit_block": null,
"last_exploit_block_timestamp": null,
"last_poll_ip": "xx.xx.xx.xx",
"last_poll_timestamp": "2022-02-23T09:08:31.000Z",
"os": {
"bitness": "64-bit",
"kernel_version": null,
"patch_level": null,
"platform": "win",
"product_name": "Windows 10 Pro"
},
"primary_ip_address": "xx.xx.xx.xx",
"primary_mac": "xx-xx-xx-xx-xx-xx",
"reported_clone": false,
"stats": {
"acqs": 15,
"alerting_conditions": 1,
"alerts": 1,
"exploit_alerts": 0,
"exploit_blocks": 0,
"false_positive_alerts": 0,
"false_positive_alerts_by_source": {},
"generic_alerts": 0,
"malware_alerts": 0,
"malware_cleaned_count": 0,
"malware_false_positive_alerts": 0,
"malware_quarantined_count": 0
},
"sysinfo": {
"url": "/hx/api/v3/hosts/YYYXXXYYY/sysinfo"
},
"timezone": "Pacific Standard Time",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
}
}
}
Human Readable Output
FireEye HX Get Host Information
Host Name Host IP Agent ID Agent Version OS Last Poll Containment State Domain Last Alert XXX xx.xx.xx.xx YYYXXXYYY 31.28.17 win 2022-02-23T09:08:31.000Z normal WORKGROUP _id: 365
url: /hx/api/v3/alerts/365
fireeye-hx-get-all-hosts-information
Returns information on all hosts.
Base Command
fireeye-hx-get-all-hosts-information
Input
| Argument Name | Description | Required |
|---|---|---|
| offset | Specifies which record to start with in the response. Default is 0. | Optional |
| limit | Limits the number of results. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Hosts._id | String | The FireEye HX Agent ID. |
| FireEyeHX.Hosts.agent_version | String | The version of the agent. |
| FireEyeHX.Hosts.excluded_from_containment | Boolean | Determines whether the host is excluded from containment. |
| FireEyeHX.Hosts.containment_missing_software | Boolean | Whether there is containment missing software. |
| FireEyeHX.Hosts.containment_queued | Boolean | Determines whether the host is queued for containment. |
| FireEyeHX.Hosts.containment_state | String | The containment state of the host. Possible values are normal, contain, contain_fail, containing, contained, uncontain, uncontaining, wtfc, wtfu. |
| FireEyeHX.Hosts.stats.alerting_conditions | Number | The number of conditions that have been alerted for the host. |
| FireEyeHX.Hosts.stats.alerts | Number | The total number of alerts, including exploit-detection alerts. |
| FireEyeHX.Hosts.stats.exploit_blocks | Number | The number of blocked exploits on the host. |
| FireEyeHX.Hosts.stats.malware_alerts | Number | The number of malware alerts associated with the host. |
| FireEyeHX.Hosts.hostname | String | The name of the host. |
| FireEyeHX.Hosts.domain | String | The name of the domain. |
| FireEyeHX.Hosts.timezone | String | The time zone of the host. |
| FireEyeHX.Hosts.primary_ip_address | String | The IP address of the host. |
| FireEyeHX.Hosts.last_poll_timestamp | String | The timestamp of the last system poll preformed on the host. |
| FireEyeHX.Hosts.initial_agent_checkin | String | The timestamp of the initial agent check-in. |
| FireEyeHX.Hosts.last_alert_timestamp | String | The time stamp of the last alert for the host. |
| FireEyeHX.Hosts.last_exploit_block_timestamp | Unknown | The time when the last exploit was blocked on the host. The value is null if no exploits have been blocked. |
| FireEyeHX.Hosts.os.product_name | String | The operating system of the host. |
| FireEyeHX.Hosts.os.bitness | String | The bitness of the operating system. |
| FireEyeHX.Hosts.os.platform | String | The list of operating systems. Valid values are win, osx, and linux. |
| FireEyeHX.Hosts.primary_mac | String | The host MAC address. |
Command example
!fireeye-hx-get-all-hosts-information limit=1
Context Example
{
"FireEyeHX": {
"Hosts": {
"Agent ID": "YYYXXXYYY",
"Agent Version": "31.28.17",
"Containment State": "normal",
"Domain": "WORKGROUP",
"Host IP": "xx.xx.xx.xx",
"Host Name": "XXX",
"Last Alert": {
"_id": 365,
"url": "/hx/api/v3/alerts/365"
},
"Last Poll": "2022-02-23T09:08:31.000Z",
"OS": "win"
}
}
}
Human Readable Output
FireEye HX Get Hosts Information
Host Name Host IP Agent ID Agent Version OS Last Poll Containment State Domain Last Alert XXX xx.xx.xx.xx YYYXXXYYY 31.28.17 win 2022-02-23T09:08:31.000Z normal WORKGROUP _id: 365
url: /hx/api/v3/alerts/365
fireeye-hx-host-containment
Applies containment for a specific host, so that it no longer has access to other systems. If the user does not have the necessary permissions, the command will not approve the request. The permission required to approve the request is api_admin role.
Base Command
fireeye-hx-host-containment
Input
| Argument Name | Description | Required |
|---|---|---|
| hostName | The host name to be contained. If the hostName is not specified, the agentId must be specified. | Optional |
| agentId | The agent id running on the host to be contained. If the agentId is not specified, the hostName must be specified. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Hosts._id | String | The ID of the FireEye HX Agent. |
| FireEyeHX.Hosts.agent_version | String | The version of the agent. |
| FireEyeHX.Hosts.excluded_from_containment | Boolean | Determines whether the host is excluded from containment. |
| FireEyeHX.Hosts.containment_missing_software | Boolean | Whether there is containment missing software. |
| FireEyeHX.Hosts.containment_queued | Boolean | Determines whether the host is queued for containment. |
| FireEyeHX.Hosts.containment_state | String | The containment state of the host. Possible values are normal, contain, contain_fail, containing, contained, uncontain, uncontaining, wtfc, wtfu. |
| FireEyeHX.Hosts.stats.alerting_conditions | Number | The number of conditions that have been alerted for the host. |
| FireEyeHX.Hosts.stats.alerts | Number | The total number of alerts, including exploit-detection alerts. |
| FireEyeHX.Hosts.stats.exploit_blocks | Number | The number of blocked exploits on the host. |
| FireEyeHX.Hosts.stats.malware_alerts | Number | The number of malware alerts associated with the host. |
| FireEyeHX.Hosts.hostname | String | The name of the host. |
| FireEyeHX.Hosts.domain | String | The name of the domain. |
| FireEyeHX.Hosts.timezone | String | The time zone of the host. |
| FireEyeHX.Hosts.primary_ip_address | String | The IP address of the host. |
| FireEyeHX.Hosts.last_poll_timestamp | String | The timestamp of the last system poll preformed on the host. |
| FireEyeHX.Hosts.initial_agent_checkin | String | The timestamp of the initial agent check-in. |
| FireEyeHX.Hosts.last_alert_timestamp | String | The time stamp of the last alert for the host. |
| FireEyeHX.Hosts.last_exploit_block_timestamp | String | The time when the last exploit was blocked on the host. The value is null if no exploits have been blocked. |
| FireEyeHX.Hosts.os.product_name | String | The operating system of the host. |
| FireEyeHX.Hosts.os.bitness | String | The bitness of the operating system. |
| FireEyeHX.Hosts.os.platform | String | The list of operating systems. Valid values are win, osx, and linux. |
| FireEyeHX.Hosts.primary_mac | String | The host MAC address. |
Command example
!fireeye-hx-host-containment hostName=XXX
Context Example
{
"Endpoint": {
"Domain": "WORKGROUP",
"Hostname": "XXX",
"ID": "YYYXXXYYY",
"IPAddress": "xx.xx.xx.xx",
"MACAddress": "xx-xx-xx-xx-xx-xx",
"OS": "win",
"OSVersion": "Windows 10 Pro"
},
"FireEyeHX": {
"Hosts": {
"_id": "YYYXXXYYY",
"agent_version": "31.28.17",
"containment_missing_software": false,
"containment_queued": true,
"containment_state": "contain",
"domain": "WORKGROUP",
"excluded_from_containment": false,
"gmt_offset_seconds": -28800,
"hostname": "XXX",
"initial_agent_checkin": "2021-03-21T13:27:48.058Z",
"last_alert": {
"_id": 365,
"url": "/hx/api/v3/alerts/365"
},
"last_alert_timestamp": "2022-02-23T07:28:34.043+00:00",
"last_audit_timestamp": "2022-02-23T07:28:33.969Z",
"last_exploit_block": null,
"last_exploit_block_timestamp": null,
"last_poll_ip": "xx.xx.xx.xx",
"last_poll_timestamp": "2022-02-23T09:08:31.000Z",
"os": {
"bitness": "64-bit",
"kernel_version": null,
"patch_level": null,
"platform": "win",
"product_name": "Windows 10 Pro"
},
"primary_ip_address": "xx.xx.xx.xx",
"primary_mac": "xx-xx-xx-xx-xx-xx",
"reported_clone": false,
"stats": {
"acqs": 15,
"alerting_conditions": 1,
"alerts": 1,
"exploit_alerts": 0,
"exploit_blocks": 0,
"false_positive_alerts": 0,
"false_positive_alerts_by_source": {},
"generic_alerts": 0,
"malware_alerts": 0,
"malware_cleaned_count": 0,
"malware_false_positive_alerts": 0,
"malware_quarantined_count": 0
},
"sysinfo": {
"url": "/hx/api/v3/hosts/YYYXXXYYY/sysinfo"
},
"timezone": "Pacific Standard Time",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
}
}
}
Human Readable Output
Results
Domain Hostname ID IPAddress MACAddress OS OSVersion WORKGROUP XXX YYYXXXYYY xx.xx.xx.xx xx-xx-xx-xx-xx-xx win Windows 10 Pro
fireeye-hx-cancel-containment
Releases a specific host from containment.
Base Command
fireeye-hx-cancel-containment
Input
| Argument Name | Description | Required |
|---|---|---|
| hostName | The host name to be contained. If the hostName is not specified, the agentId must be specified. | Optional |
| agentId | The agent ID running on the host to be contained. If the agentId is not specified, the hostName must be specified. | Optional |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-cancel-containment hostName=XXX
Human Readable Output
Success
fireeye-hx-initiate-data-acquisition
Initiates a data acquisition process to collect artifacts from the system disk and memory.
Base Command
fireeye-hx-initiate-data-acquisition
Input
| Argument Name | Description | Required |
|---|---|---|
| script | The acquisition script in JSON format. | Optional |
| scriptName | The script name. If the acquisition script is specified, the script name must be specified as well. | Optional |
| defaultSystemScript | Select the host system to use the default system script. Possible values are: osx, win, linux. | Optional |
| agentId | The agent ID. If the hostName is not specified, the agent ID must be specified. | Optional |
| hostName | The host name. If the agent ID is not specified, the hostName must be specified. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Acquisitions.Data._id | string | The unique ID of the acquisition. |
| FireEyeHX.Acquisitions.Data.state | string | The state of the acquisition. |
| FireEyeHX.Acquisitions.Data.md5 | string | The MD5 of the file. |
| FireEyeHX.Acquisitions.Data.host._id | string | The ID of the agent. |
| FireEyeHX.Acquisitions.Data.host.hostname | string | The name of the host. |
| FireEyeHX.Acquisitions.Data.instance | string | The FireEye HX instance. |
| FireEyeHX.Acquisitions.Data.finish_time | date | The time when the acquisition finished. |
fireeye-hx-get-host-set-information
Returns a list of all host sets known to your HX Series appliance.
Base Command
fireeye-hx-get-host-set-information
Input
| Argument Name | Description | Required |
|---|---|---|
| hostSetID | The ID of a specific host set to return. | Optional |
| offset | Specifies which record to start with in the response. The offset value must be an unsigned 32-bit integer. Default is 0. | Optional |
| limit | Specifies how many records are returned. The limit value must be an unsigned 32-bit integer. Default is 50. | Optional |
| search | Searches the names of all host sets connected to the specified HX appliance. | Optional |
| sort | Sorts the results by the specified field in ascending or descending order. The default sorts in ascending order, by name. Sortable fields are _id (host set ID) and name (host set name). | Optional |
| name | Specifies the name of the host set for which to search. | Optional |
| type | Specifies the type of host set for which to search. Possible values are: venn, static. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.HostSets._id | number | The ID of the host set. |
| FireEyeHX.HostSets._revision | string | The number of the host set revision. |
| FireEyeHX.HostSets.name | string | The name of the host set. |
| FireEyeHX.HostSets.type | string | The type of the host set (static/dynamic/hidden). |
| FireEyeHX.HostSets.url | string | The FireEye URL of the host set. |
| FireEyeHX.HostSets.deleted | Boolean | Was the host set deleted. |
Command example
!fireeye-hx-get-host-set-information hostSetID=1001
Context Example
{
"FireEyeHX": {
"HostSets": {
"_id": 1001,
"_revision": "20210308150955358783164361",
"name": "Test",
"type": "venn",
"url": "/hx/api/v3/host_sets/1001",
"deleted": false
}
}
}
Human Readable Output
FireEye HX Get Host Sets Information
Name ID Type Test 1001 venn
fireeye-hx-list-policy
Returns a list of all policies.
Base Command
fireeye-hx-list-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| offset | Specifies which record to start with in the response. Default is 0. | Optional |
| limit | Limits the number of results. | Optional |
| policyName | The name of the policy. | Optional |
| policyId | The unique policy ID. | Optional |
| enabled | Whether the policy is enabled (“true”) or disabled (“false”). Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Policy._id | String | The ID of the unique policy. |
| FireEyeHX.Policy.name | String | The name of the policy. |
| FireEyeHX.Policy.description | String | The description of the policy. |
| FireEyeHX.Policy.policy_type_id | String | The ID of the unique policy type. |
| FireEyeHX.Policy.priority | Number | The priority order of the policy. |
| FireEyeHX.Policy.enabled | Boolean | Whether the policy is enabled (“true”) or disabled (“false”). |
| FireEyeHX.Policy.default | Boolean | Whether it is the default policy (true). There can only be one policy marked as default. |
| FireEyeHX.Policy.migrated | Boolean | Whether it is a migrated policy (true). |
| FireEyeHX.Policy.created_by | String | The user who created the policy. |
| FireEyeHX.Policy.created_at | String | The time the policy was first created. |
| FireEyeHX.Policy.updated_at | String | The time the policy was last updated. |
| FireEyeHX.Policy.categories | Unknown | The collection of categories that the policy is associated. |
| FireEyeHX.Policy.display_created_at | String | The time since the display was first created. |
| FireEyeHX.Policy.display_updated_at | String | The time since the display was last updated. |
Command example
!fireeye-hx-list-policy limit=2 policyName=Test
Context Example
{
"FireEyeHX": {
"Policy": {
"data": {
"entries": [],
"limit": 2,
"offset": 0,
"query": {
"limit": "2",
"name": "Test",
"offset": "0"
},
"sort": {},
"total": 0
},
"details": [],
"message": "OK",
"route": "/hx/api/v3/policies"
}
}
}
Human Readable Output
FireEye HX List Policies
No entries.
fireeye-hx-list-host-set-policy
Returns a list of all policies for all host sets.
Base Command
fireeye-hx-list-host-set-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| offset | Specifies which record to start with in the response. Default is 0. | Optional |
| limit | Limits the number of results. | Optional |
| hostSetId | The host set ID. | Optional |
| policyId | The unique policy ID. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.HostSets.Policy.policy_id | String | The ID of the unique policy. |
| FireEyeHX.HostSets.Policy.persist_id | Number | The ID of the host set. |
Command example
!fireeye-hx-list-host-set-policy limit=1
Context Example
{
"FireEyeHX": {
"HostSets": {
"Policy": [
{
"persist_id": 1001,
"policy_id": "YYYXXXYYY"
},
{
"persist_id": 1002,
"policy_id": "YYYXXXYYY"
},
{
"persist_id": 1005,
"policy_id": "YYYXXXYYY"
},
{
"persist_id": 1005,
"policy_id": "YYYXXXYYY"
}
]
}
}
}
Human Readable Output
FireEye HX Host Set Policies
Policy Id Host Set Id YYYXXXYYY 1001 YYYXXXYYY 1002 YYYXXXYYY 1005 YYYXXXYYY 1005
fireeye-hx-list-containment
Fetches all containment states across known hosts.
Base Command
fireeye-hx-list-containment
Input
| Argument Name | Description | Required |
|---|---|---|
| offset | Specifies which record to start with in the response. Default is 0. | Optional |
| limit | Limits the number of results. | Optional |
| state_update_time | Must be from type of -> String: date-time. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Hosts._id | String | The FireEye HX Agent ID. |
| FireEyeHX.Hosts.last_sysinfo | String | The Last Sysinfo date. |
| FireEyeHX.Hosts.requested_by_actor | String | The action requested by actor. |
| FireEyeHX.Hosts.requested_on | String | When the containment was requested. |
| FireEyeHX.Hosts.contained_by_actor | String | The action contained by actor. |
| FireEyeHX.Hosts.contained_on | String | When the host was contained. |
| FireEyeHX.Hosts.queued | Boolean | Determines whether the hosts are queued for containment. |
| FireEyeHX.Hosts.excluded | Boolean | Whether the hosts are excluded. |
| FireEyeHX.Hosts.missing_software | Boolean | Whether there is missing software. |
| FireEyeHX.Hosts.reported_clone | Boolean | Whether there is a reported clone. |
| FireEyeHX.Hosts.state | String | The state of the hosts. |
| FireEyeHX.Hosts.state_update_time | String | The state update time of the hosts. |
| FireEyeHX.Hosts.url | String | The URL of the hosts. |
Command example
!fireeye-hx-list-containment limit=2
Context Example
{
"FireEyeHX": {
"Hosts": [
{
"_id": "YYYXXXYYY",
"contained_by_actor": null,
"contained_on": null,
"excluded": false,
"last_sysinfo": "2022-02-23T07:28:33.969Z",
"missing_software": false,
"queued": false,
"reported_clone": false,
"requested_by_actor": null,
"requested_on": null,
"state": "normal",
"state_update_time": "2022-02-22T14:00:31.056Z",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
},
{
"_id": "YYYXXXYYY",
"contained_by_actor": null,
"contained_on": null,
"excluded": false,
"last_sysinfo": "2022-02-23T08:23:25.592Z",
"missing_software": false,
"queued": false,
"reported_clone": false,
"requested_by_actor": null,
"requested_on": null,
"state": "normal",
"state_update_time": "2021-03-17T12:54:56.481Z",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
}
]
}
}
Human Readable Output
List Containment
Id State Request Origin Request Date Containment Origin Containment Date Last System information date YYYXXXYYY normal 2022-02-23T07:28:33.969Z YYYXXXYYY normal 2022-02-23T08:23:25.592Z
fireeye-hx-search-list
Fetches all enterprise searches.
Base Command
fireeye-hx-search-list
Input
| Argument Name | Description | Required |
|---|---|---|
| offset | Specifies which record to start with in the response. Default is 0. | Optional |
| limit | Specifies how many records are returned. Default is 50. | Optional |
| state | Filter by search state. Select either STOPPED or RUNNING. Possible values are: RUNNING, STOPPED. | Optional |
| sort | Sorts the results by the specified field. Default is sort by _id. Possible values are:_id, state, host_set._id, update_time, create_time, update_actor._id, update_actor.username, create_actor._id, create_actor.username. | Optional |
| hostSetId | Filters searches by host set ID - <Integer>. | Optional |
| searchId | Returns a single enterprise search record. If you enter this argument there is no need for other arguments. | Optional |
| actorUsername | Filters searches by username that created searches - <String>. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Search._id | Number | The ID of the unique search. |
| FireEyeHX.Search.state | String | The state of the search, whether it stopped or ran. |
| FireEyeHX.Search.scripts | Unknown | A list of reference objects for the scripts utilized in this search. |
| FireEyeHX.Search.update_time | String | The time the search was last updated. |
| FireEyeHX.Search.create_time | String | The time the search was created. |
| FireEyeHX.Search.scripts.platform | Unknown | The platform for which this script is used. |
| FireEyeHX.Search.update_actor | Unknown | The actor who last updated the search. |
| FireEyeHX.Search.create_actor | Unknown | The actor who created the search. |
| FireEyeHX.Search.error | Unknown | Collection of errors per agents for the search. |
| FireEyeHX.Search._revision | String | The ETag that can be used for concurrency checking. |
| FireEyeHX.Search.input_type | String | The input method that was used to start the search. |
| FireEyeHX.Search.url | String | The URI to retrieve data for this record. |
| FireEyeHX.Search.host_set | Unknown | The Host Set information. |
| FireEyeHX.Search.stats | Unknown | The stats information. |
| FireEyeHX.Search.stats.hosts | Number | The number of hosts running this operation. |
| FireEyeHX.Search.stats.skipped_hosts | Number | The number of hosts that were skipped. |
| FireEyeHX.Search.stats.search_state | Unknown | The number of search in different states. |
| FireEyeHX.Search.stats.search_issues | Unknown | The issues encountered for searches. |
| FireEyeHX.Search.settings.query_terms.terms | Unknown | The terms for the operation. |
| FireEyeHX.Search.stats.hosts.settings.query_terms.exhaustive_terms | Unknown | The exhaustive terms for the operation. |
| FireEyeHX.Search.stats.settings.search_type | String | The type of search. |
| FireEyeHX.Search.stats.settings.exhaustive | String | Whether a search is exhaustive. |
| FireEyeHX.Search.stats.settings.mode | String | Whether a search is a HOST type or GRID type. |
| FireEyeHX.Search.stats.settings.displayname | String | The name of the search. |
Command example
!fireeye-hx-search-list limit=1
Context Example
{
"FireEyeHX": {
"Search": {
"_id": 143,
"_revision": "20220223091811214662597541",
"create_actor": {
"_id": 1001,
"username": "test"
},
"create_time": "2022-02-23T09:18:11.214Z",
"error": null,
"host_set": null,
"input_type": "api",
"scripts": [
{
"_id": "YYYXXXYYY",
"download": "/hx/api/v3/scripts/YYYXXXYYY.json",
"platform": "win",
"url": "/hx/api/v3/scripts/YYYXXXYYY"
},
{
"_id": "YYYXXXYYY",
"download": "/hx/api/v3/scripts/YYYXXXYYY.json",
"platform": "osx",
"url": "/hx/api/v3/scripts/YYYXXXYYY"
}
],
"settings": {
"displayname": null,
"exhaustive": true,
"mode": "HOST",
"query_terms": {
"exhaustive_terms": [],
"terms": [
{
"field": "IP Address",
"operator": "equals",
"value": "xx.xx.xx.xx"
}
]
},
"search_type": "QUERY"
},
"state": "RUNNING",
"stats": {
"hosts": 1,
"running_state": {
"ABORTED": 0,
"CANCELLED": 0,
"COMPLETE": 0,
"DELETED": 0,
"FAILED": 0,
"NEW": 1,
"QUEUED": 0,
"REFRESH": 0
},
"search_issues": {},
"search_state": {
"ERROR": 0,
"MATCHED": 0,
"NOT_MATCHED": 0,
"PENDING": 1
},
"skipped_hosts": 0
},
"update_actor": {
"_id": 1001,
"username": "test"
},
"update_time": "2022-02-23T09:18:11.214Z",
"url": "/hx/api/v3/searches/143"
}
}
}
Human Readable Output
Id State Host Set Created By Created At Updated By Updated At 143 RUNNING _id: 1001
username: test2022-02-23T09:18:11.214Z _id: 1001
username: test2022-02-23T09:18:11.214Z
fireeye-hx-search-stop
Stops a specific running search.
Base Command
fireeye-hx-search-stop
Input
| Argument Name | Description | Required |
|---|---|---|
| searchId | Unique search ID - Required. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Search._id | Number | The ID of the unique search. |
| FireEyeHX.Search.state | String | The state of the search, whether it stopped or ran. |
| FireEyeHX.Search.scripts | Unknown | A list of reference objects for the scripts utilized in this search. |
| FireEyeHX.Search.update_time | String | The time the search was last updated. |
| FireEyeHX.Search.create_time | String | The time the search was created. |
| FireEyeHX.Search.scripts.platform | Unknown | The platform for which this script is used. |
| FireEyeHX.Search.update_actor | Unknown | The actor who last updated the search. |
| FireEyeHX.Search.create_actor | Unknown | The actor who created the search. |
| FireEyeHX.Search.error | Unknown | The collection of errors per agents for the search. |
| FireEyeHX.Search._revision | Unknown | ETag that can be used for concurrency checking. |
| FireEyeHX.Search.input_type | String | The input method that was used to start the search. |
| FireEyeHX.Search.url | String | The URI to retrieve data for this record. |
| FireEyeHX.Search.host_set | Unknown | The Host Set information. |
| FireEyeHX.Search.stats | Unknown | The stats information. |
| FireEyeHX.Search.stats.hosts | Number | The number of hosts running this operation. |
| FireEyeHX.Search.stats.skipped_hosts | Number | The number of hosts that were skipped. |
| FireEyeHX.Search.stats.search_state | Unknown | The number of search in different states. |
| FireEyeHX.Search.stats.search_issues | Unknown | The issues encountered for searches. |
| FireEyeHX.Search.settings.query_terms.terms | Unknown | The terms for the operation. |
| FireEyeHX.Search.stats.hosts.settings.query_terms.exhaustive_terms | Unknown | The exhaustive terms for the operation |
| FireEyeHX.Search.stats.settings.search_type | String | The type of search. |
| FireEyeHX.Search.stats.settings.exhaustive | String | Whether a search is exhaustive. |
| FireEyeHX.Search.stats.settings.mode | String | Whether a search is a HOST type or GRID type. |
| FireEyeHX.Search.stats.settings.displayname | String | The name of the search. |
Command example
!fireeye-hx-search-stop searchId=141
Context Example
{
"FireEyeHX": {
"Search": {
"_id": 141,
"_revision": "20220223091838188310597550",
"create_actor": {
"_id": 1001,
"username": "test"
},
"create_time": "2022-02-23T09:05:54.645Z",
"error": null,
"host_set": null,
"input_type": "api",
"scripts": [
{
"_id": "YYYXXXYYY",
"download": "/hx/api/v3/scripts/YYYXXXYYY.json",
"platform": "win",
"url": "/hx/api/v3/scripts/YYYXXXYYY"
},
{
"_id": "YYYXXXYYY",
"download": "/hx/api/v3/scripts/YYYXXXYYY.json",
"platform": "osx",
"url": "/hx/api/v3/scripts/YYYXXXYYY"
}
],
"settings": {
"displayname": null,
"exhaustive": true,
"mode": "HOST",
"query_terms": {
"exhaustive_terms": [],
"terms": [
{
"field": "IP Address",
"operator": "equals",
"value": "xx.xx.xx.xx"
}
]
},
"search_type": "QUERY"
},
"state": "STOPPED",
"stats": {
"hosts": 1,
"running_state": {
"ABORTED": 0,
"CANCELLED": 0,
"COMPLETE": 1,
"DELETED": 0,
"FAILED": 0,
"NEW": 0,
"QUEUED": 0,
"REFRESH": 0
},
"search_issues": {},
"search_state": {
"ERROR": 0,
"MATCHED": 1,
"NOT_MATCHED": 0,
"PENDING": 0
},
"skipped_hosts": 0
},
"update_actor": {
"_id": 1001,
"username": "test"
},
"update_time": "2022-02-23T09:18:38.188Z",
"url": "/hx/api/v3/searches/141"
}
}
}
Human Readable Output
Results
Search Id 141: Success
fireeye-hx-search-result-get
Fetches the results for a specific enterprise search.
Base Command
fireeye-hx-search-result-get
Input
| Argument Name | Description | Required |
|---|---|---|
| searchId | The Unique search ID. | Required |
| limit | Limit the number of results to return per search. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Search.host._id | String | The ID of the unique agent. |
| FireEyeHX.Search.host.url | String | The URI to retrieve data for this record. |
| FireEyeHX.Search.host.hostname | String | The name of the host. |
| FireEyeHX.Search.results._id | Number | The unique ID. |
| FireEyeHX.Search.results.type | String | The type of the search result data. |
| FireEyeHX.Search.results.data | Unknown | The object containing data relating to the search result for the host. |
Command example
!fireeye-hx-search-result-get searchId=141
Context Example
{
"FireEyeHX": {
"Search": {
"host": {
"_id": "YYYXXXYYY",
"hostname": "XXX",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
},
"results": [
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "64924",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-01-20T09:41:51.470Z",
"Timestamp - Event": "2022-01-20T09:41:51.470Z",
"Username": "XXX\\User"
},
"id": 1,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "64925",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-01-20T09:41:51.470Z",
"Timestamp - Event": "2022-01-20T09:41:51.470Z",
"Username": "XXX\\User"
},
"id": 2,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "64926",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-01-20T09:41:51.470Z",
"Timestamp - Event": "2022-01-20T09:41:51.470Z",
"Username": "XXX\\User"
},
"id": 3,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "56687",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-01-31T06:56:37.591Z",
"Timestamp - Event": "2022-01-31T06:56:37.591Z",
"Username": "XXX\\User"
},
"id": 4,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "58763",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-02-01T07:51:38.928Z",
"Timestamp - Event": "2022-02-01T07:51:38.928Z",
"Username": "XXX\\User"
},
"id": 5,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "58766",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-02-01T07:53:03.630Z",
"Timestamp - Event": "2022-02-01T07:53:03.630Z",
"Username": "XXX\\User"
},
"id": 6,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "59099",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-02-01T12:04:14.969Z",
"Timestamp - Event": "2022-02-01T12:04:14.969Z",
"Username": "XXX\\User"
},
"id": 7,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "55107",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-02-07T10:51:46.951Z",
"Timestamp - Event": "2022-02-07T10:51:46.951Z",
"Username": "XXX\\User"
},
"id": 8,
"type": "IPv4 Network Event"
},
{
"data": {
"IP Address": "xx.xx.xx.xx",
"Local IP Address": "xx.xx.xx.xx",
"Local Port": "55107",
"Port": "443",
"Process ID": "8696",
"Process Name": "chrome.exe",
"Remote IP Address": "xx.xx.xx.xx",
"Remote Port": "443",
"Timestamp - Accessed": "2022-02-07T10:53:17.233Z",
"Timestamp - Event": "2022-02-07T10:53:17.233Z",
"Username": "XXX\\User"
},
"id": 9,
"type": "IPv4 Network Event"
}
]
}
}
}
Human Readable Output
Host Id YYYXXXYYY
Host Name XXX
Item Type Summary IPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 64924,
Remote Port: 443,
Timestamp - Event: 2022-01-20T09:41:51.470Z,
Timestamp - Accessed: 2022-01-20T09:41:51.470ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 64925,
Remote Port: 443,
Timestamp - Event: 2022-01-20T09:41:51.470Z,
Timestamp - Accessed: 2022-01-20T09:41:51.470ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 64926,
Remote Port: 443,
Timestamp - Event: 2022-01-20T09:41:51.470Z,
Timestamp - Accessed: 2022-01-20T09:41:51.470ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 56687,
Remote Port: 443,
Timestamp - Event: 2022-01-31T06:56:37.591Z,
Timestamp - Accessed: 2022-01-31T06:56:37.591ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 58763,
Remote Port: 443,
Timestamp - Event: 2022-02-01T07:51:38.928Z,
Timestamp - Accessed: 2022-02-01T07:51:38.928ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 58766,
Remote Port: 443,
Timestamp - Event: 2022-02-01T07:53:03.630Z,
Timestamp - Accessed: 2022-02-01T07:53:03.630ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 59099,
Remote Port: 443,
Timestamp - Event: 2022-02-01T12:04:14.969Z,
Timestamp - Accessed: 2022-02-01T12:04:14.969ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 55107,
Remote Port: 443,
Timestamp - Event: 2022-02-07T10:51:46.951Z,
Timestamp - Accessed: 2022-02-07T10:51:46.951ZIPv4 Network Event Process Name: chrome.exe,
Process ID: 8696,
Username: XXX\User,
Local IP Address: xx.xx.xx.xx,
Remote IP Address: xx.xx.xx.xx,
IP Address: xx.xx.xx.xx,
Port: 443,
Local Port: 55107,
Remote Port: 443,
Timestamp - Event: 2022-02-07T10:53:17.233Z,
Timestamp - Accessed: 2022-02-07T10:53:17.233Z
fireeye-hx-search
Searches endpoints to check all hosts or a subset of hosts for a specific file or indicator.
Base Command
fireeye-hx-search
Input
| Argument Name | Description | Required |
|---|---|---|
| searchId | searchId. | Optional |
| agentsIds | The IDs of the gents to be searched. | Optional |
| hostsNames | The names of hosts to be searched. | Optional |
| hostSet | The ID of host set to be searched. | Optional |
| hostSetName | The name of host set to be searched. | Optional |
| limit | Limits the results count (once the limit is reached, the search is stopped). | Optional |
| exhaustive | Whether a search is exhaustive or quick. Possible values are: yes, no. Default is yes. | Optional |
| ipAddress | A valid IPv4 address for which to search. | Optional |
| ipAddressOperator | Which operator to apply to the given IP address. Possible values are: equals, not equals. | Optional |
| polling | Whether to use Cortex XSOAR’s built-in polling to retrieve the result, when ready. Possible values are: true, false. | Optional |
| interval_in_seconds | The interval in seconds between each poll. Default is 60. | Optional |
| fileMD5Hash | A 32-character MD5 hash value for which to search. | Optional |
| fileMD5HashOperator | Which operator to apply to the given MD5 hash. Possible values are: equals, not equals. | Optional |
| fileFullPath | The full path of file to search. | Optional |
| fileFullPathOperator | Which operator to apply to the given file path. Possible values are: equals, not equals, contains, not contains. | Optional |
| dnsHostname | The DNS value for which to search. | Optional |
| dnsHostnameOperator | Which operator to apply to the given DNS. Possible values are: equals, not equals, contains, not contains. | Optional |
| stopSearch | The method in which the search should be stopped after finding <limit> number of results. Possible values are: stopAndDelete, stop. | Optional |
| fieldSearchName | Searchable fields - If using this argument, the ‘fieldSearchOperator’ and ‘fieldSearchValue’ arguments are required. Possible values are: Application Name, Browser Name, Browser Version, Cookie Flags, Cookie Name, Cookie Value, Driver Device Name, Driver Module Name, Executable Exported Dll Name, Executable Exported Function Name, Executable Imported Function Name, Executable Imported Module Name, Executable Injected, Executable PE Type, Executable Resource Name, File Attributes, File Certificate Issuer, File Certificate Subject, File Download Mime Type, File Download Referrer, File Download Type, File Name, File SHA1 Hash, File SHA256 Hash, File Signature Exists, File Signature Verified, File Stream Name, File Text Written, Group Name, HTTP Header, Host Set, Hostname, Local IP Address, Local Port, Parent Process Name, Parent Process Path, Port, Port Protocol, Port State, Process Arguments, Process Name, Quarantine Event Sender Address, Quarantine Event Sender Name, Registry Key Full Path, Registry Key Value Name, Registry Key Value Text, Remote IP Address, Remote Port, Service DLL, Service Mode, Service Name, Service Status, Service Type, Size in bytes, Syslog Event ID, Syslog Event Message, Syslog Facility. | Optional |
| fieldSearchOperator | Which operator to apply to the given search field. Possible values are: equals, not equals, contains, not contains, less than, greater than. | Optional |
| fieldSearchValue | One or more values that match the selected search type. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Search.results.data.Timestamp - Modified | string | The time when the entry was last modified. |
| FireEyeHX.Search.results.data.File Text Written | string | The file text content. |
| FireEyeHX.Search.results.data.File Name | string | The name of the file. |
| FireEyeHX.Search.results.data.File Full Path | string | The full path of the file. |
| FireEyeHX.Search.results.data.File Bytes Written | string | The number of bytes written to the file. |
| FireEyeHX.Search.results.data.Size in bytes | string | The size of the file in bytes. |
| FireEyeHX.Search.results.data.Browser Version | string | The version of the browser. |
| FireEyeHX.Search.results.data.Browser Name | string | The name of the browser. |
| FireEyeHX.Search.results.data.Cookie Name | string | The name of the cookie. |
| FireEyeHX.Search.results.data.DNS Hostname | string | The name of the DNS host. |
| FireEyeHX.Search.results.data.URL | string | The event URL. |
| FireEyeHX.Search.results.data.Username | string | The event username. |
| FireEyeHX.Search.results.data.File MD5 Hash | string | The MD5 hash of the file. |
| FireEyeHX.Search.host._id | string | The ID of the host. |
| FireEyeHX.Search.host.hostname | string | The name of host. |
| FireEyeHX.Search.host.url | string | The Inner FireEye host URL. |
| FireEyeHX.Search.results.data | string | The ID of the performed search. |
| FireEyeHX.Search.results.data.Timestamp - Accessed | string | The last accessed time. |
| FireEyeHX.Search.results.data.Port | number | The Port. |
| FireEyeHX.Search.results.data.Process ID | string | The ID of the process. |
| FireEyeHX.Search.results.data.Local IP Address | string | The local IP Address. |
| FireEyeHX.Search.results.data.Local IP Address | string | The local IP Address. |
| FireEyeHX.Search.results.data.Local Port | number | The local Port. |
| FireEyeHX.Search.results.data.Username | string | The username. |
| FireEyeHX.Search.results.data.Remote Port | number | The remote port. |
| FireEyeHX.Search.results.data.IP Address | string | The IP address. |
| FireEyeHX.Search.results.data.Process Name | string | The process name. |
| FireEyeHX.Search.results.data.Timestamp - Event | string | The timestamp of the event. |
| FireEyeHX.Search.results.type | string | The type of the event. |
| FireEyeHX.Search.results.id | string | The ID of the result. |
Command example
!fireeye-hx-search hostsNames=XXX ipAddress=xx.xx.xx.xx ipAddressOperator=equals polling=false
Human Readable Output
Search started,
Search ID: 143
fireeye-hx-get-alert
Get details of a specific alert.
Base Command
fireeye-hx-get-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alertId | The alert ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Alerts._id | Number | The ID of the FireEye alert. |
| FireEyeHX.Alerts.agent._id | Unknown | The ID of the FireEye agent. |
| FireEyeHX.Alerts.agent.containment_state | Unknown | The containment state of the agent. |
| FireEyeHX.Alerts.condition._id | String | The unique ID of the condition. |
| FireEyeHX.Alerts.event_at | String | The time when the event occurred. |
| FireEyeHX.Alerts.matched_at | String | The time when the event was matched. |
| FireEyeHX.Alerts.reported_at | String | The time when the event was reported. |
| FireEyeHX.Alerts.source | String | The source of the alert. |
| FireEyeHX.Alerts.matched_source_alerts._id | Unknown | The ID of the source alert. |
| FireEyeHX.Alerts.matched_source_alerts.appliance_id | Unknown | The ID of the appliance. |
| FireEyeHX.Alerts.matched_source_alerts.meta | Unknown | The source alert meta. |
| FireEyeHX.Alerts.matched_source_alerts.indicator_id | Unknown | The ID of the indicator. |
| FireEyeHX.Alerts.resolution | String | The alert resolution. |
| FireEyeHX.Alerts.event_type | String | The type of the event. |
Command example
!fireeye-hx-get-alert alertId=8
Context Example
{
"DBotScore": {
"Indicator": null,
"Score": 0,
"Type": "file",
"Vendor": "FireEyeHX v2"
},
"File": {
"Extension": "exe",
"Name": "feyeqatest.exe",
"Path": "C:\\Users\\User\\Desktop\\\u37cb\\feyeqatest.exe"
},
"FireEyeHX": {
"Alerts": {
"_id": 8,
"agent": {
"_id": "YYYXXXYYY",
"containment_state": "normal",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
},
"appliance": {
"_id": "YYYXXXYYY"
},
"condition": {
"_id": "YYYXXXYYY",
"url": "/hx/api/v3/conditions/YYYXXXYYY"
},
"decorator_statuses": [],
"decorators": [],
"event_at": "2022-01-25T10:25:19.665Z",
"event_id": 59302205,
"event_type": "fileWriteEvent",
"event_values": {
"fileWriteEvent/closed": 1,
"fileWriteEvent/drive": "C",
"fileWriteEvent/eventReason": "Unknown",
"fileWriteEvent/fileExtension": "exe",
"fileWriteEvent/fileName": "feyeqatest.exe",
"fileWriteEvent/filePath": "Users\\User\\Desktop\\\u37cb",
"fileWriteEvent/fullPath": "C:\\Users\\User\\Desktop\\\u37cb\\feyeqatest.exe",
"fileWriteEvent/numBytesSeenWritten": 0,
"fileWriteEvent/openDuration": 0,
"fileWriteEvent/openTime": "2022-01-25T10:25:19.665Z",
"fileWriteEvent/parentPid": 5560,
"fileWriteEvent/parentProcessPath": "C:\\Windows\\System32\\userinit.exe",
"fileWriteEvent/pid": 5604,
"fileWriteEvent/process": "explorer.exe",
"fileWriteEvent/processPath": "C:\\Windows",
"fileWriteEvent/size": 70,
"fileWriteEvent/timestamp": "2022-01-25T10:25:19.665Z",
"fileWriteEvent/username": "XXX\\User",
"fileWriteEvent/writes": 0
},
"indicator": {
"_id": "2b4753b0-9972-477e-ba16-1a7c29058cee",
"category": "mandiant_unrestricted",
"display_name": "FIREEYE END2END TEST",
"name": "FIREEYE END2END TEST",
"signature": null,
"uri_name": "2b4753b0-9972-477e-ba16-1a7c29058cee",
"url": "/hx/api/v3/indicators/mandiant_unrestricted/2b4753b0_9972_477e_ba16_1a7c29058cee"
},
"is_false_positive": false,
"matched_at": "2022-01-25T10:25:34.000Z",
"matched_source_alerts": [],
"md5values": [],
"multiple_match": null,
"reported_at": "2022-01-25T10:25:44.011Z",
"resolution": "ALERT",
"source": "IOC",
"subtype": null,
"url": "/hx/api/v3/alerts/8"
}
}
}
Human Readable Output
File
Name md5 Extension Path feyeqatest.exe exe C:\Users\User\Desktop\㟋\feyeqatest.exe
fireeye-hx-suppress-alert
Suppresses an alert by ID.
Base Command
fireeye-hx-suppress-alert
Input
| Argument Name | Description | Required |
|---|---|---|
| alertId | The alert ID. The alert ID is listed in the output of ‘get-alerts’. command. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-suppress-alert alertId=18
Human Readable Output
Alert 18 suppressed successfully.
fireeye-hx-get-indicators
Get a list of indicators.
Base Command
fireeye-hx-get-indicators
Input
| Argument Name | Description | Required |
|---|---|---|
| category | The category of the indicator. | Optional |
| searchTerm | The searchTerm can be any name, category, signature, source, or condition value. | Optional |
| shareMode | Determines who can see the indicator. They must belong to the correct authorization group. Possible values are: any, restricted, unrestricted, visible. | Optional |
| sort | Sorts the results by the specified field in ascending order. Possible values are: category, activeSince, createdBy, alerted. | Optional |
| createdBy | The person who created the indicator. | Optional |
| alerted | Whether the indicator resulted in alerts. Possible values are: yes, no. | Optional |
| limit | Limits the number of results. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Indicators._id | String | FireEye unique indicator ID. |
| FireEyeHX.Indicators.name | String | The indicator name as displayed in the UI. |
| FireEyeHX.Indicators.description | String | The description of the indicator. |
| FireEyeHX.Indicators.category.name | String | The Category name. |
| FireEyeHX.Indicators.created_by | String | The “Created By” field as displayed in UI. |
| FireEyeHX.Indicators.active_since | String | The date the indicator became active. |
| FireEyeHX.Indicators.stats.source_alerts | Unknown | The total number of source alerts associated with this indicator. |
| FireEyeHX.Indicators.stats.alerted_agents | Unknown | The total number of agents with HX alerts associated with this indicator. |
| FireEyeHX.Indicators.platforms | Unknown | The list of operating systems. |
| FireEyeHX.Indicators.uri_name | String | The URI formatted name of the indicator. |
| FireEyeHX.Indicators.category.uri_name | String | The URI name of the category. |
Command example
!fireeye-hx-get-indicators limit=2
Context Example
{
"FireEyeHX": {
"Indicators": [
{
"_id": "YYYXXXYYY",
"_revision": "20220223091809012244597537",
"active_since": "2022-02-23T09:18:09.012Z",
"category": {
"_id": 2,
"name": "Custom",
"share_mode": "unrestricted",
"uri_name": "Custom",
"url": "/hx/api/v3/indicator_categories/custom"
},
"create_actor": {
"_id": 1001,
"username": "test"
},
"create_text": null,
"created_by": "test",
"description": null,
"display_name": null,
"meta": null,
"name": "YYYXXXYYY",
"platforms": [
"win",
"osx",
"linux"
],
"signature": null,
"stats": {
"active_conditions": 0,
"alerted_agents": 0,
"source_alerts": 0
},
"update_actor": {
"_id": 1001,
"username": "test"
},
"uri_name": "YYYXXXYYY",
"url": "/hx/api/v3/indicators/custom/37a97ac2_35e9_40ad_a108_6802d5d82890"
},
{
"_id": "YYYXXXYYY",
"_revision": "20220223075746635023596874",
"active_since": "2022-02-23T07:57:46.635Z",
"category": {
"_id": 2,
"name": "Custom",
"share_mode": "unrestricted",
"uri_name": "Custom",
"url": "/hx/api/v3/indicator_categories/custom"
},
"create_actor": {
"_id": 1001,
"username": "test"
},
"create_text": null,
"created_by": "test",
"description": null,
"display_name": null,
"meta": null,
"name": "YYYXXXYYY",
"platforms": [
"win",
"osx",
"linux"
],
"signature": null,
"stats": {
"active_conditions": 0,
"alerted_agents": 0,
"source_alerts": 0
},
"update_actor": {
"_id": 1001,
"username": "test"
},
"uri_name": "YYYXXXYYY",
"url": "/hx/api/v3/indicators/custom/5d5cea45_2856_4338_8de8_7ef2b16f9511"
}
]
}
}
Human Readable Output
FireEye HX Get Indicator- None
OS Name Created By Active Since Category Signature Active Condition Hosts With Alerts Source Alerts win, osx, linux YYYXXXYYY test 2022-02-23T09:18:09.012Z Custom 0 0 0 win, osx, linux YYYXXXYYY test 2022-02-23T07:57:46.635Z Custom 0 0 0
fireeye-hx-get-indicator
Get details of a specific indicator.
Base Command
fireeye-hx-get-indicator
Input
| Argument Name | Description | Required |
|---|---|---|
| category | The category of the indicator. Use the uri_category value. |
Required |
| name | The name of the indicator. Use the uri_name value. |
Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Indicators._id | String | The FireEye unique indicator ID. |
| FireEyeHX.Indicators.name | String | The indicator name as displayed in the UI. |
| FireEyeHX.Indicators.description | String | The description of the indicator. |
| FireEyeHX.Indicators.category.name | String | The name of the category. |
| FireEyeHX.Indicators.created_by | String | The “Created By” field as displayed in UI. |
| FireEyeHX.Indicators.active_since | String | The date the indicator became active. |
| FireEyeHX.Indicators.stats.source_alerts | Unknown | The total number of source alerts associated with this indicator. |
| FireEyeHX.Indicators.stats.alerted_agents | Unknown | The total number of agents with HX alerts associated with this indicator. |
| FireEyeHX.Indicators.platforms | Unknown | The list of operating systems. |
| FireEyeHX.Conditions._id | Unknown | The ID of the FireEye unique condition. |
| FireEyeHX.Conditions.event_type | Unknown | The type of the event. |
| FireEyeHX.Conditions.enabled | Unknown | Indicates whether the condition is enabled. |
Command example
!fireeye-hx-get-indicator category=Custom name=YYYXXXYYY
Context Example
{
"FireEyeHX": {
"Indicators": {
"_id": "YYYXXXYYY",
"_revision": "20220223075746635023596874",
"active_since": "2022-02-23T07:57:46.635Z",
"category": {
"_id": 2,
"name": "Custom",
"share_mode": "unrestricted",
"uri_name": "Custom",
"url": "/hx/api/v3/indicator_categories/custom"
},
"create_actor": {
"_id": 1001,
"username": "test"
},
"create_text": null,
"created_by": "test",
"description": null,
"display_name": null,
"meta": null,
"name": "YYYXXXYYY",
"platforms": [
"win",
"osx",
"linux"
],
"signature": null,
"stats": {
"active_conditions": 0,
"alerted_agents": 0,
"source_alerts": 0
},
"update_actor": {
"_id": 1001,
"username": "test"
},
"uri_name": "YYYXXXYYY",
"url": "/hx/api/v3/indicators/custom/5d5cea45_2856_4338_8de8_7ef2b16f9511"
}
}
}
Human Readable Output
Indicator ‘YYYXXXYYY’ Alerts on
No entries.
fireeye-hx-append-conditions
Add conditions to an indicator. Conditions can be MD5, hash values, domain names and IP addresses.
Base Command
fireeye-hx-append-conditions
Input
| Argument Name | Description | Required |
|---|---|---|
| category | The indicator category. Use the uri_category value. |
Required |
| name | The name of the indicator. Use the uri_name value. |
Required |
| condition | A list of conditions to add. The list can include a list of IPv4 addresses, MD5 files, and domain names. For example, example.netexample.orgexample.lol. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-append-conditions category=Custom name=YYYXXXYYY condition=example.com
Context Example
{
"FireEyeHX": {
"Conditions": {
"details": [],
"message": "OK",
"route": "/hx/api/v3/indicators/category/indicator/conditions"
}
}
}
Human Readable Output
The conditions were added successfully
Category Conditions Name Custom example.com YYYXXXYYY
fireeye-hx-search-delete
Deletes the search by ID.
Base Command
fireeye-hx-search-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| searchId | The search ID. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-search-delete searchId=142
Human Readable Output
Results
Search Id 142: Deleted successfully
fireeye-hx-delete-file-acquisition
Deletes the file acquisition by ID.
Base Command
fireeye-hx-delete-file-acquisition
Input
| Argument Name | Description | Required |
|---|---|---|
| acquisitionId | The acquisition ID. | Required |
Context Output
There is no context output for this command.
fireeye-hx-approve-containment
Approves pending containment requests made by other components or users. The required permission is api_admin role.
Base Command
fireeye-hx-approve-containment
Input
| Argument Name | Description | Required |
|---|---|---|
| agentId | The Agent ID - this argument is required. | Required |
Context Output
There is no context output for this command.
fireeye-hx-assign-host-set-policy
Inserts a new host set policy on your Endpoint Security server.
Base Command
fireeye-hx-assign-host-set-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| hostSetId | The Host Set ID - this argument is required. | Required |
| policyId | The Policy ID - this argument is required. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-assign-host-set-policy hostSetId=1005 policyId=YYYXXXYYY
Human Readable Output
This hostset may already be included in this policy
fireeye-hx-get-data-acquisition
Collects artifacts from the system disk and memory for the given acquisition ID (the data is fetched as a MANS file).
Base Command
fireeye-hx-get-data-acquisition
Input
| Argument Name | Description | Required |
|---|---|---|
| acquisitionId | The acquisition unique ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Acquisitions.Data._id | string | The unique ID of the acquisition. |
| FireEyeHX.Acquisitions.Data.state | string | The state of the acquisition. |
| FireEyeHX.Acquisitions.Data.md5 | string | The MD5 of the file. |
| FireEyeHX.Acquisitions.Data.host._id | string | The ID of the agent. |
| FireEyeHX.Acquisitions.Data.finish_time | string | The time when the acquisition finished. |
| FireEyeHX.Acquisitions.Data.host.hostname | string | The hostname. |
| FireEyeHX.Acquisitions.Data.instance | date | The FireEye HX instance. |
Command example
!fireeye-hx-get-data-acquisition acquisitionId=102
Context Example
{
"File": {
"EntryID": "9ZoPJQJX9vtCa9NueiEpuj@cb52b293-6977-4d1b-8326-216bf1b32052",
"Extension": "mans",
"Info": "mans",
"MD5": "fedf0fbaf4811afd9602c22b29ebed4a",
"Name": "102_agent_YYYXXXYYY_data.mans",
"SHA1": "c83819759775fe7cb1fcfaf41a8d452f69caefc7",
"SHA256": "e92aaabe1e6dab564f421e3785dc46bacfe096b154acd042386e9f606a9e0b7e",
"SHA512": "9b4be59a5fb8dcb1832ef5eb6a4c587ac7da117b660f451b0b0414e0cf01d9a6208f605703f982486185be538e3869e821b0d8546bbbb264ac5268302a11fbd4",
"SSDeep": "393216:eijalomh9coY88Wy3cHnMcfrYECADR0E19dk:ea0jXY88dMHnv8uDL19dk",
"Size": 15678868,
"Type": "Zip archive data, at least v2.0 to extract"
},
"FireEyeHX": {
"Acquisitions": {
"Data": {
"_id": 102,
"_revision": "20220223084821573006597283",
"comment": null,
"download": "/hx/api/v3/acqs/live/102.mans",
"error_message": "The triage completed with issues.",
"external_id": null,
"finish_time": "2022-02-23T08:48:21.572Z",
"host": {
"_id": "YYYXXXYYY",
"hostname": "XXX",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
},
"instance": "FireEyeHX v2_instance_1",
"md5": null,
"name": "osxDefaultScript",
"request_actor": {
"_id": 1001,
"username": "test"
},
"request_time": "2022-02-23T08:42:46.000Z",
"script": {
"_id": "7387b70dcf9c54334b2302daf6840ee10167a7e8",
"download": "/hx/api/v3/scripts/7387b70dcf9c54334b2302daf6840ee10167a7e8.json",
"url": "/hx/api/v3/scripts/7387b70dcf9c54334b2302daf6840ee10167a7e8"
},
"state": "COMPLETE",
"url": "/hx/api/v3/acqs/live/102",
"zip_file_size": "15678868",
"zip_passphrase": null
}
}
}
}
Human Readable Output
The triage completed with issues.
acquisition ID: 102
fireeye-hx-data-acquisition
Start a data acquisition process to gather artifacts from the system disk and memory (the data is fetched as mans file).
Base Command
fireeye-hx-data-acquisition
Input
| Argument Name | Description | Required |
|---|---|---|
| script | The acquisition script in JSON format. | Optional |
| scriptName | The script name. If the Acquisition script is specified, the script name must be specified as well. | Optional |
| defaultSystemScript | Select the host system, which uses the default script. Possible values are: osx, win, linux. | Optional |
| agentId | The agent ID. If the host name is not specified, the agent ID must be specified. | Optional |
| hostName | The host name. If the agent ID is not specified, the host name must be specified. | Optional |
| acquisition_id | This argument is deprecated. | Optional |
| polling | Whether to use Cortex XSOAR’s built-in polling to retrieve the result when ready. Possible values are: true, false. | Optional |
| interval_in_seconds | The interval in seconds between each poll. Default is 60. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Acquisitions.Data._id | Number | The unique ID of the acquisition. |
| FireEyeHX.Acquisitions.Data.state | String | The state of the acquisition. |
| FireEyeHX.Acquisitions.Data.md5 | String | The MD5 of the file. |
| FireEyeHX.Acquisitions.Data.finish_time | String | The time when the acquisition finished. |
| FireEyeHX.Acquisitions.Data.host._id | unknown | The ID of the agent. |
Command example
!fireeye-hx-data-acquisition hostName=XXX defaultSystemScript=osx
Human Readable Output
Acquisition request was successful
Acquisition ID: 104
fireeye-hx-get-alerts
Returns a list of alerts. Use the different arguments to filter the results returned.
Base Command
fireeye-hx-get-alerts
Input
| Argument Name | Description | Required |
|---|---|---|
| hasShareMode | Identifies which alerts result from indicators with the specified share mode. Possible values are: any, restricted, unrestricted. | Optional |
| resolution | Sorts the results by the specified field. Possible values are: active_threat, alert, block, partial_block. | Optional |
| agentId | Filter by the agent ID. | Optional |
| conditionId | Filter by condition ID. | Optional |
| eventAt | Filter by the event occurred time. ISO-8601 timestamp. | Optional |
| alertId | Filter by the alert ID. | Optional |
| matchedAt | Filter by the match detection time. ISO-8601 timestamp. | Optional |
| minId | Filter by returning only records with an AlertId field value greater than the minId value. | Optional |
| reportedAt | Filter by the reported time. ISO-8601 timestamp. | Optional |
| IOCsource | The source of the alert-indicator of compromise. Possible values are: yes. | Optional |
| EXDsource | The source of the alert - exploit detection. Possible values are: yes. | Optional |
| MALsource | The Source of the malware alert. Possible values are: yes. | Optional |
| limit | Limit the results returned. | Optional |
| sort | Sorts the results by the specified field in ascending order. Possible values are: agentId, conditionId, eventAt, alertId, matchedAt, id, reportedAt. | Optional |
| sortOrder | The sort order for the results. Possible values are: ascending, descending. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Alerts._id | Number | The ID of the FireEye alert. |
| FireEyeHX.Alerts.agent._id | Unknown | The ID of the FireEye agent. |
| FireEyeHX.Alerts.agent.containment_state | Unknown | The state of the agent containment. |
| FireEyeHX.Alerts.condition._id | String | The unique ID of the alert. |
| FireEyeHX.Alerts.event_at | String | The time when the event occurred. |
| FireEyeHX.Alerts.matched_at | String | The time when the event was matched. |
| FireEyeHX.Alerts.reported_at | String | The time when the event was reported. |
| FireEyeHX.Alerts.source | String | The source of the alert. |
| FireEyeHX.Alerts.matched_source_alerts._id | Unknown | The ID of the source alert. |
| FireEyeHX.Alerts.matched_source_alerts.appliance_id | Unknown | The ID of the appliance. |
| FireEyeHX.Alerts.matched_source_alerts.meta | Unknown | The source alert meta. |
| FireEyeHX.Alerts.matched_source_alerts.indicator_id | Unknown | The ID of the indicator. |
| FireEyeHX.Alerts.resolution | String | The alert resolution. |
| FireEyeHX.Alerts.event_type | String | The type of the event. |
Command example
!fireeye-hx-get-alerts limit=2 sort=alertId
Context Example
{
"File": [
{
"Extension": "exe",
"Name": "feyeqatest.exe",
"Path": "C:\\Users\\User\\Desktop\\feyeqatest.exe",
"md5": "95b16477988ff5097e57a08332cfdb3a"
},
{
"Extension": "exe",
"Name": "feyeqatest.exe",
"Path": "C:\\Users\\User\\Desktop\\\u37cb\\feyeqatest.exe",
"md5": null
}
],
"FireEyeHX": {
"Alerts": [
{
"_id": 7,
"agent": {
"_id": "YYYXXXYYY",
"containment_state": "normal",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
},
"appliance": {
"_id": "86285DC29A17"
},
"condition": {
"_id": "YYYXXXYYY",
"url": "/hx/api/v3/conditions/YYYXXXYYY"
},
"decorator_statuses": [],
"decorators": [],
"event_at": "2022-01-24T10:36:33.171Z",
"event_id": 59105127,
"event_type": "fileWriteEvent",
"event_values": {
"fileWriteEvent/closed": 1,
"fileWriteEvent/drive": "C",
"fileWriteEvent/eventReason": "Unknown",
"fileWriteEvent/fileExtension": "exe",
"fileWriteEvent/fileName": "feyeqatest.exe",
"fileWriteEvent/filePath": "Users\\User\\Desktop",
"fileWriteEvent/fullPath": "C:\\Users\\User\\Desktop\\feyeqatest.exe",
"fileWriteEvent/md5": "95b16477988ff5097e57a08332cfdb3a",
"fileWriteEvent/numBytesSeenWritten": 0,
"fileWriteEvent/openDuration": 0,
"fileWriteEvent/openTime": "2022-01-24T10:36:33.171Z",
"fileWriteEvent/parentPid": 5560,
"fileWriteEvent/parentProcessPath": "C:\\Windows\\System32\\userinit.exe",
"fileWriteEvent/pid": 5604,
"fileWriteEvent/process": "explorer.exe",
"fileWriteEvent/processPath": "C:\\Windows",
"fileWriteEvent/size": 70,
"fileWriteEvent/timestamp": "2022-01-24T10:36:33.171Z",
"fileWriteEvent/username": "XXX\\User",
"fileWriteEvent/writes": 0
},
"indicator": {
"_id": "2b4753b0-9972-477e-ba16-1a7c29058cee",
"category": "mandiant_unrestricted",
"display_name": "FIREEYE END2END TEST",
"name": "FIREEYE END2END TEST",
"signature": null,
"uri_name": "2b4753b0-9972-477e-ba16-1a7c29058cee",
"url": "/hx/api/v3/indicators/mandiant_unrestricted/2b4753b0_9972_477e_ba16_1a7c29058cee"
},
"is_false_positive": false,
"matched_at": "2022-01-24T10:37:33.000Z",
"matched_source_alerts": [],
"md5values": [
"95b16477988ff5097e57a08332cfdb3a"
],
"multiple_match": null,
"reported_at": "2022-01-24T10:37:51.306Z",
"resolution": "ALERT",
"source": "IOC",
"subtype": null,
"url": "/hx/api/v3/alerts/7"
},
{
"_id": 8,
"agent": {
"_id": "YYYXXXYYY",
"containment_state": "normal",
"url": "/hx/api/v3/hosts/YYYXXXYYY"
},
"appliance": {
"_id": "86285DC29A17"
},
"condition": {
"_id": "YYYXXXYYY",
"url": "/hx/api/v3/conditions/YYYXXXYYY"
},
"decorator_statuses": [],
"decorators": [],
"event_at": "2022-01-25T10:25:19.665Z",
"event_id": 59302205,
"event_type": "fileWriteEvent",
"event_values": {
"fileWriteEvent/closed": 1,
"fileWriteEvent/drive": "C",
"fileWriteEvent/eventReason": "Unknown",
"fileWriteEvent/fileExtension": "exe",
"fileWriteEvent/fileName": "feyeqatest.exe",
"fileWriteEvent/filePath": "Users\\User\\Desktop\\\u37cb",
"fileWriteEvent/fullPath": "C:\\Users\\User\\Desktop\\\u37cb\\feyeqatest.exe",
"fileWriteEvent/numBytesSeenWritten": 0,
"fileWriteEvent/openDuration": 0,
"fileWriteEvent/openTime": "2022-01-25T10:25:19.665Z",
"fileWriteEvent/parentPid": 5560,
"fileWriteEvent/parentProcessPath": "C:\\Windows\\System32\\userinit.exe",
"fileWriteEvent/pid": 5604,
"fileWriteEvent/process": "explorer.exe",
"fileWriteEvent/processPath": "C:\\Windows",
"fileWriteEvent/size": 70,
"fileWriteEvent/timestamp": "2022-01-25T10:25:19.665Z",
"fileWriteEvent/username": "XXX\\User",
"fileWriteEvent/writes": 0
},
"indicator": {
"_id": "2b4753b0-9972-477e-ba16-1a7c29058cee",
"category": "mandiant_unrestricted",
"display_name": "FIREEYE END2END TEST",
"name": "FIREEYE END2END TEST",
"signature": null,
"uri_name": "2b4753b0-9972-477e-ba16-1a7c29058cee",
"url": "/hx/api/v3/indicators/mandiant_unrestricted/2b4753b0_9972_477e_ba16_1a7c29058cee"
},
"is_false_positive": false,
"matched_at": "2022-01-25T10:25:34.000Z",
"matched_source_alerts": [],
"md5values": [],
"multiple_match": null,
"reported_at": "2022-01-25T10:25:44.011Z",
"resolution": "ALERT",
"source": "IOC",
"subtype": null,
"url": "/hx/api/v3/alerts/8"
}
]
}
}
Human Readable Output
FireEye HX Get Alerts
Alert ID Reported Event Type Agent ID 7 2022-01-24T10:37:51.306Z fileWriteEvent YYYXXXYYY 8 2022-01-25T10:25:44.011Z fileWriteEvent YYYXXXYYY
fireeye-hx-file-acquisition
Acquires a specific file as a password protected zip file. The password for unlocking the zip file is ‘unzip-me’.
Base Command
fireeye-hx-file-acquisition
Input
| Argument Name | Description | Required |
|---|---|---|
| acquisition_id | The acquisition ID. This argument is deprecated. | Optional |
| fileName | The file name. | Required |
| filePath | The file path. | Required |
| acquireUsing | Whether to acquire the file using the API or RAW. By default, the RAW file will be acquired. Use the API option when file is encrypted. Possible values are: API, RAW. | Optional |
| agentId | The agent ID associated with the host that holds the file. If the host name is not specified, the agentId must be specified. | Optional |
| hostName | The host that holds the file. If the agentId is not specified, hostName must be specified. | Optional |
| polling | Whether to use Cortex XSOAR’s built-in polling to retrieve the result when ready. Possible values are: true, false. | Optional |
| interval_in_seconds | The interval in seconds between each poll. Default is 60. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Acquisitions.Files._id | Number | The acquisition unique ID. |
| FireEyeHX.Acquisitions.Files.state | String | The acquisition state. |
| FireEyeHX.Acquisitions.Files.md5 | String | The MD5 of the file. |
| FireEyeHX.Acquisitions.Files.req_filename | String | The name of the file. |
| FireEyeHX.Acquisitions.Files.req_path | String | The path of the file. |
| FireEyeHX.Acquisitions.Files.host._id | String | The ID of the FireEye HX agent. |
fireeye-hx-create-indicator
Create a new indicator.
Base Command
fireeye-hx-create-indicator
Input
| Argument Name | Description | Required |
|---|---|---|
| category | The indicator category. | Required |
| display_name | Display name for the indicator. | Optional |
| description | Description for the indicator. | Optional |
| platforms | The platform for the indicator. If not selected, the indicator will be created for all platforms. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Indicators.active_since | date | The date the indicator became active. |
| FireEyeHX.Indicators.meta | string | The meta data for new indicator. |
| FireEyeHX.Indicators.display_name | string | The display name of the indicator. |
| FireEyeHX.Indicators.name | string | The indicator name, as displayed in the UI. |
| FireEyeHX.Indicators.created_by | string | The “Created By” field, as displayed in UI |
| FireEyeHX.Indicators.url | string | The data URL. |
| FireEyeHX.Indicators.create_text | Unknown | The indicator created text. |
| FireEyeHX.Indicators.platforms | string | The list of operating systems. |
| FireEyeHX.Indicators.create_actor._id | number | The ID of the actor. |
| FireEyeHX.Indicators.create_actor.username | string | The user name of the actor. |
| FireEyeHX.Indicators.signature | string | The signature of the indicator. |
| FireEyeHX.Indicators._revision | string | The indicator revision. |
| FireEyeHX.Indicators._id | string | The ID of the FireEye unique indicator. |
| FireEyeHX.Indicator.description | string | The description of the indicator. |
| FireEyeHX.Indicators.category._id | number | The ID of the category. |
| FireEyeHX.Indicators.category.name | string | The name of the category. |
| FireEyeHX.Indicators.category.share_mode | string | The share mode of the category. |
| FireEyeHX.Indicators.category.uri_name | string | The URI name of the category. |
| FireEyeHX.Indicators.category.url | string | The URL of the category. |
| FireEyeHX.Indicators.uri_name | string | The URI name of the indicator. |
| FireEyeHX.Indicators.stats.active_conditions | number | The active conditions of the indicator. |
| FireEyeHX.Indicators.stats.alerted_agents | number | The total number of agents with HX alerts associated with this indicator. |
| FireEyeHX.Indicators.stats.source_alerts | number | The total number of source alerts associated with this indicator. |
| FireEyeHX.Indicators.update_actor._id | number | The ID of the updated actor. |
| FireEyeHX.Indicators.update_actor.username | string | The updated name of the actor. |
Command example
!fireeye-hx-create-indicator category=Custom
Context Example
{
"FireEyeHX": {
"Indicators": {
"_id": "YYYXXXYYY",
"_revision": "20220223091809012244597537",
"active_since": "2022-02-23T09:18:09.012Z",
"category": {
"_id": 2,
"name": "Custom",
"share_mode": "unrestricted",
"uri_name": "Custom",
"url": "/hx/api/v3/indicator_categories/custom"
},
"create_actor": {
"_id": 1001,
"username": "test"
},
"create_text": null,
"created_by": "test",
"description": null,
"display_name": null,
"meta": null,
"name": "YYYXXXYYY",
"platforms": [
"win",
"osx",
"linux"
],
"signature": null,
"stats": {
"active_conditions": 0,
"alerted_agents": 0,
"source_alerts": 0
},
"update_actor": {
"_id": 1001,
"username": "test"
},
"uri_name": "YYYXXXYYY",
"url": "/hx/api/v3/indicators/custom/37a97ac2_35e9_40ad_a108_6802d5d82890"
}
}
}
Human Readable Output
FireEye HX New Indicator created successfully
ID YYYXXXYYY
fireeye-hx-delete-host-set-policy
Deletes a Host Set policy.
Base Command
fireeye-hx-delete-host-set-policy
Input
| Argument Name | Description | Required |
|---|---|---|
| hostSetId | The host set ID. | Required |
| policyId | The policy ID. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-delete-host-set-policy hostSetId=1005 policyId=YYYXXXYYY
Human Readable Output
Success
fireeye-hx-delete-data-acquisition
Deletes data acquisition.
Base Command
fireeye-hx-delete-data-acquisition
Input
| Argument Name | Description | Required |
|---|---|---|
| acquisitionId | The acquisition ID. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-delete-data-acquisition acquisitionId=102
Human Readable Output
data acquisition 102 deleted successfully
fireeye-hx-delete-indicator-condition
Delete an indicator condition.
Base Command
fireeye-hx-delete-indicator-condition
Input
| Argument Name | Description | Required |
|---|---|---|
| category | The indicator category. | Required |
| indicator_name | The name of the indicator. Use the uri_name value. |
Required |
| type | The condition type. Possible values are: presence, execution. | Required |
| condition_id | The condition ID, which is part of the response when you request a list of all conditions known to the HX Series appliance. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-delete-indicator-condition category=Custom condition_id=myFIAYoWKoWqaaYQ7CxHVA== indicator_name=7f49e4c6-14d5-4b06-8d17-843fd17f79de type=execution
Human Readable Output
Successfully deleted condition myFIAYoWKoWqaaYQ7CxHVA== (execution) of indicator 7f49e4c6-14d5-4b06-8d17-843fd17f79de (Custom)
fireeye-hx-list-indicator-category
Lists the indicator categories.
Base Command
fireeye-hx-list-indicator-category
Input
| Argument Name | Description | Required |
|---|---|---|
| search | Performs a search of indicator categories. Searchable values are based on the name, display_name, retention_policy, ui_edit_policy, ui_signature_enabled, ui_source_alerts_enabled. | Optional |
| name | Filter for indicator categories with the specified name. | Optional |
| display_name | Filter for indicator categories with given display name. | Optional |
| retention_policy | The retention policy. Possible values are: manual, auto, intel. | Optional |
| ui_edit_policy | The UI edit policy. Possible values are: full, edit_delete, delete, read_only. | Optional |
| ui_signature_enabled | Whether to enable the UI signature. Possible values are: true, false. | Optional |
| ui_source_alerts_enabled | Whether to enable UI source alerts. Possible values are: true, false. | Optional |
| share_mode | Share mode. Possible values are: restricted, unrestricted, silent, visible, any. | Optional |
| limit | The maximum number of results to return. Default is 50. | Optional |
| offset | Result offset. Default is 0. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.IndicatorCategory.uri_name | number | The policy ID of the indicator category. |
| FireEyeHX.IndicatorCategory.name | string | The name of the indicator category. |
| FireEyeHX.IndicatorCategory._revision | number | The revision of the indicator category. |
| FireEyeHX.IndicatorCategory.display_name | string | The display name of the indicator category. |
| FireEyeHX.IndicatorCategory.retention_policy | string | The retention policy of the indicator category. |
| FireEyeHX.IndicatorCategory.ui_edit_policy | string | The UI edit policy of the indicator category. |
| FireEyeHX.IndicatorCategory.ui_signature_enabled | boolean | Whether the UI signature is enabled. |
| FireEyeHX.IndicatorCategory.ui_source_alerts_enabled | boolean | Whether the UI source alerts is enabled. |
| FireEyeHX.IndicatorCategory.share_mode | string | The share mode of the indicator category. |
Command example
!fireeye-hx-list-indicator-category search=fireEye
Context Example
{
"FireEyeHX": {
"IndicatorCategory": [
{
"_id": 4,
"_revision": "20200423145028596495100030",
"display_name": null,
"name": "FireEye",
"retention_policy": "auto",
"share_mode": "unrestricted",
"ui_edit_policy": "delete",
"ui_signature_enabled": true,
"ui_source_alerts_enabled": true,
"uri_name": "FireEye",
"url": "/hx/api/v3/indicator_categories/fireeye"
},
{
"_id": 8,
"_revision": "20200423145028596495100038",
"display_name": "FireEye Restricted",
"name": "FireEye Restricted",
"retention_policy": "auto",
"share_mode": "restricted",
"ui_edit_policy": "delete",
"ui_signature_enabled": true,
"ui_source_alerts_enabled": true,
"uri_name": "fireeye_restricted",
"url": "/hx/api/v3/indicator_categories/fireeye_restricted"
},
{
"_id": 5,
"_revision": "20200423145028596495100032",
"display_name": null,
"name": "FireEye-CMS",
"retention_policy": "auto",
"share_mode": "unrestricted",
"ui_edit_policy": "delete",
"ui_signature_enabled": true,
"ui_source_alerts_enabled": true,
"uri_name": "FireEye-CMS",
"url": "/hx/api/v3/indicator_categories/fireeye_cms"
}
]
}
}
Human Readable Output
3 Indicator categories found
Name Policy ID FireEye 4 FireEye Restricted 8 FireEye-CMS 5
fireeye-hx-delete-indicator
Delete an indicator.
Base Command
fireeye-hx-delete-indicator
Input
| Argument Name | Description | Required |
|---|---|---|
| category | The category name. | Required |
| indicator_name | The name of the indicator. Use the uri_name value. |
Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-delete-indicator category=Custom indicator_name=7f49e4c6-14d5-4b06-8d17-843fd17f79de
Human Readable Output
Successfully deleted indicator 7f49e4c6-14d5-4b06-8d17-843fd17f79de from the Custom category
fireeye-hx-create-host-set-static
Creates static host set.
Base Command
fireeye-hx-create-host-set-static
Input
| Argument Name | Description | Required |
|---|---|---|
| host_set_name | The host set name. | Required |
| hosts_ids | The hosts IDs to add to the host set. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.HostSets._id | String | The host set ID. |
| FireEyeHX.HostSets.url | String | URI to retrieve data for this record. |
| FireEyeHX.HostSets.name | String | The host set name. |
| FireEyeHX.HostSets._revision | String | Timestamp of last update. Used for preventing updates with obsolete data. If _revision in the request body does not match_revision in the database, the update will fail. |
| FireEyeHX.HostSets.deleted | Boolean | Was the host set deleted. |
Command example
!fireeye-hx-create-host-set-static host_set_name=demisto_test hosts_ids=Hqb2ns3oui1fpzg0BxI1Ch
Human Readable Output
Static Host Set demisto_test with id 1001 was created successfully.
fireeye-hx-update-host-set-static
Updates a static host set.
Base Command
fireeye-hx-update-host-set-static
Input
| Argument Name | Description | Required |
|---|---|---|
| host_set_id | The host set ID. | Required |
| host_set_name | The host set name. | Required |
| add_host_ids | The host sets IDs to add. | Optional |
| remove_host_ids | The host set IDs to remove. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.HostSets._id | String | The host set ID. |
| FireEyeHX.HostSets.url | String | URI to retrieve data for this record. |
| FireEyeHX.HostSets.name | String | The host set name. |
| FireEyeHX.HostSets._revision | String | Timestamp of last update. Used for preventing updates with obsolete data. If _revision in the request body does not match_revision in the database, the update will fail. |
| FireEyeHX.HostSets.deleted | Boolean | Was the host set deleted. |
Command example
!fireeye-hx-update-host-set-static host_set_name=demisto_test host_set_id=1036 add_host_ids=GfLI00Q4zpidezw9I11rV6 remove_host_ids=Hqb2ns3oui1fpzg0BxI1Ch
Human Readable Output
Static Host Set demisto_test was updated successfully.
fireeye-hx-create-host-set-dynamic
Creates dynamic host set.
Base Command
fireeye-hx-create-host-set-dynamic
Input
| Argument Name | Description | Required |
|---|---|---|
| host_set_name | The host set name. | Required |
| query | Free text query. Cannot be used with the other query arguments. | Optional |
| query_key | The query key. Must be provided with the query_value and query_operator. Possible values are: domain, product_name, patch_level, timezone, os_bitness, cloud_provider, app_version, hostname, server_time, gmt_offset_seconds, primary-ip_address, normalized_app_version, litmus_script_id, app_config_hash, platform. | Optional |
| query_value | The query value. Must be provided with the query_key and query_operator. | Optional |
| query_operator | The query operator. Must be provided with the query_key and query_value. Possible values are: eq, gt, lt, lte, gte, exists, cidr. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.HostSets._id | String | The host set ID. |
| FireEyeHX.HostSets.url | String | URI to retrieve data for this record. |
| FireEyeHX.HostSets.name | String | The host set name. |
| FireEyeHX.HostSets._revision | String | Timestamp of last update. Used for preventing updates with obsolete data. If _revision in the request body does not match_revision in the database, the update will fail. |
| FireEyeHX.HostSets.deleted | Boolean | Was the host set deleted. |
Command example
!fireeye-hx-create-host-set-dynamic host_set_name=demisto_test query_key=Bitlevel query_operator=eq query_value=64-bit
!fireeye-hx-update-host-set-dynamic host_set_name=MoreTestyay query=`{"key": "AgentVersion","value": "31.28.17","operator": "gte"}`
Human Readable Output
Dynamic Host Set demisto_test with id 1068 was created successfully.
fireeye-hx-update-host-set-dynamic
Updates dynamic host set.
Base Command
fireeye-hx-update-host-set-dynamic
Input
| Argument Name | Description | Required |
|---|---|---|
| host_set_name | The host set name. | Required |
| host_set_id | The host set ID. | Required |
| query | Free text query. Cannot be used with the other query arguments. | Optional |
| query_key | The query key. Must be provided with the query_value and query_operator. Possible values are: domain, product_name, patch_level, timezone, os_bitness, cloud_provider, app_version, hostname, server_time, gmt_offset_seconds, primary-ip_address, normalized_app_version, litmus_script_id, app_config_hash, platform. | Optional |
| query_value | The query value. Must be provided with the query_key and query_operator. | Optional |
| query_operator | The query operator. Must be provided with the query_value and query_key. Possible values are: eq, gt, lt, lte, gte, exists, cidr. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.HostSets._id | String | The host set ID. |
| FireEyeHX.HostSets.url | String | URI to retrieve data for this record. |
| FireEyeHX.HostSets.name | String | The host set name. |
| FireEyeHX.HostSets._revision | String | Timestamp of last update. Used for preventing updates with obsolete data. If _revision in the request body does not match_revision in the database, the update will fail. |
| FireEyeHX.HostSets.deleted | Boolean | Was the host set deleted. |
Command example
!fireeye-hx-update-host-set-dynamic host_set_name=demisto_test query_key=Bitlevel query_operator=eq query_value=64-bit host_set_id=1061
!fireeye-hx-update-host-set-dynamic host_set_name=MoreTestyay query=`{"key": "AgentVersion","value": "31.28.17","operator": "gte"}` host_set_id=1061
Human Readable Output
Dynamic Host Set Demisto_test was updated successfully.
fireeye-hx-delete-host-set
Deletes a host set.
Base Command
fireeye-hx-delete-host-set
Input
| Argument Name | Description | Required |
|---|---|---|
| host_set_id | The host set ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.HostSets._id | String | The host set ID. |
| FireEyeHX.HostSets.deleted | Boolean | Was the host set deleted. |
Command example
!fireeye-hx-delete-host-set host_set_id=1001
Human Readable Output
Host set 1001 was deleted successfully.
fireeye-hx-triage-acquisition-delete
Deletes a specified triage request.
Base Command
fireeye-hx-triage-acquisition-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| acquisitionId | The acquisition ID. | Required |
Context Output
There is no context output for this command.
Command example
!fireeye-hx-triage-acquisition-delete acquisitionId=12345
Human Readable Output
Triage acquisition 12345 deleted successfully
fireeye-hx-triage-acquisition-package-get
Collects triage package for the given acquisition ID (the data is fetched as a MANS file).
Base Command
fireeye-hx-triage-acquisition-package-get
Input
| Argument Name | Description | Required |
|---|---|---|
| acquisitionId | The acquisition ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Acquisitions.Triage._id | String | The triage ID. |
| FireEyeHX.Acquisitions.Triage.host._id | String | The host ID. |
| FireEyeHX.Acquisitions.Triage.host.hostname | String | The hostname. |
| FireEyeHX.Acquisitions.Triage.state | String | The acquisition state. |
Command example
!fireeye-hx-triage-acquisition-package-get acquisitionId=12345
Human Readable Output
The triage completed with issues.
Triage acquisition ID: 12345
fireeye-hx-triage-acquisition-get
Gets information about a specified triage acquisition.
Base Command
fireeye-hx-triage-acquisition-get
Input
| Argument Name | Description | Required |
|---|---|---|
| acquisitionId | The acquisition ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Acquisitions.Triage._id | String | The triage ID. |
| FireEyeHX.Acquisitions.Triage.host._id | String | The host ID. |
| FireEyeHX.Acquisitions.Triage.host.hostname | String | The hostname. |
| FireEyeHX.Acquisitions.Triage.state | String | The acquisition state. |
Command example
!fireeye-hx-triage-acquisition-get acquisitionId=12345
Human Readable Output
host _id: SomeHostID
url: /hx/api/v3/hosts/SomeHostID
hostname: SomeHostname_id 12345 state COMPLETE request_time 2026-03-09T15:31:49.000Z finish_time 2026-03-09T15:37:32.836Z instance FireEyeHX v2_instance_1
fireeye-hx-triage-acquisition-start
Starts a new triage request for a host.
Base Command
fireeye-hx-triage-acquisition-start
Input
| Argument Name | Description | Required |
|---|---|---|
| agentId | The agent ID. If the agent ID is not specified, the hostName must be specified. | Optional |
| hostName | The host name. If the hostName is not specified, the agent ID must be specified. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Acquisitions.Triage._id | String | The triage ID. |
| FireEyeHX.Acquisitions.Triage.host._id | String | The host ID. |
| FireEyeHX.Acquisitions.Triage.host.hostname | String | The hostname. |
| FireEyeHX.Acquisitions.Triage.state | String | The acquisition state. |
Command example
!fireeye-hx-triage-acquisition-start agentId=SomeAgentID
Human Readable Output
Triage Acquisition ID: 31032 on Instance: FireEyeHX v2_instance_1 created.
fireeye-hx-host-acquisitions-list
Gets a list of all acquisitions for a host.
Base Command
fireeye-hx-host-acquisitions-list
Input
| Argument Name | Description | Required |
|---|---|---|
| agentId | The agent ID. If the agent ID is not specified, the hostName must be specified. | Optional |
| hostName | The host name. If the hostName is not specified, the agent ID must be specified. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| FireEyeHX.Host.Acquisitions.All._id | String | The acquisition ID. |
| FireEyeHX.Host.Acquisitions.All.state | String | The state of the acquisition. |
| FireEyeHX.Host.Acquisitions.All.acq_type | String | The type of acquisition. |
| FireEyeHX.Host.Acquisitions.All.request_time | Date | The requested date of the acquisition. |
Command example
!fireeye-hx-host-acquisitions-list agentId=SomeAgentID
Human Readable Output
_id acq_type request_time state 12345 triage 2026-03-09T15:31:49.000Z COMPLETE 12328 triage 2026-02-04T21:40:44.311Z COMPLETE
Configuration parameters
server— Server URL (e.g., https://192.168.0.1:3000) (required)userName— User Name (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsisFetch— Fetch incidentsincidentType— Incident typemax_fetch— Fetch limitfirst_fetch— First fetch timestamp (<number> <time unit>, e.g., 12 hours, 3 days)incidentFetchInterval— Incidents Fetch Interval
Commands (42)
-
fireeye-hx-append-conditionsAdd conditions to an indicator. Conditions can be MD5, hash values, domain names, and IP addresses.
-
fireeye-hx-approve-containmentApproves pending containment requests made by other components or users. The required permission is api_admin role.
-
fireeye-hx-assign-host-set-policyInserts a new host set policy on your Endpoint Security server.
-
fireeye-hx-cancel-containmentReleases a specific host from containment.
-
fireeye-hx-create-host-set-dynamicCreates a dynamic host set. To use this command you must have admin permissions.
-
fireeye-hx-create-host-set-staticCreates a static host set. To use this command you must have admin permissions.
-
fireeye-hx-create-indicatorCreate a new indicator.
-
fireeye-hx-data-acquisitionStart a data acquisition process to gather artifacts from the system disk and memory. The data is fetched as a MANS file.
-
fireeye-hx-delete-data-acquisitionDeletes data acquisition.
-
fireeye-hx-delete-file-acquisitionDeletes the file acquisition by ID.
-
fireeye-hx-delete-host-setDeletes a host set. To use this command you must have admin permissions.
-
fireeye-hx-delete-host-set-policyDeletes a Host Set policy.
-
fireeye-hx-delete-indicatorDelete an indicator.
-
fireeye-hx-delete-indicator-conditionDelete an indicator condition.
-
fireeye-hx-file-acquisitionAcquires a specific file as a password protected zip file. The password for unlocking the zip file is 'unzip-me'.
-
fireeye-hx-get-alertGet details of a specific alert.
-
fireeye-hx-get-alertsReturns a list of alerts. Use the different arguments to filter the results returned.
-
fireeye-hx-get-all-hosts-informationReturns information on all hosts.
-
fireeye-hx-get-data-acquisitionCollects artifacts from the system disk and memory for the given acquisition ID. The data is fetched as a MANS file.
-
fireeye-hx-get-host-informationReturns information on a host associated with an agent.
-
fireeye-hx-get-host-set-informationReturns a list of all host sets known to your HX Series appliance.
-
fireeye-hx-get-indicatorGet details of a specific indicator.
-
fireeye-hx-get-indicatorsGet a list of indicators.
-
fireeye-hx-host-acquisitions-listGets all acquisitions for a host
-
fireeye-hx-host-containmentApplies containment for a specific host, so that it no longer has access to other systems. If the user does not have the necessary permissions, the command will not approve the request. The permission required to approve the request is api_admin role.
-
fireeye-hx-initiate-data-acquisitionInitiates a data acquisition process to collect artifacts from the system disk and memory.
-
fireeye-hx-list-containmentFetches all containment states across known hosts.
-
fireeye-hx-list-host-set-policyReturns a list of all policies for all host sets.
-
fireeye-hx-list-indicator-categoryLists the indicator categories.
-
fireeye-hx-list-policyReturns a list of all policies.
-
fireeye-hx-searchSearches endpoints to check all hosts or a subset of hosts for a specific file or indicator.
-
fireeye-hx-search-deleteDeletes the search by ID.
-
fireeye-hx-search-listFetches all enterprise searches.
-
fireeye-hx-search-result-getFetches the results for a specific enterprise search.
-
fireeye-hx-search-stopStops a specific running search.
-
fireeye-hx-suppress-alertSuppresses an alert by ID.
-
fireeye-hx-triage-acquisition-deleteDeletes a triage acquisition.
-
fireeye-hx-triage-acquisition-getGets information about a specified triage acquisition.
-
fireeye-hx-triage-acquisition-package-getGets the triage acquisition package for the given acquisition ID.
-
fireeye-hx-triage-acquisition-startStarts a triage acquisition
-
fireeye-hx-update-host-set-dynamicUpdates dynamic host set. To use this command you must have admin permissions.
-
fireeye-hx-update-host-set-staticUpdates a static host set. To use this command you must have admin permissions.
import urllib.parse from json import JSONDecodeError from re import Pattern import urllib3 from CommonServerPython import * # Disable insecure warnings urllib3.disable_warnings() # pylint: disable=no-member """ CONSTANTS """ DATE_FORMAT = "%Y-%m-%dT%H:%M:%S" # ISO8601 format with UTC, default in XSOAR STANDARD_INVESTIGATIVE_DETAILS_OSX = { # pragma: no cover "commands": [ {"name": "sysinfo"}, {"name": "disks"}, {"name": "volumes"}, {"name": "useraccounts"}, {"name": "groups"}, { "name": "files-api", "parameters": [ {"name": "Path", "value": "/"}, {"name": "Regex", "value": "^(?:Applications|Library|System|User|bin|cores|opt|private|sbin|usr)+"}, {"name": "Include Remote Locations", "value": False}, {"name": "Depth", "value": -1}, {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Verify Digital Signatures", "value": False}, {"name": "AND Operator", "value": False}, {"name": "Include Files", "value": True}, {"name": "Include Directories", "value": True}, {"name": "Preserve Times", "value": False}, ], }, { "name": "persistence", "parameters": [ {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Preserve Times", "value": False}, {"name": "Verify Digital Signatures", "value": False}, ], }, { "name": "tasks", "parameters": [ {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Verify Digital Signatures", "value": True}, {"name": "Preserve Times", "value": False}, ], }, {"name": "processes-api"}, { "name": "urlhistory", "parameters": [ {"name": "TargetBrowser", "value": "Chrome"}, {"name": "TargetBrowser", "value": "Firefox"}, {"name": "TargetBrowser", "value": "Safari"}, ], }, {"name": "quarantine-events"}, {"name": "ports"}, { "name": "services", "parameters": [ {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Verify Digital Signatures", "value": True}, {"name": "Preserve Times", "value": False}, ], }, {"name": "stateagentinspector", "parameters": [{"name": "eventTypes", "value": []}]}, {"name": "syslog"}, ] } STANDARD_INVESTIGATIVE_DETAILS_LINUX = { "commands": [ {"name": "sysinfo"}, { "name": "files-api", "parameters": [ {"name": "Path", "value": "/"}, {"name": "Regex", "value": "^(?:usr|lib|lib64|opt|home|sbin|bin|etc|root)+"}, {"name": "Include Remote Locations", "value": False}, {"name": "Depth", "value": -1}, {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "AND Operator", "value": False}, {"name": "Include Files", "value": True}, {"name": "Include Directories", "value": True}, {"name": "Preserve Times", "value": False}, ], }, {"name": "processes-api"}, {"name": "ports"}, {"name": "shell-history", "parameters": [{"name": "ShellList", "value": ["bash", "zsh", "ksh93"]}]}, ] } STANDARD_INVESTIGATIVE_DETAILS_WIN = { "commands": [ {"name": "sysinfo"}, {"name": "disks", "parameters": [{"name": "Prevent Hibernation", "value": True}]}, {"name": "volumes", "parameters": [{"name": "Prevent Hibernation", "value": True}]}, {"name": "useraccounts", "parameters": [{"name": "Prevent Hibernation", "value": True}]}, {"name": "prefetch", "parameters": [{"name": "Prevent Hibernation", "value": True}]}, { "name": "files-raw", "parameters": [ {"name": "Prevent Hibernation", "value": True}, {"name": "Active Files", "value": True}, {"name": "Deleted Files", "value": True}, {"name": "Parse NTFS INDX Buffers", "value": True}, {"name": "Path", "value": "%systemdrive%"}, {"name": "Depth", "value": -1}, {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Analyze Entropy", "value": False}, {"name": "Enumerate Imports", "value": False}, {"name": "Enumerate Exports", "value": False}, {"name": "Analyze File Anomalies", "value": False}, {"name": "Verify Digital Signatures", "value": False}, {"name": "Strings", "value": False}, {"name": "AND Operator", "value": False}, {"name": "Include Files", "value": True}, {"name": "Include Directories", "value": True}, {"name": "Get Resources", "value": False}, {"name": "Get Resource Data", "value": False}, {"name": "Get Version Info", "value": False}, ], }, { "name": "persistence", "parameters": [ {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Preserve Times", "value": False}, {"name": "Enumerate Imports", "value": False}, {"name": "Enumerate Exports", "value": False}, {"name": "Verify Digital Signatures", "value": True}, {"name": "Analyze Entropy", "value": False}, {"name": "Analyze File Anomalies", "value": False}, {"name": "Get Resources", "value": False}, {"name": "Get Version Info", "value": False}, {"name": "Prevent Hibernation", "value": True}, ], }, { "name": "registry-raw", "parameters": [{"name": "Prevent Hibernation", "value": True}, {"name": "Type", "value": "All"}], }, { "name": "tasks", "parameters": [ {"name": "Prevent Hibernation", "value": True}, {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Verify Digital Signatures", "value": True}, {"name": "Preserve Times", "value": False}, {"name": "raw mode", "value": False}, ], }, {"name": "eventlogs", "parameters": [{"name": "Prevent Hibernation", "value": True}]}, { "name": "processes-memory", "parameters": [ {"name": "Preserve Times", "value": False}, {"name": "Prevent Hibernation", "value": True}, {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "MemD5", "value": False}, {"name": "enumerate imports", "value": True}, {"name": "enumerate exports", "value": True}, {"name": "Verify Digital Signatures", "value": True}, {"name": "sections", "value": True}, {"name": "ports", "value": True}, {"name": "handles", "value": True}, {"name": "detect injected dlls", "value": True}, {"name": "raw mode", "value": False}, {"name": "strings", "value": False}, ], }, { "name": "urlhistory", "parameters": [ {"name": "Prevent Hibernation", "value": True}, {"name": "GetThumbnails", "value": False}, {"name": "GetIndexedPageContent", "value": False}, ], }, {"name": "ports", "parameters": [{"name": "Prevent Hibernation", "value": True}]}, { "name": "services", "parameters": [ {"name": "Prevent Hibernation", "value": True}, {"name": "MD5", "value": True}, {"name": "SHA1", "value": False}, {"name": "SHA256", "value": False}, {"name": "Verify Digital Signatures", "value": True}, {"name": "Preserve Times", "value": False}, {"name": "raw mode", "value": False}, ], }, {"name": "stateagentinspector", "parameters": [{"name": "eventTypes", "value": []}]}, ] } SYS_SCRIPT_MAP = { "osx": STANDARD_INVESTIGATIVE_DETAILS_OSX, "win": STANDARD_INVESTIGATIVE_DETAILS_WIN, "linux": STANDARD_INVESTIGATIVE_DETAILS_LINUX, } TABLE_POLLING_COMMANDS = { "searching": {"type": "searchId", "message": "Searching... , started polling for id "}, "acquisition": {"type": "acquisition_id", "message": "Acquisition is not yet ready, started polling for id "}, } """ CLIENT CLASS """ class Client(BaseClient): def __init__(self, base_url: str, verify: bool = True, proxy: bool = False, auth: Optional[tuple] = None): headers = {"Accept": "application/json"} super().__init__(base_url, verify=verify, proxy=proxy, ok_codes=tuple(range(200, 205)), headers=headers, auth=auth) self._headers["X-FeApi-Token"] = self.get_token_request() def get_token_request(self): """ returns a token on successful request """ # basic authentication try: response = self._http_request(method="GET", url_suffix="token", resp_type="response") except Exception as e: exception_str = str(e) demisto.info(f"Encountered an error for url {self._base_url}/token: {exception_str}") if "Incorrect user id or password" in exception_str: raise DemistoException("Unauthorized - Incorrect user id or password") raise ValueError("Could not get a token") # successful request response_headers = response.headers token = response_headers.get("X-FeApi-Token") self._auth = None # the authentication now is based on the token return token def token_logout(self): """ perform logout for the active session """ if self._headers["X-FeApi-Token"]: try: self._http_request(method="DELETE", url_suffix="token", resp_type="response") except Exception as e: demisto.debug(f"Encountered an error when trying to logout: {e}") # successful request self._headers["X-FeApi-Token"] = None """ POLICIES REQUEST """ def list_policy_request(self, offset: int, limit: int, policy_id: str = None, name: str = None, enabled: bool = None): params = assign_params(_id=policy_id, name=name, offset=offset, limit=limit, enabled=enabled) return self._http_request( method="GET", url_suffix="policies", params=params, ) def list_host_set_policy_request(self, offset: int, limit: int, policy_id: str = ""): params = assign_params(policy_id=policy_id, offset=offset, limit=limit) return self._http_request(method="GET", url_suffix="host_set_policies", params=params) def list_host_set_policy_by_hostSetId_request(self, host_set_id): return self._http_request(method="GET", url_suffix=f"host_sets/{host_set_id}/host_set_policies") def assign_host_set_policy_request(self, body: Dict[str, Any]): return self._http_request(method="POST", url_suffix="host_set_policies", json_data=body, return_empty_response=True) def delete_host_set_policy_request(self, host_set_id, policy_id): return self._http_request( method="DELETE", url_suffix=f"host_sets/{host_set_id}/host_set_policies/{policy_id}", return_empty_response=True ) """ HOST INFORMATION REQUEST """ def get_hosts_by_agentId_request(self, agent_id: str): return self._http_request(method="GET", url_suffix=f"hosts/{agent_id}") def get_hosts_request( self, limit=None, offset=None, has_active_threats=None, has_alerts=None, agent_version=None, containment_queued=None, containment_state=None, host_name=None, os_platform=None, reported_clone=None, time_zone=None, ): params = assign_params( limit=limit, offset=offset, has_active_threats=has_active_threats, has_alerts=has_alerts, agent_version=agent_version, containment_queued=containment_queued, containment_state=containment_state, hostname=host_name, reported_clone=reported_clone, time_zone=time_zone, ) if os_platform: params["os.platform"] = os_platform return self._http_request(method="GET", url_suffix="hosts", params=params, headers=self._headers) def get_host_set_information_request(self, body, host_set_id): url = f"host_sets/{host_set_id}" if host_set_id else "host_sets" return self._http_request(method="GET", url_suffix=url, params=body) """ HOST CONTAINMENT REQUESTS """ def host_containment_request(self, agent_id: str): self._http_request( method="POST", url_suffix=f"hosts/{agent_id}/containment", ) def approve_containment_request(self, agent_id: str): return self._http_request( method="PATCH", url_suffix=f"hosts/{agent_id}/containment", json_data={"state": "contain"}, return_empty_response=True ) def cancel_containment_request(self, agent_id: str): self._http_request(method="DELETE", url_suffix=f"hosts/{agent_id}/containment", return_empty_response=True) def get_list_containment_request(self, offset: int, limit: int, state_update_time: str): params = assign_params(offset=offset, limit=limit, state_update_time=state_update_time) return self._http_request(method="GET", url_suffix="containment_states", params=params) """ HOST SETS """ def delete_host_set_request(self, host_set_id: str): return self._http_request(method="DELETE", url_suffix=f"host_sets/{host_set_id}", return_empty_response=True) def create_static_host_set_request(self, host_set_name: str, hosts_ids: List[str]): body = self.create_static_host_request_body(host_set_name, hosts_ids, []) return self._http_request(method="POST", url_suffix="/host_sets/static", json_data=body) def update_static_host_set_request(self, host_set_id, host_set_name, add_host_ids, remove_host_ids): body = self.create_static_host_request_body(host_set_name, add_host_ids, remove_host_ids) return self._http_request(method="PUT", url_suffix=f"/host_sets/static/{host_set_id}", json_data=body) def create_dynamic_host_set_request(self, host_set_name, query, query_key, query_value, query_operator): body = self.create_dynamic_host_request_body(host_set_name, query, query_key, query_value, query_operator) return self._http_request(method="POST", url_suffix="/host_sets/dynamic", json_data=body) def update_dynamic_host_set_request(self, host_set_id, host_set_name, query, query_key, query_value, query_operator): body = self.create_dynamic_host_request_body(host_set_name, query, query_key, query_value, query_operator) return self._http_request(method="PUT", url_suffix=f"/host_sets/dynamic/{host_set_id}", json_data=body) @staticmethod def create_static_host_request_body(host_set_name: str, host_ids_to_add: list, host_ids_to_remove: list): body = {"name": host_set_name, "changes": [{"command": "change", "add": host_ids_to_add, "remove": host_ids_to_remove}]} return body @staticmethod def create_dynamic_host_request_body(host_set_name: str, query: str, query_key: str, query_value: str, query_operator: str): body: Dict[str, Any] = { "name": host_set_name, } if query: body["query"] = safe_load_json(query) else: body["query"] = {"key": query_key, "value": query_value, "operator": query_operator} return body """ ACQUISITION REQUEST """ def data_acquisition_request(self, agent_id: str, body: Dict): return self._http_request(method="POST", url_suffix=f"hosts/{agent_id}/live", json_data=body) def data_acquisition_information_request(self, acquisition_id): return self._http_request(method="GET", url_suffix=f"acqs/live/{acquisition_id}").get("data") def delete_data_acquisition_request(self, acquisition_id): self._http_request(method="DELETE", url_suffix=f"acqs/live/{acquisition_id}", return_empty_response=True) def data_collection_request(self, acquisition_id): return self._http_request(method="GET", url_suffix=f"acqs/live/{acquisition_id}.mans", resp_type="content") def file_acquisition_request(self, agent_id, file_name, file_path, comment=None, external_id=None, req_use_api=None): body = assign_params( req_path=file_path, req_filename=file_name, comment=comment, external_id=external_id, req_use_api=req_use_api ) return self._http_request(method="POST", url_suffix=f"hosts/{agent_id}/files", json_data=body).get("data") def file_acquisition_information_request(self, acquisition_id): return self._http_request(method="GET", url_suffix=f"acqs/files/{acquisition_id}").get("data") def file_acquisition_package_request(self, acquisition_id): headers = {"Accept": "application/octet-stream"} response = self._http_request( method="GET", url_suffix=f"acqs/files/{acquisition_id}.zip", headers=self._headers | headers, # Update the headers with the new Accept octet-stream resp_type="content", ) return response def delete_file_acquisition_request(self, acquisition_id): """ no return value on successful request """ self._http_request(method="DELETE", url_suffix=f"acqs/files/{acquisition_id}", return_empty_response=True) def host_acquisition_information_request(self, agent_id: str) -> Dict[str, Any]: """API Call to get information about a specific triage Args: agent_id (str): The unique agent ID Returns: dict: HTTP response from the server, containing information about all acquisitions for the host. """ return self._http_request(method="GET", url_suffix=f"hosts/{agent_id}/host_details_acquisitions").get("data") def triage_acquisition_information_request(self, acquisition_id: str) -> Dict[str, Any]: """API Call to get information about a specific triage Args: acquisition_id (str): The unique Triage ID Returns: dict: HTTP response from the server, containing information about the specified triage. """ return self._http_request(method="GET", url_suffix=f"acqs/triages/{acquisition_id}").get("data") def triage_acquisition_request(self, agent_id: str): """API Call to start a triage for a specific host Args: agent_id (str): The unique agent ID Returns: dict: HTTP response from the server, containing information about the started triage acquisition. """ return self._http_request(method="POST", url_suffix=f"hosts/{agent_id}/triages").get("data") def delete_triage_acquisition_request(self, acquisition_id: str): """API Call to delete a specific triage Args: acquisition_id (str): The unique Triage ID """ headers = {"Accept": "text/plain"} self._http_request( method="DELETE", url_suffix=f"acqs/triages/{acquisition_id}", headers=headers, return_empty_response=True, resp_type="text", ) def triage_acquisition_package_request(self, acquisition_id): """API Call to return the triage collection file Args: acquisition_id (str): The unique Triage ID Returns: dict: HTTP response content. """ headers = {"Accept": "application/octet-stream"} response = self._http_request( method="GET", url_suffix=f"acqs/triages/{acquisition_id}.mans", headers=self._headers | headers, # Update the headers with the new Accept octet-stream resp_type="content", ) return response """ ALERTS REQUEST """ def get_alerts_request( self, has_share_mode=None, resolution=None, agent_id=None, condition_id=None, limit=None, offset=None, sort=None, min_id=None, event_at=None, alert_id=None, matched_at=None, reported_at=None, source=None, filter_query=None, ): """ returns the response body on successful request """ params = assign_params( has_share_mode=has_share_mode, resolution=resolution, event_at=event_at, min_id=min_id, _id=alert_id, matched_at=matched_at, reported_at=reported_at, source=source, limit=limit, offset=offset, sort=sort, ) if agent_id: params["agent._id"] = agent_id if condition_id: params["condition._id"] = condition_id if filter_query: return self._http_request( "GET", url_suffix=f"alerts?filterQuery={filter_query}", params=params, headers=self._headers ) else: return self._http_request("GET", url_suffix="alerts", params=params, headers=self._headers) def get_alert_request(self, alert_id: int): return self._http_request(method="GET", url_suffix=f"/alerts/{alert_id}", headers=self._headers) def suppress_alert_request(self, alert_id: int): """ no return value on successful request """ return self._http_request(method="DELETE", url_suffix=f"/alerts/{alert_id}", return_empty_response=True) """ INDICATORS REQUEST """ def get_indicator_request(self, category, name): """ returns a json object representing an indicator """ try: return self._http_request(method="GET", url_suffix=f"/indicators/{category}/{name}", raise_on_status=True)["data"] except DemistoException as e: if e.res and e.res.response_code == 404: raise ValueError(f"The indicator '{name}' was not found") else: raise ValueError(e) def get_indicators_request(self, params): try: return self._http_request( method="GET", url_suffix="/indicators" if not params.get("category") else f"/indicators/{params.get('category')}", params=params, ) except Exception as e: demisto.debug(str(e)) raise ValueError("Failed to parse response body") def get_indicator_conditions_request(self, category: str, name: str, offset: int, enabled: Optional[bool] = True): """ returns a list of json objects, each representing an indicator condition if no results are found- returns None the enabled argument is only passed to FireEye if not None. """ params = {"offset": offset} if enabled is not None: params["enabled"] = enabled try: return self._http_request(method="GET", url_suffix=f"/indicators/{category}/{name}/conditions", params=params) except Exception as e: demisto.debug(str(e)) raise ValueError("Failed to parse response body") def append_conditions_request(self, name: str, category: str, body: str): self._headers["Content-Type"] = "text/plain" return self._http_request(method="PATCH", url_suffix=f"/indicators/{category}/{name}/conditions", data=body) def delete_condition(self, indicator_name: str, category: str, condition_type: str, condition_id: str): return self._http_request( method="DELETE", url_suffix=f"/indicators/{category}/{indicator_name}/conditions/{condition_type}/{condition_id}", ok_codes=(200, 204), raise_on_status=True, ) def new_indicator_request(self, category, body: Dict[str, Any]): """ Create a new indicator """ try: return self._http_request(method="POST", url_suffix=f"indicators/{category}", json_data=body) except Exception as e: demisto.debug(str(e)) raise ValueError("Failed to parse response body, unexpected response structure from the server.") def delete_indicator(self, indicator_name: str, category: str): return self._http_request( method="DELETE", url_suffix=f"/indicators/{category}/{indicator_name}", ok_codes=(204,), raise_on_status=True, resp_type="response", ) def list_indicator_categories( self, search: Optional[str], name: Optional[str], display_name: Optional[str], retention_policy: Optional[str], ui_edit_policy: Optional[str], ui_signature_enabled: Optional[bool], ui_source_alerts_enabled: Optional[bool], share_mode: Optional[str], limit: int = 50, offset: int = 0, ): params = {"limit": limit, "offset": offset} params.update( assign_params( search=search, name=name, display_name=display_name, retention_policy=retention_policy, ui_edit_policy=ui_edit_policy, ui_signature_enabled=ui_signature_enabled, ui_source_alerts_enabled=ui_source_alerts_enabled, share_mode=share_mode, ) ) return self._http_request( method="GET", url_suffix="/indicator_categories", params=params, ok_codes=(200,), raise_on_status=True, ) """ SEARCHES REQUEST """ def get_search_by_id_request(self, search_id: int): return self._http_request(method="GET", url_suffix=f"searches/{search_id}") def get_search_list_request( self, offset: int, limit: int, state: str = None, host_set_id: int = None, actor_username: str = None, sort: str = None ): params = assign_params(offset=offset, limit=limit, state=state, sort=sort) if actor_username: params["update_actor.username"] = actor_username if host_set_id: params["host_set._id"] = host_set_id return self._http_request(method="GET", url_suffix="searches", params=params) def search_stop_request(self, search_id: str): return self._http_request( method="POST", url_suffix=f"searches/{search_id}/actions/stop", ) def delete_search_request(self, search_id): """ no return value on successful request """ self._http_request(method="DELETE", url_suffix=f"searches/{search_id}", return_empty_response=True) def search_result_get_request(self, search_id: str): return self._http_request( method="GET", url_suffix=f"searches/{search_id}/results", ) def search_request(self, body: Dict): return self._http_request(method="POST", url_suffix="searches", json_data=body) """ HELPER FUNCTIONS """ def get_alerts(client: Client, args: Dict[str, Any]) -> List: offset = 0 alerts = [] # type: List[Dict[str, str]] max_records = args.get("limit") or float("inf") while len(alerts) < max_records: alerts_partial_results = client.get_alerts_request( has_share_mode=args.get("hasShareMode"), resolution=args.get("resolution"), agent_id=args.get("agentId"), condition_id=args.get("conditionId"), event_at=args.get("eventAt"), alert_id=args.get("alertId"), matched_at=args.get("matchedAt"), reported_at=args.get("reportedAt"), source=args.get("source"), offset=offset, limit=args.get("limit") or 100, sort=args.get("sort"), filter_query=args.get("filterQuery"), ) # empty list if len(alerts_partial_results["data"]["entries"]) == 0: break alerts.extend(alerts_partial_results["data"]["entries"]) offset = len(alerts) # remove excess results if len(alerts) > max_records: alerts[int(max_records) - 1 : -1] = [] return alerts def get_agent_id_by_host_name(client: Client, host_name: str): return client.get_hosts_request(host_name=host_name, limit=1)["data"]["entries"][0]["_id"] def host_set_entry(host_sets: List[Dict]) -> List[Dict]: return [{"Name": host_set.get("name"), "ID": host_set.get("_id"), "Type": host_set.get("type")} for host_set in host_sets] def general_context_from_event(alert: Dict): def file_context(values: Dict): dbot = Common.DBotScore( values.get("fileWriteEvent/md5"), DBotScoreType.FILE, integration_name="FireEye-HX", score=Common.DBotScore.NONE ) return Common.File( dbot, name=values.get("fileWriteEvent/fileName"), md5=values.get("fileWriteEvent/md5"), extension=values.get("fileWriteEvent/fileExtension"), path=values.get("fileWriteEvent/fullPath"), ) def ip_context(values: Dict): dbot = Common.DBotScore( values.get("ipv4NetworkEvent/remoteIP"), DBotScoreType.IP, integration_name="FireEye-HX", score=Common.DBotScore.NONE ) return Common.IP(values.get("ipv4NetworkEvent/remoteIP"), dbot_score=dbot) context_map = {"fileWriteEvent": file_context, "ipv4NetworkEvent": ip_context} if context_map.get(alert["event_type"]) is not None: f = context_map[alert["event_type"]] return f(alert["event_values"]) return None def oneFromList(list_of_args, args): checker = 0 result = None for arg in list_of_args: if args.get(arg): checker += 1 result = (arg, args.get(arg)) return result if checker == 1 else False def organize_search_body_host(client: Client, arg: tuple, body: Dict): if arg[0] == "hostsNames": hostsNames = arg[1].split(",") agentsIds = [] for hostName in hostsNames: try: agentsIds.append({"_id": get_agent_id_by_host_name(client, hostName)}) except Exception: raise ValueError(f"Host Name {hostName} is not valid") body["hosts"] = agentsIds elif arg[0] == "agentsIds": agentsIds = arg[1].split(",") agentsIds = [{"_id": agentId} for agentId in agentsIds] body["hosts"] = agentsIds elif arg[0] == "hostSetName": result = client.get_host_set_information_request({"name": arg[1]}, None) entries = result.get("data", {}).get("entries", []) if entries: host_set = {"_id": entries[0].get("_id")} body["host_set"] = host_set else: raise DemistoException("hostSetName is not valid.") elif arg[0] == "hostSet": hostSet = {"_id": int(arg[1])} body["host_set"] = hostSet return body def organize_search_body_query(argForQuery: tuple, args: Dict): query = [] if argForQuery[0] == "fieldSearchName": if not args.get("fieldSearchOperator") or not args.get("fieldSearchValue"): raise ValueError("fieldSearchOperator and fieldSearchValue are required arguments") fieldSearchValue = argToList(args.get("fieldSearchValue", "")) for searchValue in fieldSearchValue: query.append(assign_params(field=argForQuery[1], operator=args.get("fieldSearchOperator"), value=searchValue)) else: if not args.get(f"{argForQuery[0]}Operator"): raise ValueError(f"{argForQuery[0]}Operator is required argument") arg_to_query_field_map = { "dnsHostname": "DNS Hostname", "fileFullPath": "File Full Path", "fileMD5Hash": "File MD5 Hash", "ipAddress": "IP Address", } for searchValue in argToList(argForQuery[1]): query.append( assign_params( field=arg_to_query_field_map[argForQuery[0]], operator=args.get(f"{argForQuery[0]}Operator"), value=searchValue, ) ) return query def get_collect_endpoint_context(host: Dict): return { "Hostname": host.get("hostname"), "ID": host.get("_id"), "IPAddress": host.get("primary_ip_address"), "Domain": host.get("domain"), "MACAddress": host.get("primary_mac"), "OS": host.get("os", {}).get("platform"), "OSVersion": host.get("os", {}).get("product_name"), } def get_data_acquisition(client: Client, args: Dict[str, Any]) -> Dict: host_name = args.get("hostName", "") agent_id = args.get("agentId") script = args.get("script", "") script_name = args.get("scriptName") default_system_script = args.get("defaultSystemScript") if not host_name and not agent_id: raise ValueError("Please provide either agentId or hostName") if not default_system_script and not script: raise ValueError("If the script is not provided, defaultSystemScript must be specified") if script and not script_name: raise ValueError("If the script is provided, script name must be specified as well") if not agent_id: agent_id = get_agent_id_by_host_name(client, host_name) # determine whether to use the default script sys = default_system_script if sys: script = json.dumps(SYS_SCRIPT_MAP[sys]) script_name = f"{sys}DefaultScript" body = {"name": script_name, "script": {"b64": base64.b64encode(bytes(script, "utf-8")).decode()}} return client.data_acquisition_request(agent_id, body)["data"] # Helper function triage acq def get_triage_acquisition(client: Client, args: Dict[str, Any]) -> Dict: """Helper function to start a triage on a provided host Args: client (Client): The HX client object. args (Dict[str, Any]): Demisto Arguments Raises: ValueError: Missing Agent ID or Hostname Returns: Dict: HTTP response from the server, containing information about the started triage acquisition. """ host_name = args.get("hostName", "") agent_id = args.get("agentId") if not host_name and not agent_id: raise ValueError("Please provide either agentId or hostName") if not agent_id: agent_id = get_agent_id_by_host_name(client, host_name) return client.triage_acquisition_request(agent_id) def get_alert_entry(alert: Dict): alert_entry = { "Alert ID": alert.get("_id"), "Reported": alert.get("reported_at"), "Event Type": alert.get("event_type"), "Agent ID": alert.get("agent", {}).get("_id"), } return alert_entry def get_indicator_entry(indicator: Dict): indicator_entry = { "OS": ", ".join(indicator.get("platforms", [])), "Name": indicator.get("name"), "Created By": indicator.get("created_by"), "Active Since": indicator.get("active_since"), "Category": indicator.get("category", {}).get("name"), "Signature": indicator.get("signature"), "Active Condition": indicator.get("stats", {}).get("active_conditions"), "Hosts With Alerts": indicator.get("stats", {}).get("alerted_agents"), "Source Alerts": indicator.get("stats", {}).get("source_alerts"), } return indicator_entry def get_indicator_command_result(alert: Dict[str, Any]) -> CommandResults: if alert.get("event_type") == "fileWriteEvent": indicator = general_context_from_event(alert) event_values: Dict[str, Any] = alert.get("event_values", {}) md_table = tableToMarkdown( name="File", t={ "Name": event_values.get("fileWriteEvent/fileName"), "md5": event_values.get("fileWriteEvent/md5"), "Extension": event_values.get("fileWriteEvent/fileExtension"), "Path": event_values.get("fileWriteEvent/fullPath"), }, headers=["Name", "md5", "Extension", "Path"], ) return CommandResults(outputs_prefix="File", indicator=indicator, readable_output=md_table) elif alert.get("event_type") == "ipv4NetworkEvent": indicator = general_context_from_event(alert) event_values = alert.get("event_values", {}) md_table = tableToMarkdown(name="Ip", t={"Ipv4": event_values.get("ipv4NetworkEvent/remoteIP")}) return CommandResults(outputs_prefix="Ip", indicator=indicator, readable_output=md_table) return CommandResults(readable_output=f'Unknown event type: {alert.get("event_type")}') def get_condition_entry(condition: Dict): indicator_entry = { "Event Type": condition.get("event_type"), "Operator": condition.get("tests", {})[0].get("operator"), "Value": condition.get("tests", {})[0].get("value"), } return indicator_entry def get_all_indicators( client: Client, category=None, search=None, share_mode=None, sort=None, created_by=None, alerted=None, limit=None ): max_records = limit or float("inf") indicators = [] # type: List[Dict[str, str]] params = assign_params(category=category, search=search, sort=sort, created_by=created_by, offset=0, limit=limit or 100) if share_mode: params["category.share_mode"] = share_mode if alerted: params["stats.alerted_agents"] = share_mode # get all results while len(indicators) < max_records: indicators_partial_results = client.get_indicators_request(params)["data"]["entries"] if not indicators_partial_results: break indicators.extend(indicators_partial_results) params["offset"] = len(indicators) # remove access results if len(indicators) > max_records: indicators[int(max_records) - 1 : -1] = [] return indicators def get_all_enabled_conditions(client: Client, indicator_category, indicator_name): offset = 0 conditions = [] # type: List[Dict[str, str]] # get all results while True: conditions_partial_results = client.get_indicator_conditions_request( indicator_category, indicator_name, offset=offset, enabled=True, )["data"]["entries"] if not conditions_partial_results: break conditions.extend(conditions_partial_results) offset = len(conditions) return conditions def get_indicator_conditions(client: Client, args: Dict[str, Any]) -> CommandResults: """ returns a list of enabled conditions associated with a specific indicator to the war room """ conditions = get_all_enabled_conditions(client, args.get("category"), args.get("name")) conditions_entries = [get_condition_entry(condition) for condition in conditions] md_table = tableToMarkdown(name=f"Indicator '{args.get('name')}' Alerts on", t=conditions_entries) return CommandResults( outputs_prefix="FireEyeHX.Conditions", outputs_key_field="_id", outputs=conditions, readable_output=md_table ) def validate_base_url(base_url: str) -> None: # Any of the following combinations is not allowed as suffix: /v3, /api/v3, /hx/api/v3 etc. # The error message is built to include the complete suffix that should be removed (rather than running 2 or 3 times, # seeing an error each time) error_message = "" for suffix in (("/v3", "/v3/"), ("/api", "/api/"), ("/hx", "/hx/")): if base_url.endswith(suffix): base_url = base_url[: -len(suffix[0])] error_message = suffix[0] + error_message if error_message: raise ValueError(f"The base URL is invalid please set the base URL without including {error_message}") """helper fetch-incidents""" def organize_reported_at(reported_at): millisecond = int(reported_at[-4:-1]) + 1 if millisecond == 1000: reported_at = date_to_timestamp(reported_at[:-5], date_format=DATE_FORMAT) + 1000 reported_at = timestamp_to_datestring(reported_at, date_format=DATE_FORMAT) + ".000Z" else: if millisecond < 10: reported_at = reported_at[:-4] + "00" + str(millisecond) + reported_at[-1] elif millisecond < 100: reported_at = reported_at[:-4] + "0" + str(millisecond) + reported_at[-1] else: reported_at = reported_at[:-4] + str(millisecond) + reported_at[-1] return reported_at def query_fetch(reported_at=None, first_fetch: str = None): query = '{"operator":"between","arg":[' if reported_at: query += '"' + reported_at + '"' + "," else: query += '"' + timestamp_to_datestring(parse_date_range(first_fetch, to_timestamp=True, utc=False)[0]) + '"' + "," query += ( '"' + timestamp_to_datestring(parse_date_range("1 days", to_timestamp=True, utc=False)[1]) + '"' + '],"field":"reported_at"}' ) return query def parse_alert_to_incident(alert: Dict, pattern: Pattern) -> Dict: event_type = alert.get("event_type") event_type = event_type if event_type else "NewEvent" event_values = alert.get("event_values", {}) event_indicators_map = { "fileWriteEvent": "fileWriteEvent/fileName", "ipv4NetworkEvent": "ipv4NetworkEvent/remoteIP", "dnsLookupEvent": "dnsLookupEvent/hostname", "regKeyEvent": "regKeyEvent/valueName", } event_indicator = event_indicators_map.get(event_type) event_indicator = event_indicator if event_indicator else "No Indicator" indicator = "" if isinstance(event_values, dict): indicator = event_values.get(event_indicator, "") incident_name = "{event_type_parsed}: {indicator}".format( event_type_parsed=pattern.sub(r"\g<1> \g<2>", event_type).title(), indicator=indicator ) incident = {"name": incident_name, "occurred": alert.get("event_at"), "rawJSON": json.dumps(alert)} return incident def run_commands_without_polling(client: Client, args: Dict[str, Any]): if args.get("cmd") == "fireeye-hx-search": return start_search_command(client, args)[0] if args.get("cmd") == "fireeye-hx-data-acquisition": return data_acquisition_command(client, args)[0] if args.get("cmd") == "fireeye-hx-file-acquisition": return file_acquisition_command(client, args)[0] return None """ COMMAND FUNCTIONS """ """ POLICIES """ def list_policy_command(client: Client, args: Dict[str, Any]) -> CommandResults: offset = args.get("offset", 0) limit = args.get("limit", 50) name = args.get("policyName") policy_id = args.get("policyId") enabled = args.get("enabled") if name and policy_id: raise ValueError("Enter a name or ID but not both") response = client.list_policy_request(offset=offset, limit=limit, policy_id=policy_id, name=name, enabled=enabled) for_table = [ { "Policy Id": entry["_id"], "Policy Name": entry["name"], "Description": entry["description"], "Priority": entry["priority"], "Enabled": entry["enabled"], } for entry in response["data"]["entries"] ] headers_for_table = ["Policy Name", "Policy Id", "Description", "Priority", "Enabled"] md = tableToMarkdown(name="FireEye HX List Policies", t=for_table, headers=headers_for_table) command_results = CommandResults( outputs_prefix="FireEyeHX.Policy", outputs_key_field="_id", outputs=response, raw_response=response, readable_output=md ) return command_results def list_host_set_policy_command(client: Client, args: Dict[str, Any]) -> CommandResults: offset = args.get("offset", 0) limit = args.get("limit", 50) host_set_id = args.get("hostSetId") policy_id = args.get("policyId", "") if host_set_id and policy_id: raise ValueError("Enter a Policy Id or Host Set Id but not both") if host_set_id: response = client.list_host_set_policy_by_hostSetId_request(host_set_id) else: response = client.list_host_set_policy_request(offset=offset, limit=limit, policy_id=policy_id) for_table = [] for entry in response["data"]["entries"]: for_table.append({"Policy Id": entry["policy_id"], "Host Set Id": entry["persist_id"]}) headers_for_table = ["Policy Id", "Host Set Id"] md = tableToMarkdown(name="FireEye HX Host Set Policies", t=for_table, headers=headers_for_table) return CommandResults( outputs_prefix="FireEyeHX.HostSets.Policy", outputs_key_field="_id", outputs=response["data"]["entries"], readable_output=md, ) def assign_host_set_policy_command(client: Client, args: Dict[str, Any]) -> CommandResults: host_set_id = args.get("hostSetId") policy_id = args.get("policyId") if not policy_id or not host_set_id: raise ValueError("policy ID and hostSetId are required") message = "" response = None try: response = client.assign_host_set_policy_request({"persist_id": host_set_id, "policy_id": policy_id}) message = "Success" except Exception as e: if "400" in str(e): demisto.debug(str(e)) message = "This hostset may already be included in this policy" else: raise ValueError(e) return CommandResults(readable_output=message, outputs_prefix="FireEyeHX.Policy", outputs=response) def delete_host_set_policy_command(client: Client, args: Dict[str, Any]) -> CommandResults: host_set_id = int(args.get("hostSetId", "")) policy_id = args.get("policyId") message = "" try: client.delete_host_set_policy_request(host_set_id, policy_id) message = "Success" except Exception as e: if "404" in str(e): message = f"policy ID - {policy_id} or Host Set ID - {host_set_id} Not Found" else: raise ValueError(e) return CommandResults(readable_output=message) """ HOST INFORMATION """ def get_all_hosts_information_command(client: Client, args: Dict[str, Any]) -> CommandResults: offset = int(args.get("offset", 0)) hosts = [] limit = int(args.get("limit", 1000)) if limit > 1000: limit = 1000 while True: hosts_partial = client.get_hosts_request(offset=offset, limit=limit) if not hosts_partial["data"]["entries"]: break hosts.extend(hosts_partial["data"]["entries"]) offset = len(hosts) if len(hosts) > limit: hosts[int(limit) - 1 : -1] = [] outputs = [] for host in hosts: outputs.append( { "Host Name": host.get("hostname"), "Last Poll": host.get("last_poll_timestamp"), "Agent ID": host.get("_id"), "Agent Version": host.get("agent_version"), "Host IP": host.get("primary_ip_address"), "OS": host.get("os", {}).get("platform"), "Containment State": host.get("containment_state"), "Domain": host.get("domain"), "Last Alert": host.get("last_alert"), } ) headers_for_table = [ "Host Name", "Host IP", "Agent ID", "Agent Version", "OS", "Last Poll", "Containment State", "Domain", "Last Alert", ] md = tableToMarkdown(name="FireEye HX Get Hosts Information", t=outputs, headers=headers_for_table) return CommandResults( outputs_prefix="FireEyeHX.Hosts", outputs_key_field="_id", outputs=outputs, raw_response=hosts, readable_output=md ) def get_host_information_command(client: Client, args: Dict[str, Any]) -> CommandResults: agent_id = args.get("agentId") host_name = args.get("hostName") if not agent_id and not host_name: raise ValueError("Please provide either agentId or hostName") host: Dict if agent_id: try: host = client.get_hosts_by_agentId_request(agent_id)["data"] except Exception: raise ValueError(f"agentId {agent_id} is not correct") else: try: host = client.get_hosts_request(limit=1, host_name=host_name)["data"]["entries"][0] except Exception: raise ValueError(f"{host_name} is not found") headers_for_table = [ "Host Name", "Host IP", "Agent ID", "Agent Version", "OS", "Last Poll", "Containment State", "Domain", "Last Alert", ] for_table = [ { "Host Name": host.get("hostname"), "Last Poll": host.get("last_poll_timestamp"), "Agent ID": host.get("_id"), "Agent Version": host.get("agent_version"), "Host IP": host.get("primary_ip_address"), "OS": host.get("os", {}).get("platform"), "Containment State": host.get("containment_state"), "Domain": host.get("domain"), "Last Alert": host.get("last_alert"), } ] md = tableToMarkdown(name="FireEye HX Get Host Information", t=for_table, headers=headers_for_table) return CommandResults(outputs_prefix="FireEyeHX.Hosts", outputs_key_field="_id", outputs=host, readable_output=md) def get_host_set_information_command(client: Client, args: Dict[str, Any]) -> CommandResults: """ return host set information to the war room according to given id or filters """ host_set_id = args.get("hostSetID") body = assign_params( limit=args.get("limit"), offset=args.get("offset"), search=args.get("search"), sort=args.get("sort"), name=args.get("name"), type=args.get("type"), ) response = client.get_host_set_information_request(body, host_set_id) host_set = [] # type: List[Dict[str, Any]] try: if host_set_id: data = response["data"] host_set = [data] else: data = response["data"] host_set = data.get("entries", []) except Exception as e: demisto.debug(str(e)) raise ValueError("Failed to get host set information - unexpected response from the server.\n" + response.text) md_table = "No host sets found" if len(host_set) > 0: md_table = tableToMarkdown( name="FireEye HX Get Host Sets Information", t=host_set_entry(host_set), headers=["Name", "ID", "Type"] ) for entry in host_set: entry["deleted"] = False return CommandResults( outputs_prefix="FireEyeHX.HostSets", outputs_key_field="_id", outputs=host_set, readable_output=md_table ) """ HOST CONTAINMENT """ def get_list_containment_command(client: Client, args: Dict[str, Any]) -> CommandResults: state_update_time = args.get("state_update_time", "") offset = args.get("offset", 0) limit = args.get("limit", 50) response = client.get_list_containment_request(offset=offset, limit=limit, state_update_time=state_update_time)["data"][ "entries" ] for_table = [] for entry in response: for_table.append( { "Id": entry["_id"], "State": entry["state"], "Request Origin": entry["requested_by_actor"], "Request Date": entry["requested_on"], "Containment Origin": entry["contained_by_actor"], "Containment Date": entry["contained_on"], "Last System information date": entry["last_sysinfo"], } ) headers_for_table = [ "Id", "State", "Request Origin", "Request Date", "Containment Origin", "Containment Date", "Last System information date", ] md = tableToMarkdown(name="List Containment", t=for_table, headers=headers_for_table) return CommandResults(outputs_prefix="FireEyeHX.Hosts", outputs_key_field="_id", outputs=response, readable_output=md) def host_containment_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]: agent_id = args.get("agentId") host_name = args.get("hostName", "") if not agent_id and not host_name: raise ValueError("Please provide either agentId or hostName") if not agent_id: agent_id = get_agent_id_by_host_name(client, host_name) try: client.host_containment_request(agent_id) except Exception as e: raise ValueError(e) message = "" try: client.approve_containment_request(agent_id) message = "Containment request for the host was sent and approved successfully" except Exception as e: if "422" in str(e): message = ( "You do not have the required permissions for containment approve\n" "The containment request sent, but it is not approve." ) elif "409" in str(e): message = "This host may already in containment" else: raise ValueError(e) host = client.get_hosts_by_agentId_request(agent_id) return [ CommandResults(outputs_prefix="FireEyeHX.Hosts", outputs_key_field="_id", outputs=host["data"], readable_output=message), CommandResults(outputs_prefix="Endpoint", outputs=get_collect_endpoint_context(host["data"])), ] def approve_containment_command(client: Client, args: Dict[str, Any]) -> CommandResults: agent_id = args.get("agentId") if not agent_id: raise ValueError("Agent ID is required") message = "Containment for the host was approved successfully" try: client.approve_containment_request(agent_id) except Exception as e: if "409" in str(e): message = "This host may already in containment" else: message = "Containment for the host failed, check if you have the necessary permissions" return CommandResults(outputs_prefix="FireEyeHX.Hosts", readable_output=message) def cancel_containment_command(client: Client, args: Dict[str, Any]) -> CommandResults: agent_id = args.get("agentId") host_name = args.get("hostName", "") if not agent_id and not host_name: raise ValueError("One of the following arguments is required -> [agentId, hostName]") if not agent_id: agent_id = get_agent_id_by_host_name(client, host_name) message = "Success" try: client.cancel_containment_request(agent_id) except Exception as e: if "409" in str(e): message = "This host may already in uncontain" else: raise ValueError(e) return CommandResults(readable_output=message) """ HOST SETS """ def delete_host_set_command(client: Client, args: Dict[str, Any]) -> CommandResults: host_set_id: str = args.get("host_set_id", "") outputs = {} try: client.delete_host_set_request(host_set_id) message = f"Host set {host_set_id} was deleted successfully" outputs = {"deleted": True, "_id": host_set_id} except Exception as e: if "404" in str(e): message = f"Host set id - {host_set_id} Not Found" else: raise ValueError(e) return CommandResults(outputs_prefix="FireEyeHX.HostSets", outputs_key_field="_id", outputs=outputs, readable_output=message) def create_static_host_set_command(client: Client, args: Dict[str, Any]) -> CommandResults: host_set_name = args.get("host_set_name", "") hosts_ids = argToList(args.get("hosts_ids")) data = {} try: response = client.create_static_host_set_request(host_set_name, hosts_ids) if data := response.get("data"): data["deleted"] = False date = datetime.strptime(data["_revision"][:-6], "%Y%m%d%H%M%S%f") data["_revision"] = date.strftime("%m/%d/%Y, %H:%M:%S.%f") host_set_id = data.get("_id") message = f"Static Host Set {host_set_name} with id {host_set_id} was created successfully." else: message = "" demisto.debug(f"No data -> {message=}") except Exception as e: response = {} if "409" in str(e): message = "Another host set with the same name was found, please use a different one." elif "Referenced entity not found" in str(e): message = "Referenced entity not found, check if one of the host ids that were given does not exists." else: demisto.debug(str(e)) message = "Creating Host Set failed, check if you have the necessary permissions." return CommandResults( outputs_prefix="FireEyeHX.HostSets", outputs_key_field="_id", outputs=data, readable_output=message, raw_response=response ) def update_static_host_set_command(client: Client, args: Dict[str, Any]) -> CommandResults: host_set_id = args.get("host_set_id") host_set_name = args.get("host_set_name") add_host_ids = argToList(args.get("add_host_ids")) remove_host_ids = argToList(args.get("remove_host_ids")) if not add_host_ids and not remove_host_ids: message = "Nothing to update, no host ids to add or to remove were given." return CommandResults(readable_output=message) data: Dict[str, Any] = {} try: response = client.update_static_host_set_request(host_set_id, host_set_name, add_host_ids, remove_host_ids) if data := response.get("data"): data["deleted"] = False date = datetime.strptime(data["_revision"][:-6], "%Y%m%d%H%M%S%f") data["_revision"] = date.strftime("%m/%d/%Y, %H:%M:%S.%f") message = f"Static Host Set {host_set_name} was updated successfully." except Exception as e: response = {} if "409" in str(e): message = "Another host set with the same name was found, please use a different one." elif "Referenced entity not found" in str(e): message = "Referenced entity not found, Check if one of the host ids that was given does not exists." elif "404" in str(e): message = "Host set was not found." else: demisto.debug(str(e)) message = "Updating Host Set failed, check if you have the necessary permissions." return CommandResults( outputs_prefix="FireEyeHX.HostSets", outputs_key_field="_id", outputs=data, readable_output=message, raw_response=response ) def create_dynamic_host_set_command(client: Client, args: Dict[str, Any]) -> CommandResults: host_set_name = args.get("host_set_name") query = args.get("query") query_key = args.get("query_key") query_value = args.get("query_value") query_operator = args.get("query_operator") if query and (query_key or query_value or query_operator): raise ValueError("Cannot use free text query with other query operators, Please use one.") elif not (query_key and query_value and query_operator) and not query: raise ValueError("Please provide a free text query, or add all of the query operators together.") data: Dict[str, Any] = {} try: response = client.create_dynamic_host_set_request(host_set_name, query, query_key, query_value, query_operator) if data := response.get("data"): data["deleted"] = False date = datetime.strptime(data["_revision"][:-6], "%Y%m%d%H%M%S%f") data["_revision"] = date.strftime("%m/%d/%Y, %H:%M:%S.%f") host_set_id = data.get("_id") message = f"Dynamic Host Set {host_set_name} with id {host_set_id} was created successfully." else: message = "" demisto.debug(f"No data -> {message=}") except Exception as e: response = {} if "409" in str(e): message = "Another host set with the same name was found, please use a different one." else: demisto.debug(str(e)) message = "Creating Host Set failed, check if you have the necessary permissions." return CommandResults( outputs_prefix="FireEyeHX.HostSets", outputs_key_field="_id", outputs=data, readable_output=message, raw_response=response ) def update_dynamic_host_set_command(client: Client, args: Dict[str, Any]) -> CommandResults: host_set_name = args.get("host_set_name") host_set_id = args.get("host_set_id") query = args.get("query") query_key = args.get("query_key") query_value = args.get("query_value") query_operator = args.get("query_operator") if query and (query_key or query_value or query_operator): raise ValueError("Cannot use free text query with other query operators, Please use one.") elif not (query_key and query_value and query_operator) and not query: raise ValueError("Please provide a free text query, or add all of the query operators together.") data = {} try: response = client.update_dynamic_host_set_request( host_set_id, host_set_name, query, query_key, query_value, query_operator ) if data := response.get("data"): data["deleted"] = False date = datetime.strptime(data["_revision"][:-6], "%Y%m%d%H%M%S%f") data["_revision"] = date.strftime("%m/%d/%Y, %H:%M:%S.%f") message = f"Dynamic Host Set {host_set_name} was updated successfully." else: message = "" demisto.debug(f"No data -> {message=}") except Exception as e: response = {} if "409" in str(e): message = "Another host set with the same name was found, please use a different one." elif "404" in str(e): message = "Host set was not found." else: demisto.debug(str(e)) message = "Updating Host Set failed, check if you have the necessary permissions" return CommandResults( outputs_prefix="FireEyeHX.HostSets", outputs_key_field="_id", outputs=data, readable_output=message, raw_response=response ) """ ACQUISITION """ def data_acquisition_command(client: Client, args: Dict[str, Any]) -> tuple[CommandResults, bool, str]: if "acquisition_id" not in args: acquisition_info = get_data_acquisition(client, args) acquisition_id = acquisition_info.get("_id") demisto.debug("Acquisition request was successful. Waiting for acquisition process to be complete.") acquisition_id = args.get("acquisition_id") if args.get("acquisition_id") else acquisition_id acquisition_info = client.data_acquisition_information_request(acquisition_id) if acquisition_info.get("state") != "COMPLETE": return ( CommandResults(readable_output=f"Acquisition request was successful\nAcquisition ID: {acquisition_id}"), False, str(acquisition_id), ) args["acquisition_info"] = acquisition_info return ( CommandResults(readable_output=f"Acquisition request was successful\nAcquisition ID: {acquisition_id}"), True, str(acquisition_id), ) def data_acquisition_with_polling_command(client: Client, args: Dict[str, Any]): return run_polling_command( client, args, "fireeye-hx-data-acquisition", data_acquisition_command, result_data_acquisition, "acquisition" ) def result_data_acquisition(client: Client, args: Dict[str, Any]) -> List: demisto.debug("Acquisition process has been complete. Fetching mans file.") message = f'{args.get("fileName")} acquired successfully' if args.get("acquisition_info", {}).get("error_message"): message = args.get("acquisition_info", {}).get("error_message", "") # output file and acquisition information to the war room data = client.data_collection_request(args.get("acquisition_id")) return [ CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Data", outputs=args.get("acquisition_info", {}), readable_output=f'{message}\nacquisition ID: {args.get("acquisition_id")}', ), fileResult(f'agent_{args.get("agentId")}_data.mans', data), ] def delete_data_acquisition_command(client: Client, args: Dict[str, Any]) -> CommandResults: if "acquisitionId" not in args: raise ValueError("Acquisition Id is required") client.delete_data_acquisition_request(args.get("acquisitionId")) return CommandResults(readable_output=f"data acquisition {args.get('acquisitionId')} deleted successfully") def file_acquisition_command(client: Client, args: Dict[str, Any]) -> tuple[CommandResults, bool, str]: if "acquisition_id" not in args: if not args.get("hostName") and not args.get("agentId"): raise ValueError("Please provide either agentId or hostName") if args.get("hostName"): args["agentId"] = get_agent_id_by_host_name(client, args.get("hostName", "")) use_api = args.get("acquireUsing") == "API" acquisition_info = client.file_acquisition_request( args.get("agentId"), args.get("fileName"), args.get("filePath"), req_use_api=use_api ) acquisition_id = acquisition_info.get("_id") demisto.debug("acquisition request was successful. Waiting for acquisition process to be complete.") acquisition_id = args.get("acquisition_id") if args.get("acquisition_id") else str(acquisition_id) acquisition_info = client.file_acquisition_information_request(acquisition_id) state = acquisition_info.get("state") if state not in ["COMPLETE", "ERROR", "FAILED"]: return ( CommandResults(readable_output=f"acquisition request was successful, Acquisition Id: {acquisition_id}"), False, acquisition_id, ) args["acquisition_info"] = acquisition_info return ( CommandResults(readable_output=f"acquisition request was successful, Acquisition Id: {acquisition_id}"), True, acquisition_id, ) def file_acquisition_with_polling_command(client: Client, args: Dict[str, Any]): return run_polling_command( client, args, "fireeye-hx-file-acquisition", file_acquisition_command, result_file_acquisition, "acquisition" ) def result_file_acquisition(client: Client, args: Dict[str, Any]) -> List: demisto.debug("acquisition process has been complete. Fetching zip file.") acquired_file = client.file_acquisition_package_request(args.get("acquisition_id")) message = f"{args.get('fileName')} acquired successfully" if args.get("acquisition_info", {}).get("error_message"): message = args.get("acquisition_info", {}).get("error_message") return [ CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Files", outputs_key_field="_id", outputs=args.get("acquisition_info"), readable_output=f"{message}\nacquisition ID: {args.get('acquisition_id')}", ), fileResult(f"{os.path.splitext(args.get('fileName', ''))[0]}.zip", acquired_file), ] def get_data_acquisition_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]: """ Wait for acquisition process to complete and fetch the data """ # validate the acquisitionId was passed if not args.get("acquisitionId"): raise ValueError("Please provide acquisitionId") acquisition_id = args.get("acquisitionId") acquisition_info = client.data_acquisition_information_request(acquisition_id) agent_id = acquisition_info.get("host").get("_id") host_info = client.get_hosts_by_agentId_request(agent_id)["data"] hostname = host_info.get("hostname") # Add hostname to the host info of acquisition_info acquisition_info["host"]["hostname"] = hostname # Add Integration Instance to the acquisition_info acquisition_info["instance"] = demisto.integrationInstance() # if `state` equals to 'COMPLETE' if acquisition_info.get("state") == "COMPLETE": message = "Acquisition completed successfully." if acquisition_info.get("error_message"): message = acquisition_info.get("error_message") # output file and acquisition information to the war room data = client.data_collection_request(acquisition_id) return [ CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Data", outputs_key_field="_id", outputs=acquisition_info, readable_output=f"{message}\nacquisition ID: {acquisition_id}", ), fileResult(f"{acquisition_id}_agent_{agent_id}_data.mans", data), ] # else return message for states in [ NEW, ERROR, QUEUED, RUNNING, FAILED ] state = acquisition_info.get("state") message = "Acquisition process not yet completed." if acquisition_info.get("error_message"): message = acquisition_info.get("error_message") return [ CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Data", outputs_key_field="_id", outputs=acquisition_info, readable_output=f"{message}\nacquisition ID: {acquisition_id}\nstate: {state}", ) ] def initiate_data_acquisition_command(client: Client, args: Dict[str, Any]) -> CommandResults: acquisition_info: Dict = get_data_acquisition(client, args) # Add hostname to the host info of acquisition_info acquisition_info["host"]["hostname"] = args.get("hostName") # Add Integration Instance to the acquisition_info acquisition_info["instance"] = demisto.integrationInstance() return CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Data", outputs=acquisition_info, readable_output=f'Acquisition ID: {acquisition_info.get("_id")} on Instance: {acquisition_info.get("instance")}', ) def delete_file_acquisition_command(client: Client, args: Dict[str, Any]) -> CommandResults: """ returns a success message to the war room """ acquisition_id = args.get("acquisitionId") client.delete_file_acquisition_request(acquisition_id) # successful request return CommandResults(readable_output=f"file acquisition {acquisition_id} deleted successfully") # Start of Triage demisto calls def initiate_triage_acquisition_command(client: Client, args: Dict[str, Any]) -> CommandResults: """Demisto function to start a triage on the provided hosts via Demisto Args Args: client (Client): The HX client object. args (Dict[str, Any]): Demisto Arguments Returns: CommandResults: A demisto command result. """ acquisition_info: Dict = get_triage_acquisition(client, args) # Add hostname to the host info of acquisition_info if args.get("hostName", False): acquisition_info["host"]["hostname"] = args.get("hostName") # Add Integration Instance to the acquisition_info acquisition_info["instance"] = demisto.integrationInstance() readable = f'Triage Acquisition ID: {acquisition_info.get("_id")} on Instance: {acquisition_info.get("instance")} created.' return CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Triage", outputs=acquisition_info, outputs_key_field="_id", readable_output=readable, ) def list_host_acquisitions(client: Client, args: Dict[str, Any]) -> CommandResults: """Demisto call to get acq info for a host Args: client (Client): The HX client object. args (Dict[str, Any]): Demisto Arguments Raises: ValueError: A required parameter is not provided. Returns: CommandResults: A demisto command result. """ host_name = args.get("hostName", "") agent_id = args.get("agentId") if not host_name and not agent_id: raise ValueError("Please provide either agentId or hostName") if not agent_id: agent_id = get_agent_id_by_host_name(client, host_name) acquisition_info = client.host_acquisition_information_request(agent_id) headers_for_table = ["_id", "acq_type", "request_time", "state"] md_table = tableToMarkdown( name="FireEye HX Acquisitions", t=acquisition_info, headers=headers_for_table, removeNull=True, date_fields=["request_time"], ) return CommandResults( outputs_prefix="FireEyeHX.Host.Acquisitions.All", outputs=acquisition_info, readable_output=md_table, outputs_key_field="_id", ) def get_triage_acquisition_information(client: Client, args: Dict[str, Any]) -> CommandResults: """Demisto call to get information (Status, requested by, etc) from an HX Triage Args: client (Client): The HX client object. args (Dict[str, Any]): Demisto Arguments Raises: ValueError: A required parameter is not provided. Returns: CommandResults: A demisto command result. """ if not args.get("acquisitionId"): raise ValueError("Acquisition Id is required") acquisition_id = str(args.get("acquisitionId")) acquisition_info = client.triage_acquisition_information_request(acquisition_id) agent_id = acquisition_info.get("host", {}).get("_id", "") host_info = client.get_hosts_by_agentId_request(agent_id)["data"] hostname = host_info.get("hostname") # Add hostname to the host info of acquisition_info acquisition_info["host"]["hostname"] = hostname # Add Integration Instance to the acquisition_info acquisition_info["instance"] = demisto.integrationInstance() headers_for_table = [ "host", "_id", "state", "request_time", "finish_time", "instance", ] md_table = tableToMarkdown( name="FireEye HX Triage", t=acquisition_info, headers=headers_for_table, removeNull=True, date_fields=["request_time", "finish_time"], ) return CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Triage", outputs=acquisition_info, outputs_key_field="_id", readable_output=md_table, ) def delete_triage_acquisition_command(client: Client, args: Dict[str, Any]) -> CommandResults: """Demisto call to delete a triage acquisition Args: client (Client): The HX client object. args (Dict[str, Any]): Demisto Arguments Returns: CommandResults: A demisto command result. """ if "acquisitionId" not in args: raise ValueError("Acquisition Id is required") acquisition_id = str(args.get("acquisitionId")) client.delete_triage_acquisition_request(acquisition_id) # successful request return CommandResults(readable_output=f"Triage acquisition {acquisition_id} deleted successfully") def get_triage_acquisition_package(client: Client, args: Dict[str, Any]) -> list[CommandResults | dict[str, Any]]: """Demisto call to return a file result from a triage acquisition Args: client (Client): The HX client object. args (Dict[str, Any]): Demisto Arguments Raises: ValueError: Required parameters are not provided. Returns: list[CommandResults]: A list of Demisto command results. """ if not args.get("acquisitionId"): raise ValueError("Acquisition Id is required") acquisition_id = str(args.get("acquisitionId")) acquisition_info = client.triage_acquisition_information_request(acquisition_id) agent_id = acquisition_info.get("host", {}).get("_id", "") host_info = client.get_hosts_by_agentId_request(agent_id)["data"] hostname = host_info.get("hostname") # Add hostname to the host info of acquisition_info acquisition_info["host"]["hostname"] = hostname # Add Integration Instance to the acquisition_info acquisition_info["instance"] = demisto.integrationInstance() # if `state` equals to 'COMPLETE' if acquisition_info.get("state") == "COMPLETE": message = "Triage acquisition completed successfully." if acquisition_info.get("error_message"): message = acquisition_info.get("error_message", "Generic error message, no details provided.") # output file and acquisition information to the war room data = client.triage_acquisition_package_request(acquisition_id) return [ CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Triage", outputs_key_field="_id", outputs=acquisition_info, readable_output=f"{message}\nTriage acquisition ID: {acquisition_id}", ), fileResult(f"triage_{acquisition_id}_agent_{agent_id}_data.mans", data), ] # else return message for states in [ NEW, ERROR, QUEUED, RUNNING, FAILED ] state = acquisition_info.get("state") message = "Triage acquisition process not yet completed." if acquisition_info.get("error_message"): message = acquisition_info.get("error_message", "Generic error message, no details provided.") return [ CommandResults( outputs_prefix="FireEyeHX.Acquisitions.Triage", outputs_key_field="_id", outputs=acquisition_info, readable_output=f"{message}\nacquisition ID: {acquisition_id}\nstate: {state}", ) ] """ ALERTS """ def get_all_alerts_command(client: Client, args: Dict[str, Any]) -> CommandResults: """ returns a list of alerts, all results up to limit """ source = [] # add source type if args.get("MALsource"): source.append("mal") if args.get("EXDsource"): source.append("exd") if args.get("IOCsource"): source.append("ioc") if source: args["source"] = source sort_map = { "agentId": "agent._id", "conditionId": "condition._id", "eventAt": "event_at", "alertId": "_id", "matchedAt": "matched_at", "id": "_id", "reportedAt": "reported_at", } if args.get("sort"): args["sort"] = f"{sort_map.get(args['sort'])}+{args.get('sortOrder', 'ascending')}" if args.get("hostName"): args["agentId"] = get_agent_id_by_host_name(client, args.get("hostName", "")) args["limit"] = int(args.get("limit", "50")) alerts = get_alerts(client, args) # parse each alert to a record displayed in the human readable table alerts_entries = [get_alert_entry(alert) for alert in alerts] headers_for_table = ["Alert ID", "Reported", "Event Type", "Agent ID"] md_table = tableToMarkdown(name="FireEye HX Get Alerts", t=alerts_entries, headers=headers_for_table) registry_key = [] ips = [] files = [] for alert in alerts: if alert["event_type"] == "regKeyEvent": registry_key.append( { "Path": alert.get("event_values").get("regKeyEvent/path"), "Name": alert.get("event_values").get("regKeyEvent/valueName"), "Value": alert.get("event_values").get("regKeyEvent/value"), } ) elif alert["event_type"] == "fileWriteEvent": files.append( { "Name": alert.get("event_values", {}).get("fileWriteEvent/fileName"), "md5": alert.get("event_values", {}).get("fileWriteEvent/md5"), "Extension": alert.get("event_values", {}).get("fileWriteEvent/fileExtension"), "Path": alert.get("event_values", {}).get("fileWriteEvent/fullPath"), } ) elif alert["event_type"] == "ipv4NetworkEvent": ips.append({"Ipv4": alert.get("event_values", {}).get("ipv4NetworkEvent/remoteIP")}) results_outputs = assign_params(FireEyeHX={"Alerts": alerts}, RegistryKey=registry_key, File=files, Ip=ips) return CommandResults(outputs_key_field="_id", outputs=results_outputs, readable_output=md_table) def get_alert_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]: alert_id = int(args.get("alertId", "")) alert: Dict = client.get_alert_request(alert_id)["data"] alert_entry = get_alert_entry(alert) headers_for_table = ["Alert ID", "Reported", "Event Type", "Agent ID"] alert_table = tableToMarkdown(name=f"FireEye HX Get Alert # {alert_id}", t=alert_entry, headers=headers_for_table) event_type = alert.get("event_type") event_type = event_type if event_type else "NewEvent" event_type = re.sub("([a-z])([A-Z])", r"\g<1> \g<2>", event_type).title() event_table = tableToMarkdown(name=event_type, t=alert.get("event_values")) result = [ CommandResults( outputs_prefix="FireEyeHX.Alerts", outputs_key_field="_id", outputs=alert, readable_output=f"{alert_table}\n{event_table}", ) ] indicator = get_indicator_command_result(alert) if indicator: result.append(indicator) return result def suppress_alert_command(client: Client, args: Dict[str, Any]) -> CommandResults: """ returns a success message to the war room """ alert_id = int(args.get("alertId", "")) try: client.suppress_alert_request(alert_id) except Exception as e: if "404" in str(e): raise ValueError(f"Alert {alert_id} Not Found") else: raise ValueError(e) # no exceptions raised->successful request return CommandResults(readable_output=f"Alert {alert_id} suppressed successfully.") """ INDICATORS """ def get_indicators_command(client: Client, args: Dict[str, Any]) -> CommandResults: sort_map = { "category": "category", "activeSince": "active_since", "createdBy": "created_by", "alerted": "stats.alerted_agents", } if limit := args.get("limit"): args["limit"] = int(limit) if alerted := args.get("alerted"): args["alerted"] = alerted == "yes" if sort := args.get("sort"): args["sort"] = sort_map.get(sort) # get all results indicators = get_all_indicators( client=client, category=args.get("category"), search=args.get("searchTerm"), share_mode=args.get("shareMode"), sort=args.get("sort"), created_by=args.get("createdBy"), alerted=args.get("alerted"), limit=args.get("limit"), ) for_table = [get_indicator_entry(indicator) for indicator in indicators] headers_for_table = [ "OS", "Name", "Created By", "Active Since", "Category", "Signature", "Active Condition", "Hosts With Alerts", "Source Alerts", ] md_table = tableToMarkdown(name=f"FireEye HX Get Indicator- {args.get('name')}", t=for_table, headers=headers_for_table) return CommandResults( outputs_prefix="FireEyeHX.Indicators", outputs_key_field="_id", outputs=indicators, readable_output=md_table ) def get_indicator_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]: if not args.get("category") or not args.get("name"): raise ValueError("The category and name arguments are required") indicator = client.get_indicator_request(args.get("category"), args.get("name")) headers_for_table = [ "OS", "Name", "Created By", "Active Since", "Category", "Signature", "Active Condition", "Hosts With Alerts", "Source Alerts", ] md_table = tableToMarkdown( name=f"FireEye HX Get Indicator- {args.get('name')}", t=get_indicator_entry(indicator), headers=headers_for_table ) return [ CommandResults( outputs_prefix="FireEyeHX.Indicators", outputs_key_field="_id", outputs=indicator, readable_output=md_table ), get_indicator_conditions(client, args), ] def delete_indicator_command(client: Client, args: Dict[str, str]) -> CommandResults: # XSOAR yml makes sure the args exist indicator_name = args["indicator_name"] category = args["category"] human_readable_args = f"indicator {indicator_name} from the {category} category" try: client.delete_indicator(indicator_name, category) # raises on error human_readable = f"Successfully deleted {human_readable_args}" except DemistoException as e: message = None try: message = e.res.json().get("message") except JSONDecodeError: pass if not message: message = str(e) human_readable = f"Failed deleting {human_readable_args}: {message}" return CommandResults(readable_output=human_readable) def list_indicator_categories_command(client: Client, args: Dict[str, Any]) -> CommandResults: # The following may be None or int if limit := args.get("limit"): limit = int(limit) if offset := args.get("offset"): offset = int(offset) # The following may be None or bool if ui_signature_enabled := args.get("ui_signature_enabled"): ui_signature_enabled = argToBoolean(ui_signature_enabled) if ui_source_alerts_enabled := args.get("ui_source_alerts_enabled"): ui_source_alerts_enabled = argToBoolean(ui_source_alerts_enabled) try: response = client.list_indicator_categories( search=args.get("search"), name=args.get("name"), display_name=args.get("display_name"), retention_policy=args.get("retention_policy"), ui_edit_policy=args.get("ui_edit_policy"), ui_signature_enabled=ui_signature_enabled, ui_source_alerts_enabled=ui_source_alerts_enabled, share_mode=args.get("share_mode"), offset=offset, limit=limit, ) data = response.get("data", {}) entries = data.get("entries", []) readable_entries = [ { "Policy ID": entry.get("_id"), "Name": entry.get("name"), } for entry in entries ] return CommandResults( outputs_prefix="FireEyeHX.IndicatorCategory", outputs=entries, readable_output=tableToMarkdown(f"{len(readable_entries)} Indicator categories found", readable_entries), raw_response=response, ) except DemistoException as e: if message := (e.res or {}).get("message"): readable_output = f"Could not list categories. Error: {message}" else: readable_output = f"Could not list categories. Error: {e}" return CommandResults(readable_output=readable_output, raw_response=e.res) def append_conditions_command(client: Client, args: Dict[str, Any]) -> CommandResults: """ Append conditions to indicator no return value on successful request """ name = args.get("name") category = args.get("category") body = args.get("condition") if not name or not category or not body: raise ValueError("All of the following arguments are required -> ['name','category','condition']") body = body.replace(",", "\n") response = client.append_conditions_request(name, category, body) md = tableToMarkdown( name="The conditions were added successfully", t={"Name": name, "Category": category, "Conditions": body} ) return CommandResults(outputs_prefix="FireEyeHX.Conditions", outputs=response, readable_output=md) def delete_condition_command(client: Client, args: Dict[str, str]) -> CommandResults: # Mandatory args - always exist indicator_name = args["indicator_name"] category = args["category"] condition_type = args["type"] condition_id = args["condition_id"] human_readable_args = f"condition {condition_id} ({condition_type}) of indicator {indicator_name} ({category})".replace( "'", "" ) response = None try: response = client.delete_condition(indicator_name, category, condition_type, condition_id) # raises on failure human_readable = f"Successfully deleted {human_readable_args}" except DemistoException as e: message = None if e.res: response = e.res try: message = response.json().get("message") except (JSONDecodeError, AttributeError): pass if not message: message = str(e) human_readable = f"Failed deleting {human_readable_args}: {message}" return CommandResults(readable_output=human_readable, raw_response=response) def create_indicator_command(client: Client, args: Dict[str, Any]) -> CommandResults: """ Get new indicator details returns a success message to the war room """ category = args.get("category") payload = {} if args.get("display_name"): payload["display_name"] = args.get("display_name") if args.get("description"): payload["description"] = args.get("description") if args.get("platforms"): if isinstance(args.get("platforms"), list): payload["platforms"] = args.get("platforms") else: payload["platforms"] = [args.get("platforms")] response = client.new_indicator_request(category, payload) md_table = tableToMarkdown("FireEye HX New Indicator created successfully", {"ID": response.get("data").get("_id")}) return CommandResults( outputs_prefix="FireEyeHX.Indicators", outputs_key_field="_id", outputs=response.get("data"), readable_output=md_table, raw_response=response, ) """ SEARCHES """ def start_search_command(client: Client, args: Dict[str, Any]) -> tuple[CommandResults, bool, str]: if "searchId" not in args: demisto.debug("searchId is not in the args, starting a new search") list_of_args = ["agentsIds", "hostsNames", "hostSet", "hostSetName"] arg = oneFromList(list_of_args=list_of_args, args=args) if arg is False: raise ValueError("One of the following arguments is required -> [agentsIds, hostsNames, hostSet, hostSetName]") # organized the search body, the function checks if provided only one argument, # and returns dict with key of Host_name or Hosts body = organize_search_body_host(client, arg, {}) # checking if provided only one of these following arguments list_of_args = ["dnsHostname", "fileFullPath", "fileMD5Hash", "ipAddress", "fieldSearchName"] arg_for_query = oneFromList(list_of_args=list_of_args, args=args) if arg_for_query is False: raise ValueError( "One of the following arguments is required ->" " [dnsHostname, fileFullPath, fileMD5Hash, ipAddress, fieldSearchName]" ) # this function organize the query of the request body, and returns list of queries body["query"] = organize_search_body_query(arg_for_query, args) body["exhaustive"] = args.get("exhaustive") != "false" try: search_id = client.search_request(body)["data"]["_id"] demisto.debug(f"got the following search id: {search_id}") except Exception as e: raise ValueError(e) limit = int(args.get("limit", 1000)) search_id = str(args.get("searchId")) if args.get("searchId") else str(search_id) searchInfo = client.get_search_by_id_request(search_id)["data"] matched = searchInfo.get("stats", {}).get("search_state", {}).get("MATCHED", 0) pending = searchInfo.get("stats", {}).get("search_state", {}).get("PENDING", 0) running_state = searchInfo.get("stats", {}).get("running_state", {}) new_run = True for _state, count in running_state.items(): if count != 0: new_run = False break if searchInfo.get("state") != "STOPPED" and ((matched < int(limit) and pending != 0) or new_run): demisto.debug(f"search is not ready yet, running state is: {running_state}") return CommandResults(readable_output=f"Search started,\nSearch ID: {search_id}"), False, search_id demisto.debug("search is ready") return CommandResults(readable_output=f"Search started,\nSearch ID: {search_id}"), True, search_id def start_search_with_polling_command(client: Client, args: Dict[str, Any]) -> Union[CommandResults, List[CommandResults]]: return run_polling_command(client, args, "fireeye-hx-search", start_search_command, search_result_get_command, "searching") def get_search_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: if args.get("searchId"): searches_ids = sorted(args.get("searchId", "").split(","), reverse=True) response = [] for search_id in searches_ids: response.append(client.get_search_by_id_request(search_id)["data"]) else: offset = args.get("offset") or 0 limit = args.get("limit") or 50 state = args.get("state") hostSetId = args.get("hostSetId") actorUsername = args.get("actorUsername") sort = args.get("sort") response = client.get_search_list_request( offset=offset, limit=limit, state=state, host_set_id=hostSetId, actor_username=actorUsername, sort=sort )["data"]["entries"] for_table = [] for search in response: host_set = None if search.get("host_set"): host_set = search["host_set"].copy() del host_set["url"] for_table.append( { "Id": search.get("_id"), "State": search.get("state"), "Host Set": host_set, "Created By": search.get("create_actor"), "Created At": search.get("create_time"), "Updated By": search.get("update_actor"), "Updated At": search.get("update_time"), } ) headers_for_table = ["Id", "State", "Host Set", "Created By", "Created At", "Updated By", "Updated At"] md = tableToMarkdown(name="", t=for_table, headers=headers_for_table) return CommandResults(outputs_prefix="FireEyeHX.Search", outputs_key_field="_id", outputs=response, readable_output=md) def search_stop_command(client: Client, args: Dict[str, Any]) -> CommandResults: if not args.get("searchId"): raise ValueError("Search Id is must be") searches_ids = argToList(str(args.get("searchId"))) responses = [] md = "Results" for search_id in searches_ids: try: response = client.search_stop_request(search_id) md += f"\nSearch Id {search_id}: Success" responses.append(response["data"]) except Exception: md += f"\nSearch Id {search_id}: Not Found" return CommandResults(outputs_prefix="FireEyeHX.Search", outputs_key_field="_id", outputs=responses, readable_output=md) def search_result_get_command(client: Client, args: Dict[str, Any]) -> List[CommandResults]: if not args.get("searchId"): raise ValueError("Search Id is must be") demisto.debug(f"in get search results command with search id: {args.get('searchId')}") searches_ids = argToList(str(args.get("searchId"))) limit = args.get("limit") results: List[List[Dict]] = [] for search_id in searches_ids: result = client.search_result_get_request(search_id)["data"]["entries"] demisto.debug(f"result is: {result}") if result: results.append(result) commandsResults: List = [] for result in results: entries_amount = min(int(limit), len(result)) if limit else len(result) for entry in result[:entries_amount]: Title = f"Host Id {entry.get('host', {}).get('_id')}\nHost Name {entry.get('host', {}).get('hostname')}" for_table = [] for res in entry.get("results", []): for_table.append( {"Item Type": res.get("type"), "Summary": [f"**{k}:** {v}" for k, v in res.get("data", {}).items()]} ) md = tableToMarkdown(name=Title, t=for_table, headers=["Item Type", "Summary"]) commandsResults.append( CommandResults(outputs_prefix="FireEyeHX.Search", outputs_key_field="_id", outputs=entry, readable_output=md) ) if "stopSearch" in args: message = "" try: if args.get("stopSearch") == "stop": message = "Failed to stop search" client.search_stop_request(searches_ids[0]) message = "The search was stopped successfully" # no need to stop a search before deleting it. if args.get("stopSearch") == "stopAndDelete": message = "Failed to delete search" client.delete_search_request(searches_ids[0]) message = "The search was deleted successfully" except Exception as e: demisto.debug(f"{message}\n{e}") if len(commandsResults) > 0: commandsResults[0].readable_output += f"\n\n{message}" else: commandsResults.append(CommandResults(readable_output=message)) return commandsResults if commandsResults else [CommandResults(readable_output="No Results")] def search_delete_command(client: Client, args: Dict[str, Any]) -> CommandResults: search_ids = argToList(str(args.get("searchId"))) message = "Results" for search_id in search_ids: try: client.delete_search_request(search_id) message += f"\nSearch Id {search_id}: Deleted successfully" except Exception as e: if "404" in str(e): message += f"\nSearch Id {search_id}: Not Found" else: message += f"\nSearch Id {search_id}: Failed to delete search" return CommandResults(readable_output=message) """ FETCH INCIDENT """ def fetch_incidents(client: Client, args: Dict[str, Any]) -> List: last_run = demisto.getLastRun() alerts = [] # type: List[Dict[str, str]] fetch_limit = int(args.get("max_fetch") or "50") args["sort"] = "reported_at+ascending" args["limit"] = fetch_limit # Checks if this is the first call to a function or not if last_run and last_run.get("reported_at"): # Design the filterQuery argument with last reported_at, and convert it to urlEncoding query = query_fetch(reported_at=organize_reported_at(last_run.get("reported_at"))) demisto.debug(f"fetch-incident query -> {query}") args["filterQuery"] = urllib.parse.quote_plus(query) # Get all alerts with reported_at greater than last reported_at alerts = get_alerts(client, args) else: # Design the filterQuery argument, and convert it to urlEncoding first_fetch = args.get("first_fetch") if args.get("first_fetch") else "3 days" query = query_fetch(first_fetch=first_fetch) demisto.debug(f"fetch-incident query -> {query}") args["filterQuery"] = urllib.parse.quote_plus(query) # Receive alerts from last 3 days - if they are more than 50 return the 50 older alerts alerts = get_alerts(client, args) # Results are sorted in ascending order - the last alert holds the greatest time reported_at = alerts[-1].get("reported_at") if alerts else None # Parse the alerts as the incidents pattern = re.compile("([a-z])([A-Z])") incidents = [parse_alert_to_incident(alert, pattern) for alert in alerts] # Keeps the last reported_at for next time if reported_at is not None: demisto.setLastRun({"reported_at": reported_at}) return incidents """ POLLING """ def run_polling_command(client, args, cmd, post_func, get_func, t): ScheduledCommand.raise_error_if_not_supported() interval_in_secs = int(args.get("interval_in_seconds", 60)) type_id = TABLE_POLLING_COMMANDS[t]["type"] _, is_ready, item_id = post_func(client, args) if not is_ready: demisto.debug("still not ready") readable_output = f"{TABLE_POLLING_COMMANDS[t]['message']}{item_id}" if type_id not in args else None if not args.get(type_id): args[type_id] = item_id scheduled_command = ScheduledCommand( command=cmd, next_run_in_seconds=interval_in_secs, args=args, timeout_in_seconds=1800 ) # result with scheduled_command only - no update to the war room return CommandResults(readable_output=readable_output, scheduled_command=scheduled_command) if type_id not in args: args[type_id] = item_id return get_func(client, args) """ MAIN FUNCTION """ def main() -> None: """main function, parses params and runs command functions :return: :rtype: """ polling_commands = { "fireeye-hx-search": start_search_with_polling_command, "fireeye-hx-data-acquisition": data_acquisition_with_polling_command, "fireeye-hx-file-acquisition": file_acquisition_with_polling_command, } commands = { "fireeye-hx-get-host-information": get_host_information_command, "fireeye-hx-get-all-hosts-information": get_all_hosts_information_command, "fireeye-hx-host-containment": host_containment_command, "fireeye-hx-cancel-containment": cancel_containment_command, "fireeye-hx-get-host-set-information": get_host_set_information_command, "fireeye-hx-search": run_commands_without_polling, "fireeye-hx-search-list": get_search_list_command, "fireeye-hx-search-stop": search_stop_command, "fireeye-hx-search-result-get": search_result_get_command, "fireeye-hx-search-delete": search_delete_command, "fireeye-hx-append-conditions": append_conditions_command, "fireeye-hx-get-indicators": get_indicators_command, "fireeye-hx-get-indicator": get_indicator_command, "fireeye-hx-create-indicator": create_indicator_command, "fireeye-hx-data-acquisition": run_commands_without_polling, "fireeye-hx-delete-data-acquisition": delete_data_acquisition_command, "fireeye-hx-file-acquisition": run_commands_without_polling, "fireeye-hx-delete-file-acquisition": delete_file_acquisition_command, "fireeye-hx-get-data-acquisition": get_data_acquisition_command, "fireeye-hx-initiate-data-acquisition": initiate_data_acquisition_command, "fireeye-hx-get-alert": get_alert_command, "fireeye-hx-get-alerts": get_all_alerts_command, "fireeye-hx-suppress-alert": suppress_alert_command, "fireeye-hx-list-policy": list_policy_command, "fireeye-hx-list-host-set-policy": list_host_set_policy_command, "fireeye-hx-assign-host-set-policy": assign_host_set_policy_command, "fireeye-hx-delete-host-set-policy": delete_host_set_policy_command, "fireeye-hx-approve-containment": approve_containment_command, "fireeye-hx-list-containment": get_list_containment_command, "fireeye-hx-delete-indicator": delete_indicator_command, "fireeye-hx-list-indicator-category": list_indicator_categories_command, "fireeye-hx-delete-indicator-condition": delete_condition_command, "fireeye-hx-delete-host-set": delete_host_set_command, "fireeye-hx-create-host-set-static": create_static_host_set_command, "fireeye-hx-update-host-set-static": update_static_host_set_command, "fireeye-hx-create-host-set-dynamic": create_dynamic_host_set_command, "fireeye-hx-update-host-set-dynamic": update_dynamic_host_set_command, "fireeye-hx-triage-acquisition-delete": delete_triage_acquisition_command, "fireeye-hx-triage-acquisition-package-get": get_triage_acquisition_package, "fireeye-hx-triage-acquisition-get": get_triage_acquisition_information, "fireeye-hx-triage-acquisition-start": initiate_triage_acquisition_command, "fireeye-hx-host-acquisitions-list": list_host_acquisitions, } params = demisto.params() user_name = params.get("userName").get("identifier") password = params.get("userName").get("password") if not user_name or not password: raise ValueError("User Name and Password are required") # get the service API url base_url = params.get("server") validate_base_url(base_url) base_url = urljoin(base_url, "/hx/api/v3/") # if your Client class inherits from BaseClient, SSL verification is # handled out of the box by it, just pass ``verify_certificate`` to # the Client constructor verify_certificate = not demisto.params().get("insecure", False) # if your Client class inherits from BaseClient, system proxy is handled # out of the box by it, just pass ``proxy`` to the Client constructor proxy = params.get("proxy", False) command = demisto.command() args = demisto.args() client = None demisto.debug(f"Command being called is {demisto.command()}") try: client = Client(base_url=base_url, verify=verify_certificate, proxy=proxy, auth=(user_name, password)) if command == "test-module": get_alerts(client, {"limit": 1}) return_results("ok") elif command == "fetch-incidents": incidents = fetch_incidents(client, params) demisto.incidents(incidents) elif args.get("polling", "false") == "true": result = polling_commands[command](client, args) return_results(result) else: if command in ["fireeye-hx-search", "fireeye-hx-data-acquisition", "fireeye-hx-file-acquisition"]: args["cmd"] = command result = commands[command](client, args) return_results(result) # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}") finally: # perform logout to avoid open sessions if client: client.token_logout() """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()