TrustwaveFusion
The Trustwave Fusion platform connects your organization’s digital footprint to a robust security cloud comprised of the Trustwave data lake, advanced analytics, actionable threat intelligence and a wide range of Trustwave services including Trustwave SpiderLabs , elite team of security specialists. Your team will benefit from deep visibility and the advanced security expertise necessary for protecting assets and eradicating threats as they arise.
Data Enrichment & Threat Intelligence · Trustwave Fusion
Details
| ID | TrustwaveFusion |
|---|---|
| Provider | LevelBlue |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
The Trustwave Fusion platform connects your organization’s digital footprint
to a robust security cloud comprised of the Trustwave data lake, advanced
analytics, actionable threat intelligence and a wide range of Trustwave
services including Trustwave SpiderLabs , elite team of security
specialists. Your team will benefit from deep visibility and the advanced
security expertise necessary for protecting assets and eradicating threats as
they arise.
This integration was integrated and tested with version 1.0.68 of TrustwaveFusion
Configure TrustwaveFusion in Cortex
| Parameter | Description | Required |
|---|---|---|
| Fusion API URL | True | |
| API Key | The API Key to use for connection | True |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False | |
| Fetch incidents | False | |
| Incident type | False | |
| Maximum number of incidents per fetch | False | |
| First fetch time | Format: [number] [time unit]. e.g., 12 hours, 7 days, 2 seconds etc. | False |
| Ticket Types | Types of tickets to fetch | 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.
trustwave-get-ticket
Get a single ticket
Base Command
trustwave-get-ticket
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Ticket ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Trustwave.Ticket.number | String | The Ticket ID |
| Trustwave.Ticket.subject | String | The ticket title. |
| Trustwave.Ticket.status | String | The status of the ticket |
| Trustwave.Ticket.description | String | The detailed ticket description. |
| Trustwave.Ticket.category | String | Ticket category |
| Trustwave.Ticket.createdBy | String | User that created the ticket. |
| Trustwave.Ticket.createdOn | Date | The ticket creation time. |
| Trustwave.Ticket.customerName | String | The name of the customer. |
| Trustwave.Ticket.findings.classification | String | Category for finding related to the ticket. |
| Trustwave.Ticket.findings.classificationCode | String | Category code for finding related to the ticket. |
| Trustwave.Ticket.findings.findingId | String | Id finding related to the ticket. |
| Trustwave.Ticket.formatted_notes | String | Human readable Notes for the ticket. |
| Trustwave.Ticket.impact | String | Ticket impact (HIGH, MEDIUM, LOW) |
| Trustwave.Ticket.notes.actor | String | User that added the note (comment) |
| Trustwave.Ticket.notes.text | String | The note (comment) text. |
| Trustwave.Ticket.notes.timestamp | Date | Time when the note (comment) was created. |
| Trustwave.Ticket.priority | String | Ticket priority (CRITICAL, HIGH, MEDIUM, LOW) |
| Trustwave.Ticket.subCategory | String | Ticket sub-category. |
| Trustwave.Ticket.type | String | The ticket type (CASE, INCIDENT, CHANGE) |
| Trustwave.Ticket.updatedOn | Date | When the ticket was last updated. |
| Trustwave.Ticket.urgency | String | The ticket urgency (HIGH, MEDIUM, LOW) |
Command example
!trustwave-get-ticket id="INA1976568"
Context Example
{
"Trustwave": {
"Ticket": {
"assetIds": [],
"category": "Threat Detection & Response",
"createdBy": "dummyuser",
"createdOn": "2021-12-08T17:16:27.000+00:00",
"customerName": "Sample Customer",
"description": "Ticket description.",
"findings": [
{
"classification": null,
"classificationCode": "UnauthorizedAccessOrIntrusionAttempt.",
"findingId": "765432:THREAT:@AXv0k6GhG2zTcaogE1vG"
}
],
"formatted_notes": "2021-12-08T17:16:27.000+00:00 Created by: dummyuser\nNOTE:\nNote A\n----------------\n2021-12-08T17:17:57.000+00:00 Created by: dummyuser\nNOTE:\nNote B\n----------------\n2021-12-09T16:43:31.000+00:00 Created by: dummy_user\nNOTE:\nNote C",
"impact": "HIGH",
"notes": [
{
"actor": "dummyuser",
"text": "Note A",
"timestamp": "2021-12-08T17:16:27.000+00:00"
},
{
"actor": "dummyuser",
"text": "Note B",
"timestamp": "2021-12-08T17:17:57.000+00:00"
},
{
"actor": "dummy_user",
"text": "Note C",
"timestamp": "2021-12-09T16:43:31.000+00:00"
}
],
"number": "INA1976568",
"priority": "HIGH",
"status": "ON_HOLD",
"subCategory": "Threat Operations",
"subject": "Test incident #354",
"type": "INCIDENT",
"updatedOn": "2021-12-09T16:43:48.000+00:00",
"urgency": "MEDIUM"
}
}
}
Human Readable Output
field value assetIds category Threat Detection & Response createdBy dummyuser createdOn 2021-12-08T17:16:27.000+00:00 customerName Sample Customer description Ticket description. findings {‘classification’: None, ‘classificationCode’: ‘UnauthorizedAccessOrIntrusionAttempt.’, ‘findingId’: ‘765432:THREAT:@AXv0k6GhG2zTcaogE1vG’} impact HIGH notes {‘actor’: ‘dummyuser’, ‘text’: ‘Note A’, ‘timestamp’: ‘2021-12-08T17:16:27.000+00:00’},
{‘actor’: ‘dummyuser’, ‘text’: ‘Note B’, ‘timestamp’: ‘2021-12-08T17:17:57.000+00:00’},
{‘actor’: ‘dummy_u….[Truncated]number INA1976568 priority HIGH status ON_HOLD subCategory Threat Operations subject Test incident #354 type INCIDENT updatedOn 2021-12-09T16:43:48.000+00:00 urgency MEDIUM formatted_notes 2021-12-08T17:16:27.000+00:00 Created by: dummyuser
NOTE:
Note A
—————-
2021-12-08T17:17:57.000+00:00 Created by: dummyuser
NOTE:
Note B
—————-
2021-12-09T1….[Truncated]
trustwave-search-tickets
Search tickets
Base Command
trustwave-search-tickets
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Ticket ID. | Optional |
| subject | Ticket Subject. | Optional |
| type | Ticket type to query. Possible values are: INCIDENT, CASE, CHANGE. | Optional |
| status | Ticket status. Possible values are: NEW, OPEN, IN_PROGRESS, AWAITING_INFO, ON_HOLD, RESOLVED, CLOSED, CANCELED, SCHEDULED. | Optional |
| priority | Ticket priority. Possible values are: CRITICAL, HIGH, MEDIUM, LOW. | Optional |
| impact | Ticket impact. Possible values are: HIGH, MEDIUM, LOW. | Optional |
| urgency | Ticket urgency. Possible values are: HIGH, MEDIUM, LOW. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Trustwave.Ticket.number | String | The Ticket ID |
| Trustwave.Ticket.subject | String | The ticket title. |
| Trustwave.Ticket.status | String | The status of the ticket |
| Trustwave.Ticket.description | String | The detailed ticket description. |
| Trustwave.Ticket.category | String | Ticket category. |
| Trustwave.Ticket.createdBy | String | User that created the ticket. |
| Trustwave.Ticket.createdOn | Date | The time when the ticket was created. |
| Trustwave.Ticket.customerName | String | The name of the customer. |
| Trustwave.Ticket.formatted_notes | String | Human readable notes. |
| Trustwave.Ticket.impact | String | Ticket impact (HIGH, MEDIUM, LOW) |
| Trustwave.Ticket.notes.actor | String | User that added the note (comment) |
| Trustwave.Ticket.notes.text | String | The note (comment) text. |
| Trustwave.Ticket.notes.timestamp | Date | Time when the note (comment) was created. |
| Trustwave.Ticket.priority | String | Ticket priority (CRITICAL, HIGH, MEDIUM, LOW) |
| Trustwave.Ticket.subCategory | String | Ticket sub-category. |
| Trustwave.Ticket.type | String | The ticket type (CASE, INCIDENT, CHANGE) |
| Trustwave.Ticket.updatedOn | Date | When the ticket was last updated. |
| Trustwave.Ticket.urgency | String | The ticket urgency (HIGH, MEDIUM, LOW) |
Command example
!trustwave-search-tickets limit=2 type=INCIDENT
Context Example
{
"Trustwave": {
"Ticket": [
{
"assetIds": [
"765432:managed-device#DEVICE:AW8Qp1Bextjwd2cF57Mk"
],
"category": "Technology Management",
"createdBy": "cpe_outage_service",
"createdOn": "2021-11-29T10:56:45.000+00:00",
"customerName": "Sample Customer",
"description": "",
"findings": [],
"formatted_notes": "2021-11-29T10:56:44.000+00:00 Created by: cpe_outage_service\nNOTE:\nNOTE A",
"impact": "HIGH",
"notes": [
{
"actor": "cpe_outage_service",
"text": "NOTE A",
"timestamp": "2021-11-29T10:56:44.000+00:00"
}
],
"number": "INA1077007",
"priority": "HIGH",
"status": "CLOSED",
"subCategory": "Cellular Backup",
"subject": "Alert: device is using cellular",
"type": "INCIDENT",
"updatedOn": "2021-12-29T00:00:08.000+00:00",
"urgency": "MEDIUM"
},
{
"assetIds": [],
"category": "Threat Detection & Response",
"createdBy": "dummyuser",
"createdOn": "2021-12-08T17:16:27.000+00:00",
"customerName": "Sample Customer",
"description": "Ticket description",
"findings": [
{
"classification": null,
"classificationCode": "UnauthorizedAccessOrIntrusionAttempt.",
"findingId": "765432:THREAT:@AXv0k6GhG2zTcaogE1vG"
}
],
"formatted_notes": "2021-12-08T17:16:27.000+00:00 Created by: dummyuser\nNOTE:\nSample Note.\n----------------\n2021-12-08T17:17:57.000+00:00 Created by: dummyuser\nNOTE:\nSample note #2.\n----------------\n2021-12-09T16:43:31.000+00:00 Created by: dummy_user\nNOTE:\nSample note #3",
"impact": "HIGH",
"notes": [
{
"actor": "dummyuser",
"text": "Sample Note.",
"timestamp": "2021-12-08T17:16:27.000+00:00"
},
{
"actor": "dummyuser",
"text": "Sample note #2.",
"timestamp": "2021-12-08T17:17:57.000+00:00"
},
{
"actor": "dummy_user",
"text": "Sample note #3",
"timestamp": "2021-12-09T16:43:31.000+00:00"
}
],
"number": "INA1077535",
"priority": "HIGH",
"status": "ON_HOLD",
"subCategory": "Threat Operations",
"subject": "MCAS - Impossible travel activity",
"type": "INCIDENT",
"updatedOn": "2021-12-09T16:43:48.000+00:00",
"urgency": "MEDIUM"
}
]
}
}
Human Readable Output
Results
assetIds category createdBy createdOn customerName description findings formatted_notes impact notes number priority status subCategory subject type updatedOn urgency 765432:managed-device#DEVICE:AW8Qp1Bextjwd2cF57Mk Technology Management cpe_outage_service 2021-11-29T10:56:45.000+00:00 Sample Customer 2021-11-29T10:56:44.000+00:00 Created by: cpe_outage_service
NOTE:
NOTE AHIGH {‘actor’: ‘cpe_outage_service’, ‘text’: ‘NOTE A’, ‘timestamp’: ‘2021-11-29T10:56:44.000+00:00’} INA1077007 HIGH CLOSED Cellular Backup Alert: device is using cellular INCIDENT 2021-12-29T00:00:08.000+00:00 MEDIUM Threat Detection & Response dummyuser 2021-12-08T17:16:27.000+00:00 Sample Customer Ticket description {‘classification’: None, ‘classificationCode’: ‘UnauthorizedAccessOrIntrusionAttempt.’, ‘findingId’: ‘765432:THREAT:@AXv0k6GhG2zTcaogE1vG’} 2021-12-08T17:16:27.000+00:00 Created by: dummyuser
NOTE:
Sample Note.
—————-
2021-12-08T17:17:57.000+00:00 Created by: dummyuser
NOTE:
Sample note #2.
—————-
2021-12-09T16:43:31.000+00:00 Created by: dummy_user
NOTE:
Sample note #3HIGH {‘actor’: ‘dummyuser’, ‘text’: ‘Sample Note.’, ‘timestamp’: ‘2021-12-08T17:16:27.000+00:00’},
{‘actor’: ‘dummyuser’, ‘text’: ‘Sample note #2.’, ‘timestamp’: ‘2021-12-08T17:17:57.000+00:00’},
{‘actor’: ‘dummy_user’, ‘text’: ‘Sample note #3’, ‘timestamp’: ‘2021-12-09T16:43:31.000+00:00’}INA1077535 HIGH ON_HOLD Threat Operations MCAS - Impossible travel activity INCIDENT 2021-12-09T16:43:48.000+00:00 MEDIUM
trustwave-add-ticket-comment
Add a comment to a ticket
Base Command
trustwave-add-ticket-comment
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Incident ID. | Required |
| comment | Comment text. | Required |
Context Output
There is no context output for this command.
Command example
!trustwave-add-ticket-comment id=INA1051028 comment="test from xsoar"
Human Readable Output
Success
trustwave-close-ticket
Close a ticket
Base Command
trustwave-close-ticket
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Incident ID. | Required |
| comment | Comment text. | Required |
Context Output
There is no context output for this command.
Command example
!trustwave-close-ticket id="INA1051028" comment="Comment"
Human Readable Output
Success
trustwave-get-updated-tickets
Get updated tickets.
Base Command
trustwave-get-updated-tickets
Input
| Argument Name | Description | Required |
|---|---|---|
| since | Absolute or relative date to check for updates. | Required |
| fetch_limit | Maximum number of tickets to fetch. Default is 100. | Optional |
| ticket_types | Ticket type to query. Possible values are: INCIDENT, CASE, CHANGE. Default is INCIDENT. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Trustwave.Ticket.number | String | The Ticket ID |
| Trustwave.Ticket.subject | String | The ticket title. |
| Trustwave.Ticket.status | String | The status of the ticket |
| Trustwave.Ticket.description | String | The detailed ticket description. |
| Trustwave.Ticket.category | String | Ticket category. |
| Trustwave.Ticket.createdBy | String | User that created the ticket. |
| Trustwave.Ticket.createdOn | Date | The time when the ticket was created. |
| Trustwave.Ticket.customerName | String | The name of the customer. |
| Trustwave.Ticket.formatted_notes | String | Human readable notes. |
| Trustwave.Ticket.impact | String | Ticket impact (HIGH, MEDIUM, LOW) |
| Trustwave.Ticket.notes.actor | String | User that added the note (comment) |
| Trustwave.Ticket.notes.text | String | The note (comment) text. |
| Trustwave.Ticket.notes.timestamp | Date | Time when the note (comment) was created. |
| Trustwave.Ticket.priority | String | Ticket priority (CRITICAL, HIGH, MEDIUM, LOW) |
| Trustwave.Ticket.subCategory | String | Ticket sub-category. |
| Trustwave.Ticket.type | String | The ticket type (CASE, INCIDENT, CHANGE) |
| Trustwave.Ticket.updatedOn | Date | When the ticket was last updated. |
| Trustwave.Ticket.urgency | String | The ticket urgency (HIGH, MEDIUM, LOW) |
Command example
!trustwave-get-updated-tickets fetch_limit=2 since=2021-12-09T16:43:48.000+00:00
Context Example
{
"Trustwave": {
"Ticket": [
{
"assetIds": [
"765432:managed-device#DEVICE:AW8Qp1Bextjwd2cF57Mk"
],
"category": "Technology Management",
"createdBy": "cpe_outage_service",
"createdOn": "2021-11-29T10:56:45.000+00:00",
"customerName": "Sample Customer",
"description": "",
"findings": [],
"formatted_notes": "2021-11-29T10:56:44.000+00:00 Created by: cpe_outage_service\nNOTE:\nNOTE A",
"impact": "HIGH",
"notes": [
{
"actor": "cpe_outage_service",
"text": "NOTE A",
"timestamp": "2021-11-29T10:56:44.000+00:00"
}
],
"number": "INA1077007",
"priority": "HIGH",
"status": "CLOSED",
"subCategory": "Cellular Backup",
"subject": "Alert: device is using cellular",
"type": "INCIDENT",
"updatedOn": "2021-12-29T00:00:08.000+00:00",
"urgency": "MEDIUM"
},
{
"assetIds": [],
"category": "Threat Detection & Response",
"createdBy": "dummyuser",
"createdOn": "2021-12-08T17:16:27.000+00:00",
"customerName": "Sample Customer",
"description": "Ticket description",
"findings": [
{
"classification": null,
"classificationCode": "UnauthorizedAccessOrIntrusionAttempt.",
"findingId": "765432:THREAT:@AXv0k6GhG2zTcaogE1vG"
}
],
"formatted_notes": "2021-12-08T17:16:27.000+00:00 Created by: dummyuser\nNOTE:\nSample Note.\n----------------\n2021-12-08T17:17:57.000+00:00 Created by: dummyuser\nNOTE:\nSample note #2.\n----------------\n2021-12-09T16:43:31.000+00:00 Created by: dummy_user\nNOTE:\nSample note #3",
"impact": "HIGH",
"notes": [
{
"actor": "dummyuser",
"text": "Sample Note.",
"timestamp": "2021-12-08T17:16:27.000+00:00"
},
{
"actor": "dummyuser",
"text": "Sample note #2.",
"timestamp": "2021-12-08T17:17:57.000+00:00"
},
{
"actor": "dummy_user",
"text": "Sample note #3",
"timestamp": "2021-12-09T16:43:31.000+00:00"
}
],
"number": "INA1077535",
"priority": "HIGH",
"status": "ON_HOLD",
"subCategory": "Threat Operations",
"subject": "MCAS - Impossible travel activity",
"type": "INCIDENT",
"updatedOn": "2021-12-09T16:43:48.000+00:00",
"urgency": "MEDIUM"
}
]
}
}
Human Readable Output
Results
assetIds category createdBy createdOn customerName description findings formatted_notes impact notes number priority status subCategory subject type updatedOn urgency 765432:managed-device#DEVICE:AW8Qp1Bextjwd2cF57Mk Technology Management cpe_outage_service 2021-11-29T10:56:45.000+00:00 Sample Customer 2021-11-29T10:56:44.000+00:00 Created by: cpe_outage_service
NOTE:
NOTE AHIGH {‘actor’: ‘cpe_outage_service’, ‘text’: ‘NOTE A’, ‘timestamp’: ‘2021-11-29T10:56:44.000+00:00’} INA1077007 HIGH CLOSED Cellular Backup Alert: device is using cellular INCIDENT 2021-12-29T00:00:08.000+00:00 MEDIUM Threat Detection & Response dummyuser 2021-12-08T17:16:27.000+00:00 Sample Customer Ticket description {‘classification’: None, ‘classificationCode’: ‘UnauthorizedAccessOrIntrusionAttempt.’, ‘findingId’: ‘765432:THREAT:@AXv0k6GhG2zTcaogE1vG’} 2021-12-08T17:16:27.000+00:00 Created by: dummyuser
NOTE:
Sample Note.
—————-
2021-12-08T17:17:57.000+00:00 Created by: dummyuser
NOTE:
Sample note #2.
—————-
2021-12-09T16:43:31.000+00:00 Created by: dummy_user
NOTE:
Sample note #3HIGH {‘actor’: ‘dummyuser’, ‘text’: ‘Sample Note.’, ‘timestamp’: ‘2021-12-08T17:16:27.000+00:00’},
{‘actor’: ‘dummyuser’, ‘text’: ‘Sample note #2.’, ‘timestamp’: ‘2021-12-08T17:17:57.000+00:00’},
{‘actor’: ‘dummy_user’, ‘text’: ‘Sample note #3’, ‘timestamp’: ‘2021-12-09T16:43:31.000+00:00’}INA1077535 HIGH ON_HOLD Threat Operations MCAS - Impossible travel activity INCIDENT 2021-12-09T16:43:48.000+00:00 MEDIUM
trustwave-search-findings
Search for Findings
Base Command
trustwave-search-findings
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Finding ID. | Optional |
| limit | Maximum number of Findings to return. Default is 100. | Optional |
| name | Name of the Finding. | Optional |
| classification | Finding Classification. | Optional |
| summary | Finding summary. | Optional |
| detail | Finding detail. | Optional |
| priority | Finding priority. Possible values are: CRITICAL, HIGH, MEDIUM, LOW. | Optional |
| severity | Finding severity. | Optional |
| created_since | created_since. | Optional |
| updated_since | Updated since. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Trustwave.Finding.classification | String | Category for the finding |
| Trustwave.Finding.createdOn | Date | Time when the finding was created. |
| Trustwave.Finding.customerName | String | Customer name for the finding. |
| Trustwave.Finding.destination | String | Destination for finding. |
| Trustwave.Finding.detail | String | Detailed description of the finding. |
| Trustwave.Finding.id | String | The finding ID |
| Trustwave.Finding.priority | Number | The priority of the finding. |
| Trustwave.Finding.severity | Number | The severity of the finding. |
| Trustwave.Finding.source | String | SOAR actions taken for finding. |
| Trustwave.Finding.status.description | String | Current status of the Finding. |
| Trustwave.Finding.summary | String | The name of the finding. |
| Trustwave.Finding.type | String | The type of finding (e.g. THREAT, VULNERABILITY) |
| Trustwave.Finding.updatedOn | Date | Time when the finding was last updated. |
Command example
!trustwave-search-findings limit="2" summary="MS Graph Alert Detection Rule" type=threat updatedSince=2021-12-08T17:17:56.000+00:00
Context Example
{
"Trustwave": {
"Finding": [
{
"classification": null,
"createdOn": "2021-09-17T16:26:11.731+00:00",
"customerName": "Sample Customer",
"destination": null,
"detail": "MCAS - Impossible travel activity",
"id": "765432:THREAT:@AXv0k6GhG2zTcaogE1vG",
"priority": 4,
"severity": 4,
"source": null,
"status": {
"description": "Security Incident"
},
"summary": "MS Graph Alert Detection Rule",
"type": "THREAT",
"updatedOn": "2021-12-08T17:17:56.504+00:00"
},
{
"classification": null,
"createdOn": "2021-10-26T22:33:17.567+00:00",
"customerName": "Sample Customer",
"destination": null,
"detail": "ASC, MSTIC - Windows registry persistence method detected pqa VM_RegistryPersistencyKey",
"id": "765432:THREAT:@AXy-u5fVt3G3ZYM6G5cH",
"priority": 2,
"severity": 2,
"source": null,
"status": {
"description": "False Positive"
},
"summary": "MS Graph Alert Detection Rule",
"type": "THREAT",
"updatedOn": "2021-12-16T17:21:31.384+00:00"
}
]
}
}
Human Readable Output
Results
classification createdOn customerName destination detail id priority severity source status summary type updatedOn 2021-09-17T16:26:11.731+00:00 Sample Customer MCAS - Impossible travel activity 765432:THREAT:@AXv0k6GhG2zTcaogE1vG 4 4 description: Security Incident MS Graph Alert Detection Rule THREAT 2021-12-08T17:17:56.504+00:00 2021-10-26T22:33:17.567+00:00 Sample Customer ASC, MSTIC - Windows registry persistence method detected pqa VM_RegistryPersistencyKey 765432:THREAT:@AXy-u5fVt3G3ZYM6G5cH 2 2 description: False Positive MS Graph Alert Detection Rule THREAT 2021-12-16T17:21:31.384+00:00
trustwave-get-finding
Get a Finding
Base Command
trustwave-get-finding
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Finding ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Trustwave.Finding.analystNotes.actor | String | User that created the analyst note. |
| Trustwave.Finding.analystNotes.text | String | Analyst note text. |
| Trustwave.Finding.analystNotes.timestamp | Date | Time when the note was created |
| Trustwave.Finding.assetsIds | String | Assets impacted by the finding |
| Trustwave.Finding.classification | String | Category for the finding |
| Trustwave.Finding.createdOn | Date | Time when the finding was created. |
| Trustwave.Finding.customerName | String | Customer name for the finding. |
| Trustwave.Finding.destination | String | Destination for finding. |
| Trustwave.Finding.detail | String | Detailed description of the finding. |
| Trustwave.Finding.eventsIds | String | List of event ID associated with the finding. |
| Trustwave.Finding.id | String | The finding ID |
| Trustwave.Finding.parentId | String | The ID of the parent of the finding. |
| Trustwave.Finding.priority | Number | The priority of the finding. |
| Trustwave.Finding.severity | Number | The severity of the finding. |
| Trustwave.Finding.source | String | Source for finding |
| Trustwave.Finding.status.description | String | Current status of the Finding. |
| Trustwave.Finding.summary | String | The name of the finding. |
| Trustwave.Finding.type | String | The type of finding (e.g. THREAT, VULNERABILITY) |
| Trustwave.Finding.updatedOn | Date | Time when the finding was last updated. |
Command example
!trustwave-get-finding id="765432:THREAT:@AXv0k6GhG2zTcaogE1vG"
Context Example
{
"Trustwave": {
"Finding": {
"analystNotes": [
{
"actor": "dummyuser",
"text": "Note A",
"timestamp": "2021-12-08T17:17:56.790+00:00"
}
],
"assetsIds": [
"765432:PERSON:AXsNy0R8CfYgZQumlNdv"
],
"childFindingIds": [],
"classification": null,
"createdOn": "2021-09-17T16:26:11.731+00:00",
"customerName": "Sample Customer",
"destination": null,
"detail": "MCAS - Impossible travel activity",
"eventsIds": [
"34c0e1b2-96e6-4a25-be3d-80d0671a5d8f"
],
"id": "765432:THREAT:@AXv0k6GhG2zTcaogE1vG",
"parentId": null,
"priority": 4,
"severity": 4,
"source": null,
"status": {
"description": "Security Incident"
},
"summary": "MS Graph Alert Detection Rule",
"type": "THREAT",
"updatedOn": "2021-12-08T17:17:56.504+00:00"
}
}
}
Human Readable Output
Results
analystNotes assetsIds childFindingIds classification createdOn customerName destination detail eventsIds id parentId priority severity source status summary type updatedOn {‘actor’: ‘dummyuser’, ‘text’: ‘Note A’, ‘timestamp’: ‘2021-12-08T17:17:56.790+00:00’} 765432:PERSON:AXsNy0R8CfYgZQumlNdv 2021-09-17T16:26:11.731+00:00 Sample Customer MCAS - Impossible travel activity 34c0e1b2-96e6-4a25-be3d-80d0671a5d8f 765432:THREAT:@AXv0k6GhG2zTcaogE1vG 4 4 description: Security Incident MS Graph Alert Detection Rule THREAT 2021-12-08T17:17:56.504+00:00
trustwave-get-asset
Get an Asset
Base Command
trustwave-get-asset
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Asset ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Trustwave.Asset.cidr | String | Network address in CIDR notation. |
| Trustwave.Asset.createdOn | Date | Time when the asset was created. |
| Trustwave.Asset.customerName | String | The customer name for the asset. |
| Trustwave.Asset.id | String | The asset ID. |
| Trustwave.Asset.ips | String | List of IP addresses for the asset. |
| Trustwave.Asset.lastActivity | Date | Time of the last activity associated with the asset. |
| Trustwave.Asset.name | String | The name of the asset. |
| Trustwave.Asset.networkInterfaces.gateway | String | Gateway address for the asset network interface. |
| Trustwave.Asset.networkInterfaces.hostnames | String | List of hostname for the asset network interface |
| Trustwave.Asset.networkInterfaces.ip | String | IP address for the asset network interface |
| Trustwave.Asset.networkInterfaces.macAddress | String | MAC address for the asset network interface |
| Trustwave.Asset.networkInterfaces.macVendor | String | Vendor associated with the MAC address for the asset network interface |
| Trustwave.Asset.networkInterfaces.subnet | String | Network subnet the asset network interface |
| Trustwave.Asset.os | String | Asset operating system. |
| Trustwave.Asset.services.applicationName | String | Service name. |
| Trustwave.Asset.services.applicationProtocol | String | Service protocol. |
| Trustwave.Asset.services.port | Number | Service port |
| Trustwave.Asset.services.transportProtocol | String | Service transport. |
| Trustwave.Asset.status | String | Asset status. |
| Trustwave.Asset.type | String | The type of asset. |
| Trustwave.Asset.updatedOn | Date | Time when the asset was last updated. |
| Trustwave.Asset.uri | String | URI of the asset. |
Command example
!trustwave-get-asset id="765432:DNA#DEVICE:AW2X-hCmXdgvNlcDpVGf"
Context Example
{
"Trustwave": {
"Asset": {
"cidr": null,
"createdOn": "2019-10-04T18:13:30.941+00:00",
"customerName": "Sample Customer",
"id": "765432:DNA#DEVICE:AW2X-hCmXdgvNlcDpVGf",
"ips": [
"10.103.201.47"
],
"lastActivity": null,
"name": "host.example.com",
"networkInterfaces": [
{
"gateway": null,
"hostnames": [
"host.example.com"
],
"ip": "10.103.201.47",
"macAddress": null,
"macVendor": null,
"subnet": null
}
],
"notes": [],
"os": null,
"services": [
{
"applicationName": null,
"applicationProtocol": null,
"port": 80,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "sunrpcportmap",
"port": 111,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "sunrpcportmap",
"port": 111,
"transportProtocol": "udp"
},
{
"applicationName": null,
"applicationProtocol": "ntp",
"port": 123,
"transportProtocol": "udp"
},
{
"applicationName": null,
"applicationProtocol": "snmp",
"port": 161,
"transportProtocol": "udp"
},
{
"applicationName": null,
"applicationProtocol": null,
"port": 443,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "mysql",
"port": 3306,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": null,
"port": 5672,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "snmp",
"port": 16161,
"transportProtocol": "udp"
}
],
"status": null,
"tags": [],
"type": "Device",
"updatedOn": "2019-10-04T19:09:59.907+00:00",
"uri": null
}
}
}
Human Readable Output
Results
cidr createdOn customerName id ips lastActivity name networkInterfaces notes os services status tags type updatedOn uri 2019-10-04T18:13:30.941+00:00 Sample Customer 765432:DNA#DEVICE:AW2X-hCmXdgvNlcDpVGf 10.103.201.47 host.example.com {‘gateway’: None, ‘hostnames’: [‘host.example.com’], ‘ip’: ‘10.103.201.47’, ‘macAddress’: None, ‘macVendor’: None, ‘subnet’: None} {‘applicationName’: None, ‘applicationProtocol’: None, ‘port’: 80, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘sunrpcportmap’, ‘port’: 111, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘sunrpcportmap’, ‘port’: 111, ‘transportProtocol’: ‘udp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘ntp’, ‘port’: 123, ‘transportProtocol’: ‘udp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘snmp’, ‘port’: 161, ‘transportProtocol’: ‘udp’},
{‘applicationName’: None, ‘applicationProtocol’: None, ‘port’: 443, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘mysql’, ‘port’: 3306, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: None, ‘port’: 5672, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘snmp’, ‘port’: 16161, ‘transportProtocol’: ‘udp’}Device 2019-10-04T19:09:59.907+00:00
trustwave-search-assets
Search for Assets
Base Command
trustwave-search-assets
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Asset ID. | Optional |
| limit | Maximum number of Assets to return. Default is 100. | Optional |
| name | Name of the Asset. | Optional |
| os | OS for the Asset. | Optional |
| tags | Asset Tags to search for. | Optional |
| port | port. | Optional |
| app_protocol | Application Protocol. | Optional |
| transport | Transport Protocol. | Optional |
| type | Asset Type. | Optional |
| created_since | created_since. | Optional |
| updated_since | Updated since. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Trustwave.Asset.cidr | String | Network address in CIDR notation. |
| Trustwave.Asset.createdOn | Date | Time when the asset was created. |
| Trustwave.Asset.customerName | String | The customer name for the asset. |
| Trustwave.Asset.id | String | The asset ID. |
| Trustwave.Asset.ips | String | List of IP addresses for the asset. |
| Trustwave.Asset.lastActivity | Date | Time of the last activity associated with the asset. |
| Trustwave.Asset.name | String | The name of the asset. |
| Trustwave.Asset.networkInterfaces.gateway | String | Gateway address for the asset network interface. |
| Trustwave.Asset.networkInterfaces.hostnames | String | List of hostname for the asset network interface |
| Trustwave.Asset.networkInterfaces.ip | String | IP address for the asset network interface |
| Trustwave.Asset.networkInterfaces.macAddress | String | MAC address for the asset network interface |
| Trustwave.Asset.networkInterfaces.macVendor | String | Vendor associated with the MAC address for the asset network interface |
| Trustwave.Asset.networkInterfaces.subnet | String | Network subnet the asset network interface |
| Trustwave.Asset.os | String | Asset operating system. |
| Trustwave.Asset.status | String | Asset status. |
| Trustwave.Asset.type | String | The type of asset. |
| Trustwave.Asset.updatedOn | Date | Time when the asset was last updated. |
| Trustwave.Asset.uri | String | URI of the asset. |
Command example
!trustwave-search-assets limit=2 type="DEVICE" name="host.example.com"
Context Example
{
"Trustwave": {
"Asset": {
"cidr": null,
"createdOn": "2019-10-04T18:13:30.941+00:00",
"customerName": "Sample Customer",
"id": "765432:DNA#DEVICE:AW2X-hCmXdgvNlcDpVGf",
"ips": [
"10.103.201.47"
],
"lastActivity": null,
"name": "host.example.com",
"networkInterfaces": [
{
"gateway": null,
"hostnames": [
"host.example.com"
],
"ip": "10.103.201.47",
"macAddress": null,
"macVendor": null,
"subnet": null
}
],
"notes": [],
"os": null,
"services": [
{
"applicationName": null,
"applicationProtocol": null,
"port": 80,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "sunrpcportmap",
"port": 111,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "sunrpcportmap",
"port": 111,
"transportProtocol": "udp"
},
{
"applicationName": null,
"applicationProtocol": "ntp",
"port": 123,
"transportProtocol": "udp"
},
{
"applicationName": null,
"applicationProtocol": "snmp",
"port": 161,
"transportProtocol": "udp"
},
{
"applicationName": null,
"applicationProtocol": null,
"port": 443,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "mysql",
"port": 3306,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": null,
"port": 5672,
"transportProtocol": "tcp"
},
{
"applicationName": null,
"applicationProtocol": "snmp",
"port": 16161,
"transportProtocol": "udp"
}
],
"status": null,
"tags": [],
"type": "Device",
"updatedOn": "2019-10-04T19:09:59.907+00:00",
"uri": null
}
}
}
Human Readable Output
Results
cidr createdOn customerName id ips lastActivity name networkInterfaces notes os services status tags type updatedOn uri 2019-10-04T18:13:30.941+00:00 Sample Customer 765432:DNA#DEVICE:AW2X-hCmXdgvNlcDpVGf 10.103.201.47 host.example.com {‘gateway’: None, ‘hostnames’: [‘host.example.com’], ‘ip’: ‘10.103.201.47’, ‘macAddress’: None, ‘macVendor’: None, ‘subnet’: None} {‘applicationName’: None, ‘applicationProtocol’: None, ‘port’: 80, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘sunrpcportmap’, ‘port’: 111, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘sunrpcportmap’, ‘port’: 111, ‘transportProtocol’: ‘udp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘ntp’, ‘port’: 123, ‘transportProtocol’: ‘udp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘snmp’, ‘port’: 161, ‘transportProtocol’: ‘udp’},
{‘applicationName’: None, ‘applicationProtocol’: None, ‘port’: 443, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘mysql’, ‘port’: 3306, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: None, ‘port’: 5672, ‘transportProtocol’: ‘tcp’},
{‘applicationName’: None, ‘applicationProtocol’: ‘snmp’, ‘port’: 16161, ‘transportProtocol’: ‘udp’}Device 2019-10-04T19:09:59.907+00:00
Configuration parameters
url— Fusion API URL (required)apikey— API Key (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsisFetch— Fetch incidentsincidentType— Incident typeincidentFetchInterval— Incidents Fetch Intervalmax_fetch— Maximum number of incidents per fetchfirst_fetch— First fetch timeticket_types— Ticket Types
Commands (9)
-
trustwave-add-ticket-commentAdd a comment to a ticket.
-
trustwave-close-ticketClose a ticket.
-
trustwave-get-assetGet an Asset.
-
trustwave-get-findingGet a Finding.
-
trustwave-get-ticketGet a single ticket.
-
trustwave-get-updated-ticketsGet updated tickets.
-
trustwave-search-assetsSearch for Assets.
-
trustwave-search-findingsSearch for Findings.
-
trustwave-search-ticketsSearch tickets.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 """Trustwave Fusion Integration for Cortex XSOAR""" from CommonServerUserPython import * # noqa import urllib3 import traceback from typing import Any import urllib.parse # Disable insecure warnings urllib3.disable_warnings() # pylint: disable=no-member """ CONSTANTS """ # Date format for Fusion searches FUSION_DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # Map Fusion priority to Demisto severity SEVERITY_MAP = { "INFO": 0.5, "LOW": 1, "MEDIUM": 2, "HIGH": 3, "CRITICAL": 4, } TICKET_FIELDS = [ "assetIds", "category", "createdBy", "createdOn", "customerName", "description", "findings", "impact", "notes", "number", "priority", "status", "subCategory", "subject", "type", "updatedOn", "urgency", "formatted_notes", ] FINDING_FIELDS = [ "analystNotes", "assetsIds", "childFindingIds", "classification", "createdOn", "customerName", "destination", "detail", "eventsIds", "id", "parentId", "priority", "severity", "source", "status", "summary", "type", "updatedOn", ] ASSET_FIELDS = [ "cidr", "createdOn", "customerName", "id", "ips", "lastActivity", "name", "networkInterfaces", "notes", "os", "services", "status", "tags", "type", "updatedOn", "uri", ] """ CLIENT CLASS """ class Client(BaseClient): """ Trustwave Fusion API Client """ def search_tickets(self, **kwargs): result = self._http_request(method="GET", url_suffix="/v2/tickets", params=kwargs) tickets = [] if result: tickets = result.get("items", []) # add formatted_notes field for tkt in tickets: if tkt["notes"]: tkt["formatted_notes"] = format_notes(tkt["notes"]) else: tkt["formatted_notes"] = "" simplify_ticket(tkt) return tickets def describe(self): return self._http_request(method="GET", url_suffix="/v2/describe") def get_ticket(self, id): quoted_id = urllib.parse.quote(id, safe="") url_suffix = f"/v2/tickets/{quoted_id}" try: ticket = self._http_request(method="GET", url_suffix=url_suffix) except DemistoException as e: if e.res is not None and e.res.status_code == 404: return None else: raise simplify_ticket(ticket) if ticket["notes"]: ticket["formatted_notes"] = format_notes(ticket["notes"]) else: ticket["formatted_notes"] = "" return ticket def add_ticket_comment(self, id, comment): quoted_id = urllib.parse.quote(id, safe="") url_suffix = f"/v1/tickets/{quoted_id}/comments" payload = { "comment": comment, } result = self._http_request( method="POST", url_suffix=url_suffix, json_data=payload, empty_valid_codes=(201,), return_empty_response=True, ) return result def close_ticket(self, id, comment): quoted_id = urllib.parse.quote(id, safe="") url_suffix = f"/v1/tickets/{quoted_id}/close" payload = { "comment": comment, } return self._http_request( method="POST", url_suffix=url_suffix, json_data=payload, empty_valid_codes=(202,), return_empty_response=True, ) def get_finding(self, id): quoted_id = urllib.parse.quote(id, safe="") url_suffix = f"/v2/findings/{quoted_id}" try: finding = self._http_request(method="GET", url_suffix=url_suffix) except DemistoException as e: if e.res is not None and e.res.status_code == 404: return None else: raise simplify_finding(finding) return finding def get_asset(self, id): quoted_id = urllib.parse.quote(id, safe="") url_suffix = f"/v2/assets/{quoted_id}" try: asset = self._http_request(method="GET", url_suffix=url_suffix) except DemistoException as e: if e.res is not None and e.res.status_code == 404: return None else: raise simplify_asset(asset) return asset def search_assets(self, **kwargs): params = {k: v for k, v in kwargs.items() if v is not None} url_suffix = "/v2/assets" results = self._http_request(method="GET", url_suffix=url_suffix, params=params) if "items" not in results: return None assets = results["items"] for asset in assets: simplify_asset(asset) return assets def search_findings(self, **kwargs): params = {k: v for k, v in kwargs.items() if v is not None} url_suffix = "/v2/findings" results = self._http_request(method="GET", url_suffix=url_suffix, params=params) if "items" not in results: return None findings = results["items"] for finding in findings: simplify_finding(finding) return findings """ HELPER FUNCTIONS """ def arg_to_datestring(arg, arg_name, required=False, format=None): dt = arg_to_datetime(arg, arg_name, required) datestr = None if dt: if format is None: format = FUSION_DATE_FORMAT datestr = dt.strftime(format) return datestr def arg_to_timestamp(arg: Any, arg_name: str, required: bool = False) -> Optional[int]: """Converts an XSOAR argument to a timestamp (seconds from epoch) This function is used to quickly validate an argument provided to XSOAR via ``demisto.args()`` into an ``int`` containing a timestamp (seconds since epoch). It will throw a ValueError if the input is invalid. If the input is None, it will throw a ValueError if required is ``True``, or ``None`` if required is ``False. :type arg: ``Any`` :param arg: argument to convert :type arg_name: ``str`` :param arg_name: argument name :type required: ``bool`` :param required: throws exception if ``True`` and argument provided is None :return: returns an ``int`` containing a timestamp (seconds from epoch) if conversion works returns ``None`` if arg is ``None`` and required is set to ``False`` otherwise throws an Exception :rtype: ``Optional[int]`` """ if arg is None: if required is True: raise ValueError(f'Missing "{arg_name}"') return None if isinstance(arg, str) and arg.isdigit(): # timestamp is a str containing digits - we just convert it to int return int(arg) if isinstance(arg, str): # we use dateparser to handle strings either in ISO8601 format, or # relative time stamps. # For example: format 2019-10-23T00:00:00 or "3 days", etc date = dateparser.parse(arg, settings={"TIMEZONE": "UTC"}) if date is None: # if d is None it means dateparser failed to parse it raise ValueError(f"Invalid date: {arg_name}") return int(date.replace(tzinfo=timezone.utc).timestamp()) if isinstance(arg, int | float): # Convert to int if the input is a float return int(arg) raise ValueError(f'Invalid date: "{arg_name}"') def format_notes(notes, limit=5): """Format notes json from the Fusion API""" results = [] for note in notes: actor = note.get("actor", "") ts = note.get("timestamp", "") text = note.get("text", "") results.append(f"{ts} Created by: {actor}") results.append("NOTE:") for line in text.split("\n"): results.append(f"{line}") results.append("----------------") if results: results.pop() return "\n".join(results) """ COMMAND FUNCTIONS """ def test_module(client: Client) -> str: """Tests API connectivity and authentication' Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. Raises exceptions if something goes wrong. :type client: ``Client`` :param Client: client to use :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ message: str = "" try: client.describe() message = "ok" except DemistoException as e: if e.res is not None and e.res.status_code == 401: message = "Authorization Error: make sure API Key is correctly set" else: raise return message def fetch_incidents(client, max_results, first_fetch): demisto.debug(f"Fetching {max_results}, {first_fetch} {type(first_fetch)}") last_run = demisto.getLastRun() last_fetch = last_run.get("last_fetch", None) demisto.debug(f"last_run: {last_run}") if last_fetch is None: # if missing, use what provided via first_fetch last_fetch = first_fetch else: # otherwise use the stored last fetch last_fetch = int(last_fetch) search_since = max(first_fetch, last_fetch) demisto.debug(f"{first_fetch} <=> {last_fetch} == {search_since}") created_since = timestamp_to_datestring(search_since * 1000, FUSION_DATE_FORMAT) ticket_types = demisto.params().get("ticket_types") incidents = [] params = { "pageSize": max_results, "createdSince": created_since, "sortField": "createdOn", "sortDescending": "false", } if ticket_types: params["type"] = ",".join(ticket_types) demisto.debug(f"params: {params}") tickets = client.search_tickets(**params) latest_timestamp = search_since if tickets: demisto.debug(f"Found {len(tickets)} tickets from Fusion") for tkt in tickets: simplify_ticket(tkt) incident = { "name": tkt["subject"], "occurred": tkt["createdOn"], "description": tkt.get("description", ""), "severity": SEVERITY_MAP.get(tkt.get("priority"), 0), "rawJSON": json.dumps(tkt), } dt = dateparser.parse(tkt["createdOn"], settings={"TIMEZONE": "UTC"}) assert dt is not None, f'could not parse {tkt["createdOn"]}' latest_timestamp = max(dt.timestamp(), latest_timestamp) incidents.append(incident) # One second in the future to prevent duplicates last_run = {"last_fetch": latest_timestamp + 1} demisto.setLastRun(last_run) demisto.incidents(incidents) def simplify_ticket(ticket): if not ticket: return for f in list(ticket.keys()): if f not in TICKET_FIELDS: del ticket[f] def simplify_finding(finding): if not finding: return for f in list(finding.keys()): if f not in FINDING_FIELDS: del finding[f] if finding.get("status"): finding["status"].pop("code", None) def simplify_asset(asset): if not asset: return for f in list(asset.keys()): if f not in ASSET_FIELDS: del asset[f] def get_ticket_command(client, args): id = args.get("id") ticket = client.get_ticket(id) if ticket is None: return CommandResults(readable_output=f"Ticket {id} not found") readable = [ "| field | value |", "|-|-|", ] for k, v in ticket.items(): str_value = stringEscapeMD(formatCell(v), True, True) if len(str_value) > 200: str_value = str_value[:200] + "....[Truncated]" readable.append(f"| {k} | {str_value} |") command_results = CommandResults( outputs_prefix="Trustwave.Ticket", outputs_key_field="number", outputs=ticket, readable_output="\n".join(readable), ) return command_results def add_ticket_comment_command(client, args): id = args.get("id") comment = args.get("comment") client.add_ticket_comment(id, comment) return "Success" def close_ticket_command(client, args): id = args.get("id") comment = args.get("comment") client.close_ticket(id, comment) return "Success" def get_finding_command(client, args): id = args.get("id") finding = client.get_finding(id) if finding: # TODO: Add readable_output (markdown) for warroom view command_results = CommandResults(outputs_prefix="Trustwave.Finding", outputs_key_field="id", outputs=finding) else: command_results = CommandResults(readable_output=f"Finding {id} not found") return command_results def get_asset_command(client, args): id = args.get("id") asset = client.get_asset(id) if asset: # TODO: Add readable_output (markdown) for warroom view command_results = CommandResults(outputs_prefix="Trustwave.Asset", outputs_key_field="id", outputs=asset) else: command_results = CommandResults(readable_output=f"Asset {id} not found") return command_results def get_updated_tickets_command(client, args): updated_since = arg_to_datestring(args.get("since"), arg_name="since", required=True, format=FUSION_DATE_FORMAT) ticket_types = args.get("ticket_types", "INCIDENT") max_tickets = args.get("fetch_limit", 100) demisto.debug(f"Searching since {updated_since}") tickets = client.search_tickets(updatedSince=updated_since, type=ticket_types, pageSize=max_tickets) if tickets: command_results = CommandResults(outputs_prefix="Trustwave.Ticket", outputs_key_field="number", outputs=tickets) else: command_results = CommandResults(readable_output="No updated tickets found") return command_results def search_findings_command(client, args): finding_id = args.get("id") limit = args.get("limit", 100) name = args.get("name") classification = args.get("classification") summary = args.get("summary") detail = args.get("detail") severity = args.get("severity") priority = args.get("priority") created = arg_to_datestring(args.get("created_since"), arg_name="created_since", required=False, format=FUSION_DATE_FORMAT) demisto.debug(f"created: {created}") updated = arg_to_datestring(args.get("updated_since"), arg_name="updated_since", required=False, format=FUSION_DATE_FORMAT) demisto.debug(f"updated: {updated}") findings = None if finding_id is not None: finding = client.get_finding(finding_id) if finding: findings = [finding] else: findings = client.search_findings( pageSize=limit, name=name, classification=classification, summary=summary, detail=detail, priority=priority, severity=severity, createdSince=created, updatedSince=updated, ) if findings: command_results = CommandResults(outputs_prefix="Trustwave.Finding", outputs_key_field="id", outputs=findings) else: command_results = CommandResults(readable_output="No matching findings found") return command_results def search_assets_command(client, args): demisto.debug(f"args = {args}") asset_id = args.get("id") limit = args.get("limit", 100) name = args.get("name") ips = args.get("ips") demisto.debug(f"ips= {ips}") os = args.get("os") tags = args.get("tags") port = args.get("port") app_proto = args.get("app_protocol") transport = args.get("transport") asset_type = args.get("type") created = arg_to_datestring(args.get("created_since"), arg_name="created_since", required=False, format=FUSION_DATE_FORMAT) updated = arg_to_datestring(args.get("updated_since"), arg_name="updated_since", required=False, format=FUSION_DATE_FORMAT) assets = None if asset_id is not None: asset = client.get_asset(asset_id) if asset: assets = [asset] else: assets = client.search_assets( pageSize=limit, name=name, ips=ips, os=os, tags=tags, port=port, applicationProtocol=app_proto, transportProtocol=transport, type=asset_type, createdSince=created, updatedSince=updated, ) if assets: command_results = CommandResults(outputs_prefix="Trustwave.Asset", outputs_key_field="id", outputs=assets) else: command_results = CommandResults(readable_output="No matching assets found") return command_results def search_tickets_command(client, args): demisto.debug(f"args = {args}") ticket_id = args.get("id") subject = args.get("subject") limit = args.get("limit", 100) ticket_type = args.get("type") status = args.get("status") priority = args.get("priority") impact = args.get("impact") urgency = args.get("urgency") created = arg_to_datestring(args.get("created_since"), arg_name="created_since", required=False, format=FUSION_DATE_FORMAT) updated = arg_to_datestring(args.get("updated_since"), arg_name="updated_since", required=False, format=FUSION_DATE_FORMAT) tickets = None if ticket_id is not None: ticket = client.get_ticket(ticket_id) if ticket: tickets = [ticket] else: tickets = client.search_tickets( pageSize=limit, type=ticket_type, subject=subject, status=status, priority=priority, impact=impact, urgency=urgency, createdSince=created, updatedSince=updated, ) if tickets: command_results = CommandResults(outputs_prefix="Trustwave.Ticket", outputs_key_field="id", outputs=tickets) else: command_results = CommandResults(readable_output="No matching tickets found") return command_results """ MAIN FUNCTION """ def main() -> None: """main function, parses params and runs command functions :return: :rtype: """ api_key = demisto.params().get("apikey") base_url = demisto.params()["url"] verify_certificate = not demisto.params().get("insecure", False) proxy = demisto.params().get("proxy", False) first_fetch = arg_to_timestamp( arg=demisto.params().get("first_fetch", "3 days"), arg_name="First fetch time", required=True, ) max_fetch = 100 try: max_fetch = int(demisto.params().get("max_fetch", "100")) except ValueError: return_error("Maximum number of incidents per fetch needs to be an integer") demisto.debug(f"Command being called is {demisto.command()}") try: headers: dict = { "Authorization": f"Bearer {api_key}", } client = Client(base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy) if demisto.command() == "test-module": # This is the call made when pressing the integration Test button. result = test_module(client) return_results(result) elif demisto.command() == "fetch-incidents": fetch_incidents(client, max_fetch, first_fetch) elif demisto.command() == "trustwave-get-ticket": return_results(get_ticket_command(client, demisto.args())) elif demisto.command() == "trustwave-add-ticket-comment": return_results(add_ticket_comment_command(client, demisto.args())) elif demisto.command() == "trustwave-close-ticket": return_results(close_ticket_command(client, demisto.args())) elif demisto.command() == "trustwave-get-finding": return_results(get_finding_command(client, demisto.args())) elif demisto.command() == "trustwave-get-updated-tickets": return_results(get_updated_tickets_command(client, demisto.args())) elif demisto.command() == "trustwave-get-asset": return_results(get_asset_command(client, demisto.args())) elif demisto.command() == "trustwave-search-assets": return_results(search_assets_command(client, demisto.args())) elif demisto.command() == "trustwave-search-findings": return_results(search_findings_command(client, demisto.args())) elif demisto.command() == "trustwave-search-tickets": return_results(search_tickets_command(client, demisto.args())) # Log exceptions and return errors except Exception as e: demisto.error(traceback.format_exc()) # print the traceback return_error(f"Failed to execute {demisto.command()} command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()