Details
| ID | McAfee Active Response |
|---|---|
| Provider | Trellix |
| Category | Endpoint |
| From Version | 5.0.0 |
| Docker Image | demisto/dxl:1.0.0.10133006 |
| Supported Modules | Agentix XSIAM |
README
This integration was integrated and tested with version 2.1.0 of McAfee Active Response.
Playbooks
- Endpoint data collection
- MAR - Endpoint data collection
Use Cases
Capture and monitor events, files, host flows, process objects, context, and system state changes that may be indicators of attack (IoAs) or attack components lying dormant.
Create a McAfee DXL Certificate for McAfee Active Response
To configure an instance of McAfee Active Response, you first need to create a McAfee DXL certificate and add the certificate to the McAfee Intelligence Exchange integration.
Prerequisite
Before you create a McAfee DXL certificate, make sure you have a Broker CA certificate (brokercerts.crt).
- Generate a certificate signing request (CSR) with a tool such as CSR generator.
- Save the CSR and the private key as separate files.
- Access your McAfee ePolicy Orchestrator environment.
- Navigate to Server Settings.
- Select DXL Certificates and click Edit.
- Click Import CSR and select the CSR file you created previously.
- Select your certificate and click Export Certificate.
This generates a CRT file. - Add your certificate to Restrict Send Certificates and Restrict Receive Certificates.
- In Cortex XSOAR, search for McAfee Active Response integration and click Add instance.
-
Broker CA certificates content - The content of the
brokercerts.crt - Client certificates content - The content of the CRT file you created previously.
- Client private key path - The content of the private key file you created previously.
- Brokers urls - Broker server IP address, port: 8883.
- Use Load-Balancing Group - Should be enabled.
-
Broker CA certificates content - The content of the

