Traps Deprecated
Deprecated. Use CortexXDR instead.
Endpoint · Palo Alto Networks Traps (Deprecated)
Details
| ID | Traps |
|---|---|
| Provider | Palo Alto Networks |
| Category | Endpoint |
| From Version | 5.0.0 |
| Docker Image | demisto/auth-utils:1.0.0.76157 |
README
Deprecated. Use CortexXDR instead. Use the Palo Alto Networks Traps integration to initiate scans, retrieve files from events, isolate endpoints, quarantine files, and manage the allow list and block list.
Traps Playbooks
- Traps Retrieve And Download Files
- Traps Scan Endpoint
Get Your API Key and Application ID
You will need to provide the API key and Application ID when configuring an instance of the Traps integration in Cortex XSOAR.
NOTE: This procedure requires Super User privileges.
- Access your Traps TMS UI.
- Click the settings button and select API Keys.
- To create new API Key click the Add button.
- Copy and save the entire text of your API key as you will not be able to access it again, and the Application ID.
Configure Traps on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for Traps.
- Click Add instance to create and configure a new integration instance.
- Name
- Fetch incidents
- Server URL
- Application ID
- Private Key
- Trust any certificate (not secure)
- Use system proxy settings
- Click Test to validate the new instance.
Commands
You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.
- Get endpoint details: traps-get-endpoint-by-id
- Execute a file retrieve operation / SAM on an agent: traps-endpoint-files-retrieve
- Scan an endpoint: traps-endpoint-scan
- Modify details for an event: traps-event-update
- Modify details for multiple events: traps-event-bulk-update-status
- Add a file hash to the block list: traps-hash-blacklist
- Remove a file hash from the block list: traps-hash-blacklist-remove
- Return a file hash to the block list: traps-hashes-blacklist-status
- Quarantine an event: traps-event-quarantine
- Isolate an endpoint: traps-endpoint-isolate
- Get the result of a quarantine operation: traps-event-quarantine-result
- Get the result of an isolate operation: traps-endpoint-isolate-status
- Get the results of an endpoint file retrieve operation: traps-endpoint-files-retrieve-result
- Get the results of an endpoint scan operation: traps-endpoint-scan-result
1. Get endpoint details
Returns details for the specified endpoint.
Base Command
traps-get-endpoint-by-id
Input
| Argument Name | Description | Required |
|---|---|---|
| endpoint_id | Endpoint ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.Endpoint.ID | String | The ID of the endpoint. |
| Traps.Endpoint.Name | String | The name of the endpoint. |
| Traps.Endpoint.Domain | date | The domain of the endpoint. |
| Traps.Endpoint.Platform | String | The OS of the endpoint. |
| Traps.Endpoint.Status | String | The status of the endpoint. |
| Traps.Endpoint.IP | String | The IP address of the endpoint. |
| Traps.Endpoint.ComputerSid | String | The computer SID. |
| Traps.Endpoint.IsCompromised | String | Whether the endpoint is compromised. |
| Traps.Endpoint.OsVersion | String | The version of the OS on the endpoint. |
| Traps.Endpoint.OsProductType | String | The OS type of the endpoint. |
| Traps.Endpoint.OsProductName | String | The name of the OS on the endpoint. |
| Traps.Endpoint.Is64 | String | The bitness of the OS on the endpoint. |
| Traps.Endpoint.LastSeen | String | The date/time of the last active ping. |
| Traps.Endpoint.LastUser | String | The last active user on the machine. |
Command Example
!traps-get-endpoint-by-id endpoint_id="d3339851f18f470182bf2bf98ad5db4b"
Context Example
{
"Traps.Endpoint": {
"ComputerSid": "S-1-5-21-202186053-2642234773-3690463397",
"Domain": "WORKGROUP",
"ID": "d3339851f18f470182bf2bf98ad5db4b",
"IP": "172.31.33.227",
"Is64": true,
"IsCompromised": false,
"LastSeen": "2019-10-03T09:06:40.000Z",
"LastUser": "Administrator",
"Name": "EC2AMAZ-8IEUJEN",
"OsProductName": "",
"OsProductType": "server",
"OsVersion": "10.0.14393",
"Platform": "windows",
"Status": "active"
}
}
Human Readable Output
Endpoint d3339851f18f470182bf2bf98ad5db4b data:
| Computer Sid | Domain | ID | IP | Is 64 | Is Compromised | Last Seen | Last User | Name | Os Product Name | Os Product Type | Os Version | Platform | Status |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| S-1-5-21-202186053-2642234773-3690463397 | WORKGROUP | d3339851f18f470182bf2bf98ad5db4b | 172.31.33.227 | true | false | 2019-10-03T09:06:40.000Z | Administrator | EC2AMAZ-8IEUJEN | server | 10.0.14393 | windows | active |
2. Execute a file retrieve operation / SAM on an agent
Executes a file retrieve operation / SAM on the specified agent.
Base Command
traps-endpoint-files-retrieve
Input
| Argument Name | Description | Required |
|---|---|---|
| endpoint_id | The ID of the endpoint. | Required |
| file_name | The name of the file to retrieve (including path). | Required |
| event_id | The ID of the event. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.FileRetrieve.EndpointID | String | The ID of the endpoint. |
| Traps.FileRetrieve.OperationID | String | The ID of the operation. |
| Traps.FileRetrieve.Type | String | The type of operation. |
Command Example
!traps-endpoint-files-retrieve endpoint_id="d3339851f18f470182bf2bf98ad5db4b" file_name="C:\\Program Files
(x86)\\Notepad++\\notepad++.exe" event_id="1cfb8fac7b504dc9894eabb9eb33de73"
Context Example
{
"Traps.FileRetrieve": {
"EndpointID": "d3339851f18f470182bf2bf98ad5db4b",
"OperationID": "3f7d6e86e5bd11e9acbf0245d8e950da",
"Type": "files-retrieve"
}
}
Human Readable Output
Files retrieve command on endpoint: d3339851f18f470182bf2bf98ad5db4b received
| Endpoint ID | Operation ID | Type |
|---|---|---|
| d3339851f18f470182bf2bf98ad5db4b | 3f7d6e86e5bd11e9acbf0245d8e950da | files-retrieve |
3. Scan an endpoint
Performs a scan operation on the specified endpoint.
Base Command
traps-endpoint-scan
Input
| Argument Name | Description | Required |
|---|---|---|
| endpoint_id | The ID of the endpoint. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.Scan.EndpointID | String | The ID of the endpoint. |
| Traps.Scan.OperationID | String | The ID of the operation. |
| Traps.Scan.Type | String | The type of operation. |
Command Example
!traps-endpoint-scan endpoint_id="d3339851f18f470182bf2bf98ad5db4b"
Context Example
{
"Traps.Scan": {
"EndpointID": "d3339851f18f470182bf2bf98ad5db4b",
"OperationID": "404d5231e5bd11e9acbf0245d8e950da",
"Type": "endpoint-scan"
}
}
Human Readable Output
Scan command on endpoint: d3339851f18f470182bf2bf98ad5db4b received
| Endpoint ID | Operation ID | Type |
|---|---|---|
| d3339851f18f470182bf2bf98ad5db4b | 404d5231e5bd11e9acbf0245d8e950da | endpoint-scan |
4. Modify details for an event
Modifies the status and adds a comment to an existing event.
Base Command
traps-event-update
Input
| Argument Name | Description | Required |
|---|---|---|
| event_id | The ID of the event to modify. | Required |
| status | The new status for the event. | Optional |
| comment | A comment for the event. | Optional |
Context Output
There are no context output for this command.
Command Example
!traps-event-update event_id="53edb3fa9a3b4b83bcf168390a2ec08d" status="new"
Human Readable Output
Event: 53edb3fa9a3b4b83bcf168390a2ec08d was updated
New status: new
5. Modify details for multiple events
Modifies the status of multiple events.
Base Command
traps-event-bulk-update-status
Input
| Argument Name | Description | Required |
|---|---|---|
| event_ids | A comma-separated list of IDs for events to modify. | Required |
| status | The new status for the event. | Required |
Context Output
There are no context output for this command.
Command Example
!traps-event-bulk-update-status event_ids="df4e60a62515482f98c8ef37e74363df,cfe4d15aca924bfcb7d2fc629b696bdd"
status="new"
Context Example
{}
Human Readable Output
Successfully updated
**No entries.**
Failed to update
**No entries.**
Ignored
| Event ID |
|---|
| cfe4d15aca924bfcb7d2fc629b696bdd |
| df4e60a62515482f98c8ef37e74363df |
6. Add a file hash to the block list
Adds the specified file hash to the block list.
Base Command
traps-hash-blacklist
Input
| Argument Name | Description | Required |
|---|---|---|
| hash_id | The SHA256 hash to add to the block list. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.File.BlacklistStatus | String | The status of the file hash ("blacklisted" or "none"). |
| Traps.File.SHA256 | String | The SHA256 hash of the file. |
Command Example
!traps-hash-blacklist hash_id="1111111111111111111111111111111111111111111111111111111111111111"
Context Example
{
"Traps.File": {
"BlacklistStatus": "blacklisted",
"SHA256": "1111111111111111111111111111111111111111111111111111111111111111"
}
}
Human Readable Output
Successfully blacklisted: 1111111111111111111111111111111111111111111111111111111111111111
7. Remove a file hash from the block list
Removes the specified file hash from the block list.
Base Command
traps-hash-blacklist-remove
Input
| Argument Name | Description | Required |
|---|---|---|
| hash_id | The SHA256 hash to remove from the block list. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.File.BlacklistStatus | String | The status of the file hash ("blacklisted" or "none"). |
| Traps.File.SHA256 | String | The SHA256 hash of the file. |
Command Example
!traps-hash-blacklist-remove
hash_id="1111111111111111111111111111111111111111111111111111111111111111"
Context Example
{
"Traps.File": {
"BlacklistStatus": "none",
"SHA256": "1111111111111111111111111111111111111111111111111111111111111111"
}
}
Human Readable Output
Successfully removed 1111111111111111111111111111111111111111111111111111111111111111 from block list
8. Return a file hash to the block list
Returns the block list status of the specified file hashes.
Base Command
traps-hashes-blacklist-status
Input
| Argument Name | Description | Required |
|---|---|---|
| hash_ids | A comma-separated list of SHA256 file hashes for which to return the block list status. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.File.BlacklistStatus | String | The block list status of the file hash. Can be "blacklisted" or "none". |
| Traps.File.SHA256 | String | The SHA256 hash of the file. |
Command Example
!traps-hashes-blacklist-status
hash_ids="5616ff15b3f5df4e18d28771ccdae19173873009f2318761aa9f9e573b9d9acc,360b12ccfa33c6d2021bf34162b111ffc2f5939b0524b2e045cd682d93318d69"
Context Example
{
"Traps.File": [
{
"BlacklistStatus": "blacklisted",
"SHA256": "360b12ccfa33c6d2021bf34162b111ffc2f5939b0524b2e045cd682d93318d69"
},
{
"BlacklistStatus": "none",
"SHA256": "5616ff15b3f5df4e18d28771ccdae19173873009f2318761aa9f9e573b9d9acc"
}
]
}
Human Readable Output
Hashes status:
| Blacklist Status | SHA256 |
|---|---|
| blacklisted | 360b12ccfa33c6d2021bf34162b111ffc2f5939b0524b2e045cd682d93318d69 |
| none | 5616ff15b3f5df4e18d28771ccdae19173873009f2318761aa9f9e573b9d9acc |
9. Quarantine an event
Creates a quarantine entry for the specified event.
Base Command
traps-event-quarantine
Input
| Argument Name | Description | Required |
|---|---|---|
| event_id | The ID of the event for which to create a quarantine entry.. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.Quarantine.EventID | String | The ID of the event. |
| Traps.Quarantine.OperationID | String | The ID of the operation. |
| Traps.Quarantine.Type | String | The type of operation. |
Command Example
!traps-event-quarantine event_id="19903a443a47441a86c92c3aea5abb30"
Context Example
{
"Traps.Quarantine": [
{
"EventID": "19903a443a47441a86c92c3aea5abb30",
"OperationID": "42185783e5bd11e9acbf0245d8e950da",
"Type": "event-quarantine"
}
]
}
Human Readable Output
Quarantine command on event: 19903a443a47441a86c92c3aea5abb30 received
| Event ID | Operation ID | Type |
|---|---|---|
| 19903a443a47441a86c92c3aea5abb30 | 42185783e5bd11e9acbf0245d8e950da | event-quarantine |
10. Isolate an endpoint
Isolates the specified endpoint.
Base Command
traps-endpoint-isolate
Input
| Argument Name | Description | Required |
|---|---|---|
| endpoint_id | The ID of the endpoint to isolate. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.Isolate.EndpointID | String | The ID of the endpoint. |
| Traps.Isolate.OperationID | String | The ID of the operation. |
| Traps.Isolate.Type | String | The type of operation. |
Command Example
!traps-endpoint-isolate endpoint_id=d3339851f18f470182bf2bf98ad5db4b
Context Example
{
"Traps.Isolate": {
"EndpointID": "d3339851f18f470182bf2bf98ad5db4b",
"OperationID": "4278ac6ce5bd11e9acbf0245d8e950da",
"Type": "endpoint-isolate"
}
}
Human Readable Output
Isolate command on endpoint d3339851f18f470182bf2bf98ad5db4b received
| Endpoint ID | Operation ID | Type |
|---|---|---|
| d3339851f18f470182bf2bf98ad5db4b | 4278ac6ce5bd11e9acbf0245d8e950da | endpoint-isolate |
11. Get the result of a quarantine operation
Returns the result of the specified quarantine operation.
Base Command
traps-event-quarantine-result
Input
| Argument Name | Description | Required |
|---|---|---|
| operation_id | The ID of the operation for which to get the result of the quarantine operation. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.QuarantineResult.SHA256 | String | The SHA256 hash of the file. |
| Traps.QuarantineResult.FilePath | String | The file path on the endpoint. |
| Traps.QuarantineResult.OperationID | String | The ID of the operation. |
| Traps.QuarantineResult.Status | String | The status of the quarantine operation. |
Command Example
!traps-event-quarantine-result operation_id="e092afa2e08511e9acbf0245d8e950da"
Context Example
{
"Traps.QuarantineResult": {
"FilePath": "C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cache\\f_000013",
"OperationID": "e092afa2e08511e9acbf0245d8e950da",
"SHA256": "2f937ee2fd10a6ea58faca31ab455d18e29ded5d88b4a6f8cc29127a23232e45",
"Status": "finished"
}
}
Human Readable Output
Status of quarantine operation: e092afa2e08511e9acbf0245d8e950da
| File Path | Operation ID | SHA256 | Status |
|---|---|---|---|
| C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Cache\f_000013 | e092afa2e08511e9acbf0245d8e950da | 2f937ee2fd10a6ea58faca31ab455d18e29ded5d88b4a6f8cc29127a23232e45 | finished |
12. Get the result of an isolate operation
Returns the status of the specified endpoint isolate operation.
Base Command
traps-endpoint-isolate-status
Input
| Argument Name | Description | Required |
|---|---|---|
| operation_id | The ID of the operation. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.IsolateResult.OperationID | String | Operation ID. Use this to retrieve status / results. |
| Traps.IsolateResult.Status | String | The status of the isolation operation. |
Command Example
!traps-endpoint-isolate-status operation_id=d4abbbc4e5ba11e9acbf0245d8e950da
Context Example
{
"Traps.IsolateResult": {
"OperationID": "d4abbbc4e5ba11e9acbf0245d8e950da",
"Status": "finished"
}
}
Human Readable Output
Isolate status is: finished
13. Get the results of an endpoint file retrieve operation
Returns the result of the endpoint file retrieve operation.
Base Command
traps-endpoint-files-retrieve-result
Input
| Argument Name | Description | Required |
|---|---|---|
| operation_id | The ID of the operation. | Required |
Context Output
There are no context output for this command.
Command Example
!traps-endpoint-files-retrieve-result operation_id="d129d313e5ba11e9acbf0245d8e950da"
Context Example
{
"Traps.FileRetrieveResult": {
"OperationID": "d129d313e5ba11e9acbf0245d8e950da",
"Status": "finished"
}
}
Human Readable Output
File retrieval status is: finished
14. Get the results of an endpoint scan operation
Returns the results of an endpoint scan operation.
Base Command
traps-endpoint-scan-result
Input
| Argument Name | Description | Required |
|---|---|---|
| operation_id | The ID of the operation. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Traps.ScanResult.FileScanned | Number | The number of scanned files. |
| Traps.ScanResult.FilesFailed | Number | The number of files that were not scanned. |
| Traps.ScanResult.MalwareFound | Number | The number of detected malware. |
| Traps.ScanResult.OperationID | String | The ID of the operation. |
| Traps.ScanResult.Status | String | The status of the scan. |
Command Example
!traps-endpoint-scan-result operation_id="d270d8bce5ba11e9acbf0245d8e950da"
Context Example
{
"Traps.ScanResult": {
"FileScanned": 57295,
"FilesFailed": 0,
"MalwareFound": 1,
"OperationID": "d270d8bce5ba11e9acbf0245d8e950da",
"Status": "error"
}
}
Human Readable Output
Status of scan operation: d270d8bce5ba11e9acbf0245d8e950da
| File Scanned | Files Failed | Malware Found | Operation ID | Status |
|---|---|---|---|---|
| 57295 | 0 | 1 | d270d8bce5ba11e9acbf0245d8e950da | error |
Configuration parameters
url— Server URL (required)application_id— Application ID (required)private_key— Private Key (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (14)
-
traps-endpoint-files-retrieveDeprecatedExecutes a file retrieve operation / SAM on the specified agent.
-
traps-endpoint-files-retrieve-resultDeprecatedReturns the result of the endpoint file retrieve operation.
-
traps-endpoint-isolateDeprecatedIsolates the specified endpoint.
-
traps-endpoint-isolate-statusDeprecatedReturns the status of the specified endpoint isolate operation.
-
traps-endpoint-scanDeprecatedPerforms a scan operation on the specified endpoint.
-
traps-endpoint-scan-resultDeprecatedReturns the results of an endpoint scan operation.
-
traps-event-bulk-update-statusDeprecatedModifies the status of multiple events.
-
traps-event-quarantineDeprecatedCreates a quarantine entry for the specified event.
-
traps-event-quarantine-resultDeprecatedReturns the result of the specified quarantine operation.
-
traps-event-updateDeprecatedModifies the status and adds a comment to an existing event.
-
traps-get-endpoint-by-idDeprecatedReturns details for the specified endpoint.
-
traps-hash-blacklistDeprecatedAdds the specified file hash to the block list.
-
traps-hash-blacklist-removeDeprecatedRemoves the specified file hash from the block list.
-
traps-hashes-blacklist-statusDeprecatedReturns the block list status of the specified file hashes.
import copy import urllib3 import jwt from CommonServerPython import * # Disable insecure warnings urllib3.disable_warnings() PARAMS = demisto.params() # Remove trailing slash to prevent wrong URL path to service SERVER = PARAMS['url'][:-1] \ if (PARAMS['url'] and PARAMS['url'].endswith('/')) else PARAMS['url'] # Should we use SSL USE_SSL = not PARAMS.get('insecure', False) # Service base URL BASE_URL = SERVER + '/xapi/v1/' APPLICATION_ID = PARAMS.get('application_id') PRIVATE_KEY = PARAMS.get('private_key') # Headers to be sent in requests REQUEST_HEADERS = { 'Content-Type': 'application/json' } OUTPUTS = { 'get_endpoint_by_id': { 'ID': 'guid', 'Name': 'name', 'Domain': 'domain', 'Platform': 'platform', 'ScanStatus': 'scanStatus', 'Status': 'status', 'IP': 'ip', 'ComputerSid': 'computerSid', 'IsCompromised': 'compromised', 'OsVersion': 'osVersion', 'OsProductType': 'osProductType', 'OsProductName': 'osProductName', 'Is64': 'is64', 'LastSeen': 'lastSeen', 'LastUser': 'lastUser' }, 'endpoint_files_retrieve': { 'OperationID': 'operationId' }, 'endpoint_isolate': { 'OperationID': 'operationId' }, 'endpoint_scan': { 'OperationID': 'operationId' }, 'event_bulk_update_status': { 'EventID': 'eventGuid' }, 'hashes_blacklist_status': { 'SHA256': 'hash', 'BlacklistStatus': 'status' }, 'event_quarantine_result': { 'SHA256': 'fileHash', 'FilePath': 'filePath' }, 'endpoint_scan_result': { 'FileScanned': 'filesScanned', 'FilesFailed': 'filesFailed', 'MalwareFound': 'malwareFound' } } def create_headers(with_auth): """Create headers for the http_request Args: with_auth: True Returns: Headers. """ headers = copy.deepcopy(REQUEST_HEADERS) if with_auth: token = generate_auth_token().decode('utf-8') headers['Authorization'] = f'Bearer {token}' return headers def extract_and_validate_http_response(response, operation_err_message, test=False): """ Args: response: raw response operation_err_message: error message to present in case of error test: boolean value, true if test Returns: Error if response is faulty. """ try: response.raise_for_status() return response.json() if not test else response.content except requests.exceptions.HTTPError: try: err_message = response.json().get('message') except Exception: try: err_obj = json.loads(xml2json(response.text)) err_message = demisto.get(err_obj, 'Error.Message') except Exception: err_message = 'Could not parse error' return_error(f'{operation_err_message}: \n{err_message}') def http_request(method, url_suffix, plain_url=False, params=None, data=None, operation_err=None, parse_response=True, with_auth=True): """Generic http call to Traps Args: method: request method. url_suffix: URL suffix. plain_url: full URL. params: request params. data: request data. operation_err: operation error to log the user. parse_response: boolean value, if parsing the response is needed. with_auth: boolean value, do we need to authenticate the request. Returns: Result from the API. """ try: result = requests.request( method, BASE_URL + url_suffix if not plain_url else url_suffix, verify=USE_SSL, params=params, data=json.dumps(data) if data else data, headers=create_headers(with_auth), ) except requests.exceptions.ConnectionError: return_error('Error connecting to Traps server. Please check your connection and you server address') if parse_response: result = extract_and_validate_http_response(result, operation_err, plain_url) return result def health_check(): """Performs basic health check on the server. Returns: Error if not ok. """ path = f'{SERVER}/xapi/health-check' server_status = http_request('GET', path, plain_url=True).decode('utf-8') if server_status == '"Ok"': return raise Exception(f'Server health-check failed. Status returned was: {server_status}') def generate_auth_token(): """Generate a token using jwt. Returns: token. """ key = PRIVATE_KEY data = {'appId': APPLICATION_ID} token = jwt.encode(data, key, algorithm='RS256') return token def parse_data_from_response(resp_obj, operation_name=None): """Response raw data. Args: resp_obj: raw_data. operation_name: operation name. Returns: parsed data. """ new_data_obj = {} # type: dict outputs_obj = OUTPUTS[operation_name] for key, val in outputs_obj.items(): if val in resp_obj: new_data_obj[key] = resp_obj.get(val) return new_data_obj def get_endpoint_by_id(endpoint_id): """Get endpoint data by sending a GET request. Args: endpoint_id: endpoint ID. Returns: endpoint data. """ path = f'agents/{endpoint_id}' endpoint_data = http_request('GET', path, operation_err=f'Get endpoint {endpoint_id} failed') return parse_data_from_response(endpoint_data, 'get_endpoint_by_id'), endpoint_data def endpoint_files_retrieve(endpoint_id, file_name, event_id): """Retrieve a file from the endpoint by sending a POST request. Args: endpoint_id: endpoint ID. file_name: File name. event_id: Event ID. Returns: Operation data. """ path = f'agents/{endpoint_id}/files-retrieve' data = { 'incidentId': event_id, 'files': [ { "path": file_name } ] } resp = http_request('POST', path, data=data, operation_err=f'Files retrieve command on endpoint {endpoint_id} failed') operation_obj = parse_data_from_response(resp, 'endpoint_files_retrieve') operation_obj.update({ 'EndpointID': endpoint_id, 'Type': 'files-retrieve' }) return operation_obj def endpoint_scan(endpoint_id): """Initiate a scan on an endpoint by sending a POST request. Args: endpoint_id: endpoint ID. Returns: Operation data. """ path = f'agents/{endpoint_id}/scan' response = http_request('POST', path, operation_err=f'Scanning endpoint: {endpoint_id} failed') operation_obj = parse_data_from_response(response, 'endpoint_scan') operation_obj.update({ 'EndpointID': endpoint_id, 'Type': 'endpoint-scan' }) return operation_obj, response def endpoint_scan_result(operation_id): """Initiate the SAM operation for retrieving the scan result. Args: operation_id: operation ID. Returns: scan data. """ status, additional_data = sam_operation(operation_id, 'Could not get scan results') scan_data = parse_data_from_response(additional_data.get('scanData'), 'endpoint_scan_result') if additional_data else {} scan_data['Status'] = status scan_data['OperationID'] = operation_id return scan_data def update_event_status(event_ids, status): """Update event or events status by sending a POST request. Args: event_ids: event IDs. status: status. Returns: API response. """ path = 'events/status' data = { "guids": event_ids, "status": status } response = http_request('PATCH', path, data=data, operation_err=f'Update events {event_ids} status failed') return response def update_event_comment(event_id, comment): """Update event comment by sending a POST request. Args: event_id: event ID. comment: comment. """ path = f'events/{event_id}/comment' data = { "comment": comment } http_request('POST', path, data=data, operation_err=f'Update event: {event_id} comment failed') def event_update(event_id, status, comment): """Initiate update of an event. Args: event_id: event ID. status: status. comment: comment. Returns: Error if not successful. """ if not status and not comment: raise Exception('Please add a status or a comment. Neither was given.') if status: response = update_event_status([event_id], status) if response.get('failed'): raise Exception(f'Update status for event: {event_id} has failed.') if comment: update_event_comment(event_id, comment) def event_bulk_update_status(event_ids, status): """Initiate update of events statuses. Args: event_ids: event IDs. status: status. Returns: Update statuses. """ ids_obj = update_event_status(event_ids, status) results = { 'UpdateSuccess': list( map(lambda id_obj: parse_data_from_response(id_obj, 'event_bulk_update_status'), ids_obj.get('succeeded'))), 'UpdateFail': list( map(lambda id_obj: parse_data_from_response(id_obj, 'event_bulk_update_status'), ids_obj.get('failed'))), 'UpdateIgnored': list( map(lambda id_obj: parse_data_from_response(id_obj, 'event_bulk_update_status'), ids_obj.get('ignored'))) } return results def hash_blacklist(hash_id): """Add hash to a blacklist by sending a POST request. Args: hash_id: Hash. Returns: status. """ path = f'hashes/{hash_id}/blacklist' result = http_request('POST', path, operation_err=f'Failed to blacklist {hash_id}') return result.get('status') def remove_hash_from_blacklist(hash_id): """Remove hash to a blacklist by sending a POST request. Args: hash_id: Hash. Returns: status. """ path = f'hashes/{hash_id}/blacklist-remove' result = http_request('POST', path, operation_err=f'Failed to remove {hash_id} from blacklist') return result.get('status') def hashes_blacklist_status(hash_ids): """Get hashes blacklisting status by sending a POST request. Args: hash_ids: Hashes. Returns: Hashes and blacklisting data. """ path = 'hashes/blacklist-status' data = { 'hashes': hash_ids } ids_obj = http_request('POST', path, data=data, operation_err='Failed to get hashes status') result = list(map(lambda id_obj: parse_data_from_response(id_obj, 'hashes_blacklist_status'), ids_obj)) return result def event_quarantine(event_id): """Quarantine an event by sending a POST request. Args: event_id: event ID. Returns: Data regarding the event and the quarantine operation. """ path = f'events/{event_id}/quarantine' resp = http_request('POST', path, operation_err=f'Quarantine event {event_id} failed') message_ids = resp.get('operationId').get('samMessageIds') operations = [] for op_id in message_ids: operations.append({ 'EventID': event_id, 'Type': 'event-quarantine', 'OperationID': op_id }) return operations def endpoint_isolate(endpoint_id): """Isolate an endpoint by sending a POST request. Args: endpoint_id: endpoint ID. Returns: Data regarding the endpoint and the isolation operation. """ path = f'agents/{endpoint_id}/isolate' resp = http_request('POST', path, operation_err=f'Isolation of endpoint: {endpoint_id} failed') operation_obj = parse_data_from_response(resp, 'endpoint_isolate') operation_obj.update({ 'EndpointID': endpoint_id, 'Type': 'endpoint-isolate' }) return operation_obj def sam_operation(operation_id, operation_err): """ This functions invokes an API call to the sam operation endpoint on Traps server to get the operation status and/or results. :param operation_id: the operation on which to get the status/results :param operation_err: The error to return in case of a failure (changes according to the command fired.) :return: status: the status of the operation. additional_data: additional data regarding the operation (like scan results) """ path = f'sam/operations/{operation_id}' result = http_request('GET', path, operation_err=operation_err) summary_data = result.get('summaryData') if summary_data and (summary_data.get('incompatible') or summary_data.get('samExists')): if operation_err == 'Could not get scan results': # Get scan result requested_scans = int(summary_data.get('requested', 0)) incompatible_scans = int(summary_data.get('incompatible', 0)) sam_exists_scans = int(summary_data.get('samExists', 0)) if requested_scans <= incompatible_scans + sam_exists_scans: raise Exception(f'{operation_err}.\nRequested scans number: {requested_scans}.\n' f'Incompatible scans number: {requested_scans}.\n' f'Sam exists scans number: {sam_exists_scans}.') raise Exception(f'{operation_err}') if result.get('summaryData').get('samExists'): return 'ignored', None for status_obj in result.get('statuses'): if status_obj.get('count') > 0: return status_obj.get('status'), result.get('additionalData') raise Exception(f'{operation_err}: Could not retrieve status') def endpoint_isolate_status(operation_id): """Initiate the SAM operation for endpoint isolation status. Args: operation_id: operation ID. Returns: endpoint status, operation ID """ status, _ = sam_operation(operation_id, 'Could not get endpoint isolate status') return {'Status': status, 'OperationID': operation_id} def event_quarantine_result(operation_id): """Initiate the SAM operation for quarantine result. Args: operation_id: operation ID. Returns: quarantine data. """ status, additional_data = sam_operation(operation_id, 'Could not get event quarantine status') quarantine_data = parse_data_from_response(additional_data.get('quarantineData'), 'event_quarantine_result') if additional_data else {} quarantine_data['Status'] = status quarantine_data['OperationID'] = operation_id return quarantine_data def endpoint_files_retrieve_result(operation_id): """Initiate the SAM operation for file retrieving. Args: operation_id: operation ID. Returns: file as an entry, status, operation_id. """ status, additional_data = sam_operation(operation_id, 'Failed to get file retrieve results') if status == 'finished': file_info = additional_data.get('uploadData') file_name = file_info.get('fileName') url = file_info.get('downloadUrl') data = http_request('GET', url, plain_url=True, operation_err='Unable to download file.', with_auth=False) demisto.results(fileResult(filename=file_name, data=data)) return {'Status': status, 'OperationID': operation_id} def test_module_command(): """Performs basic GET request to check if the API is reachable and authentication is successful. Returns: ok if successful. """ health_check() result = http_request('GET', 'agents/1', parse_response=False) if result.status_code == 403: raise Exception('Error connecting to server. Check your Application ID and Private key') demisto.results('ok') def get_endpoint_by_id_command(): """Get endpoint data. Returns: Demisto Outputs. """ args = demisto.args() endpoint_id = args.get('endpoint_id') endpoint_data, raw_data = get_endpoint_by_id(endpoint_id) human_readable = tableToMarkdown(f'Endpoint {endpoint_id} data:', endpoint_data, headerTransform=pascalToSpace) context = {'Traps.Endpoint(val.ID == obj.ID)': createContext(endpoint_data)} return_outputs(human_readable, context, raw_response=raw_data) def endpoint_files_retrieve_command(): """Initiate retrieving of files from an endpoint. Returns: Demisto Outputs. """ args = demisto.args() endpoint_id = args.get('endpoint_id') file_name = args.get('file_name') event_id = args.get('event_id') operation_obj = endpoint_files_retrieve(endpoint_id, file_name, event_id) human_readable = tableToMarkdown(f'Files retrieve command on endpoint: {endpoint_id} received', operation_obj, headerTransform=pascalToSpace) context = {'Traps.FileRetrieve(val.OperationID == obj.OperationID)': operation_obj} return_outputs(human_readable, context, operation_obj) def endpoint_files_retrieve_result_command(): """Retrieve files from an endpoint result. Returns: Demisto Outputs. """ args = demisto.args() operation_id = args.get('operation_id') status_obj = endpoint_files_retrieve_result(operation_id) human_readable = f'### File retrieval status is: {status_obj.get("Status")}' context = {'Traps.FileRetrieveResult(val.OperationID == obj.OperationID)': status_obj} return_outputs(human_readable, context) def endpoint_scan_command(): """Initiate scan on an endpoint. Returns: Demisto Outputs. """ args = demisto.args() endpoint_id = args.get('endpoint_id') # check that running a scan is possible _, raw_data = get_endpoint_by_id(endpoint_id) scan_status = raw_data.get('scanStatus') if scan_status and scan_status in ['pending', 'in_progress']: raise Exception(f'Could not initiate a scan on the endpoint {endpoint_id}' f' because endpoint scan status is {scan_status}.') operation_obj, raw_data = endpoint_scan(endpoint_id) human_readable = tableToMarkdown(f'Scan command on endpoint: {endpoint_id} received', operation_obj, headerTransform=pascalToSpace) context = {'Traps.Scan(val.OperationID == obj.OperationID)': operation_obj} return_outputs(human_readable, context, raw_data) def endpoint_scan_result_command(): """Retrieve endpoint scan results. Returns: Demisto Outputs. """ args = demisto.args() operation_id = args.get('operation_id') status_obj = endpoint_scan_result(operation_id) context = {'Traps.ScanResult(val.OperationID == obj.OperationID)': status_obj} human_readable = tableToMarkdown(f'Status of scan operation: {operation_id}', status_obj, headerTransform=pascalToSpace) return_outputs(human_readable, context, status_obj) def event_update_command(): """Update an event. Returns: Demisto Outputs. """ args = demisto.args() event_id = args.get('event_id') status = args.get('status') comment = args.get('comment') event_update(event_id, status, comment) human_readable = f'### Event: {event_id} was updated' human_readable += f'\n##### New status: {status}' if status else '' human_readable += f'\n##### New comment: {comment}' if comment else '' return_outputs(human_readable, None, {}) def event_bulk_update_status_command(): """Update events. Returns: Demisto Outputs. """ args = demisto.args() event_ids = argToList(args.get('event_ids')) status = args.get('status') results = event_bulk_update_status(event_ids, status) human_readable = tableToMarkdown('Successfully updated', results.get('UpdateSuccess'), headerTransform=pascalToSpace) human_readable += tableToMarkdown('Failed to update', results.get('UpdateFail'), headerTransform=pascalToSpace) human_readable += tableToMarkdown('Ignored', results.get('UpdateIgnored'), headerTransform=pascalToSpace) return_outputs(human_readable, {}, {}) def event_quarantine_command(): """Quarantine an event. Returns: Demisto Outputs. """ args = demisto.args() event_id = args.get('event_id') operations = event_quarantine(event_id) human_readable = tableToMarkdown(f'Quarantine command on event: {event_id} received', operations, headerTransform=pascalToSpace) context = {'Traps.Quarantine(val.OperationID == obj.OperationID)': operations} return_outputs(human_readable, context, operations) def event_quarantine_result_command(): """Check quarantine event status. Returns: Demisto Outputs. """ args = demisto.args() operation_id = args.get('operation_id') status_obj = event_quarantine_result(operation_id) context = {'Traps.QuarantineResult(val.OperationID == obj.OperationID)': status_obj} human_readable = tableToMarkdown(f'Status of quarantine operation: {operation_id}', status_obj, headerTransform=pascalToSpace) return_outputs(human_readable, context, status_obj) def hash_blacklist_command(): """Add a hash to a blacklist. Returns: Demisto Outputs. """ args = demisto.args() hash_id = args.get('hash_id') status = hash_blacklist(hash_id) context = {} # type: dict if status == 'success': human_readable = f'#### Successfully blacklisted: {hash_id}' status_obj = { 'SHA256': hash_id, 'BlacklistStatus': 'blacklisted' } context = {'Traps.File(val.SHA256 == obj.SHA256)': status_obj} elif status == 'ignore': human_readable = f'#### Hash: {hash_id} already appears in blacklist' else: human_readable = f'#### Failed to blacklist: {hash_id}' return_outputs(human_readable, context, status) def hash_blacklist_remove_command(): """Remove a hash from blacklist. Returns: Demisto Outputs. """ args = demisto.args() hash_id = args.get('hash_id') status = remove_hash_from_blacklist(hash_id) context = {} # type: dict if status == 'success': human_readable = f'#### Successfully removed {hash_id} from blacklist' status_obj = { 'SHA256': hash_id, 'BlacklistStatus': 'none' } context = {'Traps.File(val.SHA256 == obj.SHA256)': status_obj} else: human_readable = f'#### Failed to remove {hash_id} from blacklist:' return_outputs(human_readable, context, status) def hashes_blacklist_status_command(): """Check hash blacklist status. Returns: Demisto Outputs. """ args = demisto.args() hash_ids = args.get('hash_ids').split(',') ids_obj = hashes_blacklist_status(hash_ids) human_readable = tableToMarkdown('Hashes status:', ids_obj, headerTransform=pascalToSpace) context = {'Traps.File(val.SHA256 == obj.SHA256)': ids_obj} return_outputs(human_readable, context, ids_obj) def endpoint_isolate_command(): """Isolate an endpoint. Returns: Demisto Outputs. """ args = demisto.args() endpoint_id = args.get('endpoint_id') operation_obj = endpoint_isolate(endpoint_id) human_readable = tableToMarkdown(f'Isolate command on endpoint {endpoint_id} received', operation_obj, headerTransform=pascalToSpace) context = {'Traps.Isolate(val.OperationID == obj.OperationID)': operation_obj} return_outputs(human_readable, context, operation_obj) def endpoint_isolate_status_command(): """Check endpoint isolation status. Returns: Demisto Outputs. """ args = demisto.args() operation_id = args.get('operation_id') isolate_status = endpoint_isolate_status(operation_id) human_readable = f'### Isolate status is: {isolate_status.get("Status")}' context = {'Traps.IsolateResult(val.OperationID == obj.OperationID)': isolate_status} return_outputs(human_readable, context, isolate_status) def main(): """ Initiate integration command """ # Remove proxy if not set to true in params handle_proxy() command = demisto.command() LOG(f'Command being called is {command}.') try: if command == 'test-module': test_module_command() elif command == 'traps-get-endpoint-by-id': get_endpoint_by_id_command() elif command == 'traps-endpoint-files-retrieve': endpoint_files_retrieve_command() elif command == 'traps-endpoint-files-retrieve-result': endpoint_files_retrieve_result_command() elif command == 'traps-endpoint-scan': endpoint_scan_command() elif command == 'traps-endpoint-scan-result': endpoint_scan_result_command() elif command == 'traps-event-update': event_update_command() elif command == 'traps-event-bulk-update-status': event_bulk_update_status_command() elif command == 'traps-hash-blacklist': hash_blacklist_command() elif command == 'traps-hash-blacklist-remove': hash_blacklist_remove_command() elif command == 'traps-hashes-blacklist-status': hashes_blacklist_status_command() elif command == 'traps-event-quarantine': event_quarantine_command() elif command == 'traps-event-quarantine-result': event_quarantine_result_command() elif command == 'traps-endpoint-isolate': endpoint_isolate_command() elif command == 'traps-endpoint-isolate-status': endpoint_isolate_status_command() else: raise NotImplementedError(f'Command {command} was not implemented.') except Exception as err: return_error(err) if __name__ in ["__builtin__", "builtins", "__main__"]: main()