Configure McAfee Active Response on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for McAfee Active Response.
- Click Add instance to create and configure a new integration instance.
- Name: a textual name for the integration instance.
- Broker CA certificates content (see
brokercerts.crtin the Deatiled Instructions section) - Client certificates content (see
client.crtin the Deatiled Instructions section) - Client private key content (see
client.keyin the Deatiled Instructions section) - Brokers URLs (CSV list in the form of - [ssl://][:port]) - Get the hostname and port from
brokerlist.propertiesfile in the Deatiled Instructions section. Note that the broker should be reachable from Cortex XSOAR server.
- Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
- Search endpoint data: mar-search
- Get a list of collectors: mar-collectors-list
- Search endpoint data crossed by multiple collectors: mar-search-multiple
- Get information for services: mar-search-services
- Get information for processes: mar-search-processes
- Get information for WinRegistry: mar-search-win-registry
- Get information for files: mar-search-files
- Get information for USB-connected devices: mar-search-usb-connected-storage-devices
- Get information for user profiles: mar-search-user-profiles
- Get information for scheduled tasks: mar-search-scheduled-tasks
- Get information for hosts: mar-search-host-info
1. Search endpoint data
Executes a search for endpoint data.
Base Command
mar-search
Input
| Argument Name | Description | Required |
|---|---|---|
| collector | The collector to query. | Required |
| prejection-collector | Prejection collector to return. By default, the prejection collector is equal to the collector. | Optional |
| outputs | CSV fields (outputs). Run the mar-collectors-list command to view all collectors and fields command for all collectors’ outputs. If not supplied, all outputs are displayed. |
Optional |
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR | unknown | MAR results in a given collector, e.g., '‘MAR.HostInfo`. For information about possible output paths, run the mar-collectors-list command. |
| MAR | unknown | MAR Results in a given collector, e.g., '‘MAR.HostInfo`. For information about possible output paths, run the mar-collectors-list command. |
Command Example
!mar-search collector=Processes
Context Example
{
"MAR": {
"Services": [
{
"status": "Running",
"description": "Base Filtering Engine",
"startuptype": "Automatic",
"created_at": "2019-02-06T17:16:25.193Z",
"user": "NT AUTHORITY\\LocalService",
"name": "BFE"
},
{
"status": "Running",
"description": "Diagnostic Policy Service",
"startuptype": "Automatic (Delayed Start)",
"created_at": "2019-02-06T17:16:25.193Z",
"user": "NT AUTHORITY\\LocalService",
"name": "DPS"
},
{
"status": "Stopped",
"description": "Encrypting File System (EFS)",
"startuptype": "Manual",
"created_at": "2019-02-06T17:16:25.193Z",
"user": "LocalSystem",
"name": "EFS"
}
]
}
}
Human Readable Output

2. Get a list of collectors
Returns a list of all collectors and their outputs.
Base Command
mar-collectors-list
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
Command Example
!mar-collectors-list
Human Readable Output

3. Search endpoint data crossed by multiple collectors
Searches endpoint data crossed by multiple collectors.
Base Command
mar-search-multiple
Input
| Argument Name | Description | Required |
|---|---|---|
| collectors | The collectors to query. | Required |
| filter_collector | The collector to filter by, e.g., HostInfo | Optional |
| filter-by | Field name (output) of filter_collector to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields. |
Optional |
| filter-operator | Filtering operatior | Optional |
| filter-value | Filtering value of the filter-by field |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Mar.SearchMultiple | unknown | The result of the search query. For information about possible output paths, run the mar-collectors-list command. |
Command Example
!mar-search-multiple collectors=Services,HostInfo
Context Example
{
"MAR": {
"SearchMultiple": [
{
"status": "Stopped",
"description": "Volume Shadow Copy",
"startuptype": "Manual",
"ip_address": "192.168.1.156",
"created_at": "2019-02-06T17:20:57.204Z",
"hostname": "WIN-AQ0LQQOG4Q7",
"user": "LocalSystem",
"os": "Microsoft Windows [Version 6.3.9600]",
"name": "VSS"
},
{
"status": "Running",
"description": "Network Store Interface Service",
"startuptype": "Automatic",
"ip_address": "192.168.1.156",
"created_at": "2019-02-06T17:20:57.204Z",
"hostname": "WIN-AQ0LQQOG4Q7",
"user": "NT Authority\\LocalService",
"os": "Microsoft Windows [Version 6.3.9600]",
"name": "nsi"
}
]
}
}
Human Readable Output

4. Get information for services
Returns services information from McAfee Active Response.
Base Command
mar-search-services
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors’ outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.Services.Name | unknown | Service name. |
| MAR.Services.Description | unknown | Service description. |
| MAR.Services.Status | unknown | Service status. |
| MAR.Services.Startuptype | unknown | Service startup type. |
| MAR.Services.User | unknown | Service user. |
Command Example
!mar-search-services
Context Example
{
"MAR": {
"Services": [
{
"Status": "Running",
"Description": "Base Filtering Engine",
"Startuptype": "Automatic",
"created_at": "2019-03-06T15:04:16.193Z",
"User": "NT AUTHORITY\\LocalService",
"Name": "BFE"
},
{
"Status": "Running",
"Description": "Diagnostic Policy Service",
"Startuptype": "Automatic (Delayed Start)",
"created_at": "2019-03-06T15:04:16.193Z",
"User": "NT AUTHORITY\\LocalService",
"Name": "DPS"
},
{
"Status": "Stopped",
"Description": "Encrypting File System (EFS)",
"Startuptype": "Manual",
"created_at": "2019-03-06T15:04:16.193Z",
"User": "LocalSystem",
"Name": "EFS"
}
]
}
}
Human Readable Output

5. Get information for processes
Returns processes information from McAfee Active Response.
Base Command
mar-search-processes
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.Processes.Name | unknown | Process name. |
| MAR.Processes.Id | unknown | Process ID. |
| MAR.Processes.Parentname | unknown | Process parent name. |
| MAR.Processes.Size | unknown | Process size. |
| MAR.Processes.Md5 | unknown | Process MD5 hash. |
| MAR.Processes.Sha1 | unknown | Process SHA-1 hash. |
| MAR.Processes.Cmdline | unknown | Process command line. |
| MAR.Processes.Imagepath | unknown | Process image path. |
| MAR.Processes.Kerneltime | unknown | Process kernel time. |
| MAR.Processes.Usertime | unknown | Process user time. |
| MAR.Processes.Uptime | unknown | Process up time. |
| MAR.Processes.User | unknown | Process user. |
| MAR.Processes.User_id | unknown | Process user ID. |
Command Example
!mar-search-processes
Context Example
{
"MAR": {
"Processes": [
{
"Uptime": 8468384,
"Imagepath": "C:\\WINDOWS\\SYSTEM32\\CSRSS.EXE",
"User_id": "S-1-5-18",
"Name": "CSRSS.EXE",
"Usertime": 3,
"created_at": "2019-02-07T09:16:39.195Z",
"Parentname": "-",
"Cmdline": "-",
"Sha1": "C79E4586989EBB8E8F8084B5EB49AFBFD243A625",
"User": "NT AUTHORITY\\SYSTEM",
"Kerneltime": 16,
"Size": 2048,
"Id": 336,
"Md5": "B2D3F07F5E8A13AF988A8B3C0A800880"
},
{
"Uptime": 8468383,
"Imagepath": "C:\\WINDOWS\\SYSTEM32\\WININIT.EXE",
"User_id": "S-1-5-18",
"Name": "WININIT.EXE",
"Usertime": "-",
"created_at": "2019-02-07T09:16:39.195Z",
"Parentname": "-",
"Cmdline": "wininit.exe",
"Sha1": "83D158A31A41C3FC37DB569F187108C754C629C8",
"User": "NT AUTHORITY\\SYSTEM",
"Kerneltime": "-",
"Size": 840,
"Id": 388,
"Md5": "D9516405E05F24EDCD90B1988FAF3948"
}
]
}
}
Human Readable Output

6. Get information for WinRegistry
Returns WinRegistry information from McAfee Active Response.
Base Command
mar-search-win-registry
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.WinRegistry.Keypath | unknown | WinRegistry key path. |
| MAR.WinRegistry.Keyvalue | unknown | WinRegistry key value. |
| MAR.WinRegistry.Valuedata | unknown | WinRegistry value data. |
| MAR.WinRegistry.Valuetype | unknown | WinRegistry value type. |
Command Example
!mar-search-win-registry
7. Get information for files
Returns file information from McAfee Active Response.
Base Command
mar-search-files
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.Files.Name | unknown | File name. |
| MAR.Files.Dir | unknown | File directory. |
| MAR.Files.Full_name | unknown | File full name. |
| MAR.Files.Size | unknown | File size. |
| MAR.Files.Last_write | unknown | File last write. |
| MAR.Files.MD5 | unknown | File MD5 hash. |
| MAR.Files.Sha1 | unknown | File SHA-1 hash. |
| MAR.Files.Created_at | unknown | Datetime the file was created. |
| MAR.Files.Deleted_at | unknown | Datetime the file was deleted. |
Command Example
!mar-search-files
8. Get information for USB-connected devices
Returns information for USB connected devices from McAfee Active Response.
Base Command
mar-search-usb-connected-storage-devices
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.UsbConnectedStorageDevices.Vendor_id | unknown | USB connected storage devices vendor ID. |
| MAR.UsbConnectedStorageDevices.Product_id | unknown | USB connected storage devices product ID. |
| MAR.UsbConnectedStorageDevices.Serial_number | unknown | USB connected storage devices serial number. |
| MAR.UsbConnectedStorageDevices.Device_type | unknown | USB connected storage devices type. |
| MAR.UsbConnectedStorageDevices.Guid | unknown | USB connected storage devices GUID. |
| MAR.UsbConnectedStorageDevices.Last_connection_time | unknown | USB connected storage devices last connection time. |
| MAR.UsbConnectedStorageDevices.User_name | unknown | USB connected storage devices user name. |
| MAR.UsbConnectedStorageDevices.Last_time_used_by_user | unknown | Last time USB connected storage devices were last used by a user. |
Command Example
!mar-search-usb-connected-storage-devices
9. Get information for user profiles
Returns user profile information from McAfee Active Response.
Base Command
mar-search-user-profiles
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.UserProfiles.Accountdisabled | unknown | User profile account disabled. |
| MAR.UserProfiles.Domain | unknown | User profile domain. |
| MAR.UserProfiles.Fullname | unknown | User profile full name. |
| MAR.UserProfiles.Installdate | unknown | User profile install date. |
| MAR.UserProfiles.Localaccount | unknown | User profile local account. |
| MAR.UserProfiles.Lockedout | unknown | User profile lockedout. |
| MAR.UserProfiles.Accountname | unknown | User profile account name. |
| MAR.UserProfiles.Sid | unknown | User profile SID. |
| MAR.UserProfiles.Passwordexpires | unknown | User profile password expired. |
Command Example
!mar-search-user-profiles
Context Example
{
"MAR": {
"UserProfiles": [
{
"Domain": "-",
"Installdate": "2017-10-02T06:15:20.000Z",
"Localaccount": "False",
"created_at": "2019-03-06T15:39:44.193Z",
"Sid": "S-1-5-80-3880006512-4290199581-1648723128-3569869737-3631323133",
"Accountname": "MSSQL$SQLEXPRESS",
"Lockedout": "-",
"Fullname": "-",
"Accountdisabled": "-",
"Passwordexpires": "-"
},
{
"Domain": "WIN-AQ0LQQOG4Q7",
"Installdate": "2017-09-17T02:20:46.000Z",
"Localaccount": "True",
"created_at": "2019-03-06T15:39:44.193Z",
"Sid": "S-1-5-21-2851129524-1971544412-1620677069-500",
"Accountname": "Administrator",
"Lockedout": "False",
"Fullname": "-",
"Accountdisabled": "False",
"Passwordexpires": "False"
},
{
"Domain": "WIN-AQ0LQQOG4Q7",
"Installdate": "-",
"Localaccount": "True",
"created_at": "2019-03-06T15:39:44.193Z",
"Sid": "S-1-5-21-2851129524-1971544412-1620677069-501",
"Accountname": "Guest",
"Lockedout": "False",
"Fullname": "-",
"Accountdisabled": "True",
"Passwordexpires": "False"
}
]
}
}
Human Readable Output

10. Get information for scheduled tasks
Returns scheduled task information from McAfee Active Response.
Base Command
mar-search-scheduled-tasks
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by (e.g. ip_address). Run mar-collectors-list to view all collectors and fields command for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.ScheduledTasks.Folder | unknown | Scheduled tasks folder. |
| MAR.ScheduledTasks.Taskname | unknown | Scheduled tasks name. |
| MAR.ScheduledTasks.Status | unknown | Scheduled tasks status. |
| MAR.ScheduledTasks.Last_run | unknown | Scheduled tasks last run |
| MAR.ScheduledTasks.Username | unknown | Scheduled tasks user name. |
| MAR.ScheduledTasks.Schedule_on | unknown | Scheduled tasks schedule on. |
Command Example
!mar-search-scheduled-tasks
Context Example
{
"MAR": {
"ScheduledTasks": [
{
"Status": "Ready",
"Username": "SYSTEM",
"created_at": "2019-03-06T15:41:29.195Z",
"Schedule_on": "Log On, Daily",
"Last_run": "2019-03-05T16:54:08.000Z",
"Taskname": "GoogleUpdateTaskMachineCore",
"Folder": "/"
},
{
"Status": "Disabled",
"Username": "SYSTEM",
"created_at": "2019-03-06T15:41:29.195Z",
"Schedule_on": "Idle",
"Last_run": "2017-09-17T02:32:59.000Z",
"Taskname": ".NET Framework NGEN v4.0.30319 64 Critical",
"Folder": "/Microsoft/Windows/.NET Framework"
}
]
}
}
Human Readable Output

11. Get information for hosts
Returns host information from McAfee Active Response.
Base Command
mar-search-host-info
Input
| Argument Name | Description | Required |
|---|---|---|
| filter-by | Field name (output) to filter by, e.g., ip_address. Run the mar-collectors-list command to view all collectors and fields for all collectors outputs. |
Optional |
| filter-operator | Filtering operator. | Optional |
| filter-value | Filtering value of the filter-by field. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| MAR.HostInfo.Hostname | unknown | Host name. |
| MAR.HostInfo.Ip_address | unknown | Host IP address. |
| MAR.HostInfo.Os | unknown | Host operating system. |
Command Example
!mar-search-host-info
Context Example
{
"MAR": {
"HostInfo": [
{
"Os": "Microsoft Windows [Version 6.3.9600]",
"created_at": "2019-03-06T15:44:10.192Z",
"Hostname": "WIN-AQ0LQQOG4Q7",
"Ip_address": "192.168.1.156"
}
]
}
}
Human Readable Output

Configuration parameters
broker_ca_bundle— Broker CA certificates content (see `brokercerts.crt` in instructions) (required)cert_file— Client certificates content (see `client.crt` in instructions) (required)private_key— Client private key content (see `client.key` in instructions) (required)broker_urls— Brokers urls (comma separated list in the form of - [ssl://]<hostname>[:port]) - get hostname & port from `brokerlist.properties` file in instructions. Note that the broker should be reachable from demisto server (required)
Commands (11)
-
mar-collectors-listReturns a list of all collectors and their outputs
-
mar-searchSearch endpoint data
-
mar-search-filesGets files information from McAfee Active Response
-
mar-search-host-infoGets host information from McAfee Active Response
-
mar-search-multipleSearch endpoint data crossed by multiple collectors
-
mar-search-processesGets processes information from McAfee Active Response
-
mar-search-scheduled-tasksGets scheduled tasks information from McAfee Active Response
-
mar-search-servicesGets services information from McAfee Active Response
-
mar-search-usb-connected-storage-devicesGets Usb connected devices information from McAfee Active Response
-
mar-search-user-profilesGets user profiles information from McAfee Active Response
-
mar-search-win-registryGets WinRegistry information from McAfee Active Response
import os import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 from dxlclient.broker import Broker from dxlclient.client import DxlClient from dxlclient.client_config import DxlClientConfig from dxlmarclient import ConditionConstants, MarClient, OperatorConstants, ProjectionConstants FILTER_OPERATORS = { "GreaterEqualThan": OperatorConstants.GREATER_EQUAL_THAN, "GreaterThan": OperatorConstants.GREATER_THAN, "LessEqualThan": OperatorConstants.LESS_EQUAL_THAN, "LessThan": OperatorConstants.LESS_THAN, "Equals": OperatorConstants.EQUALS, "Contains": OperatorConstants.CONTAINS, "StartWith": OperatorConstants.STARTS_WITH, "EndsWith": OperatorConstants.ENDS_WITH, "Before": OperatorConstants.BEFORE, "After": OperatorConstants.AFTER, } MAR_COLLECTORS = { "CommandLineHistory": ["user", "id"], # according to docs also includes 'CommandLine' "CurrentFlow": [ "local_ip", "local_port", "remote_ip", "remote_port", "status", "process_id", "user", "user_id", "proto", "md5", "sha1", ], "DNSCache": ["hostname", "ipaddress"], "EnvironmentVariables": ["username", "process_id", "name", "value"], "Files": [ "name", "dir", "full_name", "size", "last_write", "md5", "sha1", "created_at", "deleted_at", ], "HostEntries": ["hostname", "ipaddress"], "HostInfo": ["hostname", "ip_address", "os"], "InstalledCertificates": ["issued_to", "issued_by", "expiration_date", "purposes", "purposes_extended", "friendly_name"], "InstalledDrivers": ["displayname", "description", "last_modified_date", "name", "servicetype", "startmode", "state", "path"], "InstalledUpdates": ["description", "hotfix_id", "install_date", "installed_by"], "InteractiveSessions": ["userid", "name"], "LocalGroups": ["groupname", "groupdomain", "groupdescription", "islocal", "sid"], "LoggedInUsers": ["id", "userdomain", "username"], # according to docs also includes 'flags' "NetworkFlow": [ "src_ip", "src_port", "dst_ip", "dst_port", "time", "status", "process", "process_id", "user", "user_id", "proto", "direction", "ip_class", "seq_number", "src_mac", "dst_mac", "md5", "sha1", ], "NetworkInterfaces": [ "bssid", "displayname", "gwipaddress", "gwmacaddress", "ipaddress", "ipprefix", "macaddress", "name", "ssid", "type", "wifisecurity", ], "NetworkSessions": ["computer", "user", "client", "file", "idletime"], "NetworkShares": ["name", "description", "path"], # according to docs also includes 'thread_count', 'parentId' "Processes": [ "name", "id", "parentname", "size", "md5", "sha1", "cmdline", "imagepath", "kerneltime", "usertime", "uptime", "user", "user_id", ], # according to docs also includes 'nextruntime', 'task_run', 'log_on_type' "ScheduledTasks": ["folder", "taskname", "status", "last_run", "username", "schedule_on"], "Services": ["description", "name", "startuptype", "status", "user"], "Software": ["displayname", "installdate", "publisher", "version"], "Startup": ["caption", "command", "description", "name", "user"], "UsbConnectedStorageDevices": [ "vendor_id", "product_id", "serial_number", "device_type", "guid", "last_connection_time", "user_name", "last_time_used_by_user", ], "UserProfiles": [ "accountdisabled", "domain", "fullname", "installdate", "localaccount", "lockedout", "accountname", "sid", "passwordexpires", ], "WinRegistry": ["keypath", "keyvalue", "valuedata", "valuetype"], } broker_ca_bundle = "./brokercerts.crt" cert_file = "./cert_file.crt" private_key = "./private_key.key" broker_urls = [] # type: List[Broker] def create_error_entry(contents): return {"ContentsFormat": formats["text"], "Type": entryTypes["error"], "Contents": "Error - " + contents} def create_entry(header, contents, table, context={}, headers=None): return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": contents, "ReadableContentsFormat": formats["markdown"], "HumanReadable": tableToMarkdown(header, table, headers) if table else "No result were found", "EntryContext": context, } def translate_dict(d, translator): res = {} for key, value in d.items(): new_key = translator.get(key, key) res[new_key] = value return res # translate_list - map each lst dict by translator def translate_list(lst, translator): return [translate_dict(d, translator) for d in lst] def get_client_config(): config = DxlClientConfig( broker_ca_bundle=broker_ca_bundle, cert_file=cert_file, private_key=private_key, brokers=[Broker.parse(url) for url in broker_urls], ) config.connect_retries = 1 config.reconnect_delay = 1 config.reconnect_delay_max = 10 return config def test(): config = get_client_config() demisto.info("######## config created ########") with DxlClient(config) as client: client.connect() demisto.info("######## client connected ########") client.disconnect() demisto.info("######## client disconnected ########") MarClient(client) demisto.info("######## client MAR client created ########") def extract_item_output(item, capitalize): output = item["output"] res = {"created_at": item["created_at"]} # map <CollectorName>|<OutputName> to <OutputName> for key, value in output.items(): splited_key = key.split("|") if len(splited_key) > 1: new_key = splited_key[1] else: new_key = splited_key[0] if capitalize: new_key = new_key.capitalize() res[new_key] = value or "-" return res def search_result_to_table(search_result, capitalize=False): items = search_result["items"] table = [extract_item_output(item, capitalize) for item in items] return table def get_projection(collector, outputs): return {ProjectionConstants.NAME: collector, ProjectionConstants.OUTPUTS: outputs or MAR_COLLECTORS.get(collector)} def search(collector, projection_collector, outputs, filter_by, filter_operator, filter_value): config = get_client_config() with DxlClient(config) as client: client.connect() mar_client = MarClient(client) if not filter_by and not filter_operator and not filter_value: result_context = mar_client.search( projections=[{ProjectionConstants.NAME: collector, ProjectionConstants.OUTPUTS: outputs}] ) else: if not filter_by or not filter_operator or not filter_value: raise Exception("you must specify filter-by, filter-operator & filter-value (or specify none of them)") else: result_context = mar_client.search( projections=[{ProjectionConstants.NAME: projection_collector, ProjectionConstants.OUTPUTS: outputs}], conditions={ ConditionConstants.OR: [ { ConditionConstants.AND: [ { ConditionConstants.COND_NAME: collector, ConditionConstants.COND_OUTPUT: filter_by, ConditionConstants.COND_OP: FILTER_OPERATORS[filter_operator], ConditionConstants.COND_VALUE: filter_value, } ] } ] }, ) if result_context.has_results: return result_context.get_results() return None def search_multiple(collectors, filter_collector, filter_by, filter_operator, filter_value): config = get_client_config() with DxlClient(config) as client: client.connect() mar_client = MarClient(client) if not filter_collector: result_context = mar_client.search(projections=[get_projection(c, None) for c in collectors]) else: if not filter_by or not filter_operator or not filter_value: raise Exception( "you must specify filter-by, filter-operator & filter-value when you provide filter_collector argument" ) else: result_context = mar_client.search( projections=[get_projection(c, None) for c in collectors], conditions={ ConditionConstants.OR: [ { ConditionConstants.AND: [ { ConditionConstants.COND_NAME: filter_collector, ConditionConstants.COND_OUTPUT: filter_by, ConditionConstants.COND_OP: FILTER_OPERATORS[filter_operator], ConditionConstants.COND_VALUE: filter_value, } ] } ] }, ) if result_context.has_results: return result_context.get_results() return None def search_wrapper(collector, projection_collector, outputs_str, filter_by, filter_operator, filter_value, capitalize=False): demisto.info("######## executing " + demisto.command() + " ########") try: if outputs_str: outputs = outputs_str.split(",") else: # get all outputs outputs = MAR_COLLECTORS.get(collector) result = search(collector, projection_collector, outputs, filter_by, filter_operator, filter_value) except Exception as ex: return create_error_entry(str(ex)) if not result: return "No items were found" table = search_result_to_table(result, capitalize) context = {"MAR." + collector: table} demisto.info("######## " + demisto.command() + " command ends ########") return create_entry("Search Result For " + collector, result, table, context) def search_multiple_wrapper(collectors, filter_collector, filter_by, filter_operator, filter_value): try: result = search_multiple(collectors, filter_collector, filter_by, filter_operator, filter_value) except Exception as ex: return create_error_entry(str(ex)) if not result: return "No items were found" table = search_result_to_table(result) context = {"MAR.SearchMultiple": table} return create_entry("Search-Multiple Results", result, table, context) def mar_collectors_list(): collectors_table = [{"Name": c, "Outputs": ", ".join(MAR_COLLECTORS[c])} for c in MAR_COLLECTORS] return create_entry("Collectors", collectors_table, collectors_table, {}, ["Name", "Outputs"]) def validate_certificates_format(): if "-----BEGIN PRIVATE KEY-----" not in demisto.params()["private_key"]: # guardrails-disable-line return_error("The private key content seems to be incorrect as it doesn't start with -----BEGIN PRIVATE KEY-----") if "-----END PRIVATE KEY-----" not in demisto.params()["private_key"]: return_error("The private key content seems to be incorrect as it doesn't end with -----END PRIVATE KEY-----") if "-----BEGIN CERTIFICATE-----" not in demisto.params()["cert_file"]: return_error( "The client certificates content seem to be incorrect as they don't start with '-----BEGIN CERTIFICATE-----'" ) if "-----END CERTIFICATE-----" not in demisto.params()["cert_file"]: return_error("The client certificates content seem to be incorrect as it doesn't end with -----END CERTIFICATE-----") if not demisto.params()["broker_ca_bundle"].lstrip(" ").startswith("-----BEGIN CERTIFICATE-----"): return_error("The broker certificate seem to be incorrect as they don't start with '-----BEGIN CERTIFICATE-----'") if not demisto.params()["broker_ca_bundle"].rstrip(" ").endswith("-----END CERTIFICATE-----"): return_error("The broker certificate seem to be incorrect as they don't end with '-----END CERTIFICATE-----'") def main(): global broker_urls broker_urls = demisto.params()["broker_urls"].split(",") try: with open(broker_ca_bundle, "w") as text_file: text_file.write(demisto.params()["broker_ca_bundle"]) with open(cert_file, "w") as text_file: text_file.write(demisto.params()["cert_file"]) # lgtm [py/clear-text-storage-sensitive-data] with open(private_key, "w") as text_file: text_file.write(demisto.params()["private_key"]) args = demisto.args() if demisto.command() == "test-module": demisto.info("######## executing test command ########") test() demisto.results("ok") sys.exit(0) elif demisto.command() == "mar-search": results = search_wrapper( args.get("collector"), args.get("projection-collector", args.get("collector")), args.get("outputs"), args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-multiple": results = search_multiple_wrapper( args.get("collectors").split(","), args.get("filter_collector"), args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-collectors-list": results = mar_collectors_list() demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-processes": results = search_wrapper( "Processes", "Processes", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-services": results = search_wrapper( "Services", "Services", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-win-registry": results = search_wrapper( "WinRegistry", "WinRegistry", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True, ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-files": results = search_wrapper( "Files", "Files", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-usb-connected-storage-devices": results = search_wrapper( "UsbConnectedStorageDevices", "UsbConnectedStorageDevices", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True, ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-user-profiles": results = search_wrapper( "UserProfiles", "UserProfiles", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True, ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-scheduled-tasks": results = search_wrapper( "ScheduledTasks", "ScheduledTasks", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True, ) demisto.results(results) sys.exit(0) elif demisto.command() == "mar-search-host-info": results = search_wrapper( "HostInfo", "HostInfo", "", args.get("filter-by"), args.get("filter-operator"), args.get("filter-value"), True ) demisto.results(results) sys.exit(0) except Exception as error: validate_certificates_format() return_error(str(error)) finally: os.remove(broker_ca_bundle) os.remove(cert_file) os.remove(private_key) if __name__ in ["__main__", "__builtin__", "builtins"]: main()