From 312bf7493a57b1ca77534ba7071cd25c6fc5d052 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 29 Oct 2023 17:03:22 +0200 Subject: [PATCH] [Marketplace Contribution] Dragos Worldview - Content Pack Update (#30207) (#30504) * "contribution update to pack "Dragos Worldview"" * Update DragosWorldview.yml FIxed error with missing period in description * Update DragosWorldview_description.md Fixed spelling mistake * Update DragosWorldview.yml Added a period to the end of all command, argument, and output descriptions * Update README.md Added input and output tables for dragos-get-indicators() * Changed credential for backwards compatibility Split username/password setup of credential into two password only ones. Added back old encrypted parameters for backwards compatibility * Added backwards compatibility for credentials Updated key and token check to support old encryption and new credential parameters. * Updated docker image tag * Added back link * Updating docker image * Update Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.yml * Update Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.yml * Update DragosWorldview.py Added bug fix where multiple page numbers could be in an api call Added suggested Boolean wrapper and default * Removed redundant boolean check * changed output's key field back to indicator_id * Added suggested int wrapper for page * Fixed formatting issues and updated docker * Changed id > indicator_id in outputs * Removed parathesis for bug fix * Type casted raw_response[...] to int * Added requested changes Added descriptions to the integration parameters Changed order of columns for !dragos-get-indicators() output table Added example commands for all 4 integration commands * Added human readable output for dragos-get-indicators() * Added human readable output example for dragos-get-indicators() * Update 1_1_3.md * update README - fix validation * update correct README --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: Nicole Casartelli Co-authored-by: Israel Lappe <79846863+ilappe@users.noreply.github.com> Co-authored-by: ilappe --- .../DragosWorldview/DragosWorldview.py | 78 +++++++--- .../DragosWorldview/DragosWorldview.yml | 146 +++++++++++++++--- .../Integrations/DragosWorldview/README.md | 67 +++++--- Packs/DragosWorldview/ReleaseNotes/1_1_3.md | 9 ++ Packs/DragosWorldview/pack_metadata.json | 2 +- 5 files changed, 240 insertions(+), 62 deletions(-) create mode 100644 Packs/DragosWorldview/ReleaseNotes/1_1_3.md diff --git a/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.py b/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.py index 4c2a92cac883..1c60693c1934 100644 --- a/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.py +++ b/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.py @@ -3,12 +3,9 @@ import json from datetime import datetime, timedelta from typing import Any, Callable, Dict, Tuple - import dateparser - import urllib3 - """Dragos Worldview Integration for XSOAR.""" # flake8: noqa: F402,F405 lgtm @@ -79,26 +76,60 @@ def get_stix(client: Client, args: Dict[str, Any]) -> Dict[str, Any]: def get_indicators(client: Client, args: Dict[str, Any]) -> CommandResults: - serial = args.get('serial') - if serial: - api_query = "indicators?serial%5B%5D=" + serial + exclude_suspect_domain = argToBoolean(args.get('exclude_suspect_domain', False)) + page = args.get('page') + page_size = args.get('page_size') + updated_after = args.get('updated_after') + value = args.get('value') + indicator_type = args.get('type') + serials = argToList(args.get('serial')) + tags = argToList(args.get('tags')) + + # The arguments page, page_size and exclude_suspect_domain have an API default of 1, 500 and false respectively, + # and do not need to be included in the query unless changed + query_list = [] + if page: + query_list.append('page=' + page) + if exclude_suspect_domain: + query_list.append('exclude_suspect_domain=' + str(exclude_suspect_domain).lower()) + if page_size: + query_list.append('page_size=' + page_size) + if updated_after: + query_list.append('updated_after=' + updated_after.replace(":", "%3A")) + if value: + query_list.append('value=' + value) + if indicator_type: + query_list.append('type=' + indicator_type) + for serial in serials: + query_list.append('serial%5B%5D=' + serial) + for tag in tags: + query_list.append('tags%5B%5D=' + tag) + + # If any arguments were submitted then run the relevent query, + # else return all indicators from the last 48 hours + if query_list: + query_string = '&'.join(query_list) + api_query = f'indicators?{query_string}' else: - time = datetime.now() - timedelta(hours=48) - api_query = "indicators?updated_after=" - api_query = api_query + str(time) - api_query = api_query.replace(":", "%3A") - + time = str(datetime.now() - timedelta(hours=48)) + time = time.replace(":", "%3A") + api_query = f'indicators?updated_after={time}' raw_response = client.api_request(api_query) data = raw_response['indicators'] - page_number = 2 + page_number = 2 if not page else int(page) + 1 + if page: + query_list.pop(0) + query_string = '&'.join(query_list) full_response = raw_response - - while raw_response['total_pages'] >= raw_response['page']: - if serial: - api_query = "indicators?page=" + str(page_number) + "&serial%5B%5D=" + serial + + # If there are still more dragos pages (ie more indicators) than was returned by + # the intial query, iterate through the remaining pages and add all unique indicators + # to the return data + while int(raw_response['total_pages']) > int(raw_response['page']): + if query_list: + api_query = f'indicators?page={page_number}&{query_string}' else: - api_query = "indicators?page=" + str(page_number) + "&updated_after=" + str(time) - api_query = api_query.replace(":", "%3A") + api_query = f'indicators?page={page_number}&updated_after={time}' page_number += 1 raw_response = client.api_request(api_query) new_data = raw_response['indicators'] @@ -112,6 +143,7 @@ def get_indicators(client: Client, args: Dict[str, Any]) -> CommandResults: outputs_prefix='Dragos.Indicators', outputs_key_field='indicator_id', outputs=data, + readable_output=tableToMarkdown('Dragos Indicators', data), raw_response=full_response ) @@ -164,10 +196,16 @@ def main() -> None: base_url = base_url + "/api/v1" verify_ssl = not demisto_params.get("insecure", False) proxy = demisto_params.get("proxy", False) + api_token = demisto_params.get("credential_token", {}).get("password") or demisto_params.get("apitoken") + if not api_token: + return_error('Please provide a valid API token') + api_key = demisto_params.get("credential_key", {}).get("password") or demisto_params.get("apikey") + if not api_key: + return_error('Please provide a valid API key') headers = { "accept": "*/*", - "API-TOKEN": demisto_params["apitoken"], - "API-SECRET": demisto_params["apikey"], + "API-TOKEN": api_token, + "API-SECRET": api_key, } client = Client( base_url=base_url, verify=verify_ssl, headers=headers, proxy=proxy diff --git a/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.yml b/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.yml index b8040dbcde29..3e5ff4c02008 100644 --- a/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.yml +++ b/Packs/DragosWorldview/Integrations/DragosWorldview/DragosWorldview.yml @@ -8,19 +8,33 @@ configuration: name: url required: true type: 0 +- display: API Token + name: credential_token + required: false + type: 9 + displaypassword: API Token + hiddenusername: true +- display: API Key + name: credential_key + required: false + type: 9 + displaypassword: API Key + hiddenusername: true - display: API Token name: apitoken - required: true + required: false type: 4 + hidden: true - display: API Key name: apikey - required: true + required: false type: 4 -- defaultvalue: 3 days - display: First fetch time + hidden: true +- display: First fetch time name: first_fetch - type: 0 required: false + type: 0 + defaultvalue: 3 days - display: Trust any certificate (not secure) name: insecure type: 8 @@ -29,21 +43,21 @@ configuration: name: proxy type: 8 required: false -- defaultvalue: '1' - display: Incidents Fetch Interval +- display: Incidents Fetch Interval name: incidentFetchInterval type: 19 required: false -- additionalinfo: The Traffic Light Protocol (TLP) designation to apply to indicators - display: Traffic Light Protocol Color + defaultvalue: '1' +- display: Traffic Light Protocol Color name: tlp_color + type: 15 + required: false + additionalinfo: The Traffic Light Protocol (TLP) designation to apply to indicators options: - RED - AMBER - GREEN - WHITE - type: 15 - required: false - display: Fetch incidents name: isFetch type: 8 @@ -52,45 +66,131 @@ configuration: name: incidentType type: 13 required: false -- defaultvalue: '50' - display: Fetch Limit +- display: Fetch Limit name: max_fetch type: 0 required: false -description: 'Custom integration designed to pull in reports from the Dragos Worldview API as incidents ' + defaultvalue: '50' +description: 'Custom integration designed to pull in reports from the Dragos Worldview API as incidents.' display: Dragos Worldview name: Dragos Worldview script: commands: - arguments: - - description: Report serial number to get indicators from, if no serial number provided command will retrieve all indicators from the last 48 hours + - description: Exclude indicators that are only associated with Suspect Domain Reports (API default false). + name: exclude_suspect_domain + auto: PREDEFINED + predefined: + - 'true' + - 'false' + - description: Page number to start at (API default 1). + name: page + - description: Page size (API default 500) (must be less than 1001). + name: page_size + - description: UTC timestamp in YYYY-mm-dd (optionally with HH:mm:ss) to filter to recent indicators (default is within the last 48 hours). + name: updated_after + - description: Search for indicators that match a specific value. + name: value + - auto: PREDEFINED + description: Search for indicators of a specific type. + name: type + predefined: + - domain + - filename + - hostname + - ip + - md5 + - sha1 + - sha256 + - description: List of Dragos report serial number to get indicators from. + isArray: true name: serial - description: Get Indicators from the Dragos WorldView API + - description: List of tags to search for indicators. + isArray: true + name: tags + description: Get Indicators from the Dragos WorldView API, if no arguments are provided the command will retrieve all indicators from the last 48 hours. name: dragos-get-indicators + outputs: + - contextPath: Dragos.Indicators.activity_groups + description: A list of activity groups. + - contextPath: Dragos.Indicators.attack_techniques + description: A list of attack techniques. + - contextPath: Dragos.Indicators.category + description: The Dragos Indicator's category. + type: string + - contextPath: Dragos.Indicators.comment + description: The Dragos Indicator's comment. + type: string + - contextPath: Dragos.Indicators.confidence + description: The Dragos Indicator's confidence. + type: string + - contextPath: Dragos.Indicators.first_seen + description: The first time the Indicator was seen in Dragos (yyyy-mm-ddThh:mm:ss.sssZ). + type: string + - contextPath: Dragos.Indicators.ics_attack_techniques + description: A list of ics attack techniques. + - contextPath: Dragos.Indicators.indicator_id + description: The Dragos Indicator's id. + type: number + - contextPath: Dragos.Indicators.indicator_type + description: The Dragos Indicator's type. + type: string + - contextPath: Dragos.Indicators.kill_chain + description: The Dragos Indicator's kill chain. + type: string + - contextPath: Dragos.Indicators.kill_chains + description: A list of kill chains. + - contextPath: Dragos.Indicators.last_seen + description: The last time the Indicator was seen in Dragos (yyyy-mm-ddThh:mm:ss.sssZ). + type: string + - contextPath: Dragos.Indicators.pre_attack_techniques + description: A list of pre-attack techniques. + - contextPath: Dragos.Indicators.products + description: A list of dictionaries, usually containing the serial numbers of related Dragos reports. + - contextPath: Dragos.Indicators.products.serial + description: The serial numbers of related Dragos reports. + - contextPath: Dragos.Indicators.severity + description: The Dragos Indicator's severity. + type: string + - contextPath: Dragos.Indicators.status + description: The Dragos Indicator's status. + type: string + - contextPath: Dragos.Indicators.threat_groups + description: A list of threat groups. + - contextPath: Dragos.Indicators.updated_at + description: The last time the Indicator was updated in Dragos (yyyy-mm-ddThh:mm:ss.sssZ). + type: string + - contextPath: Dragos.Indicators.uuid + description: The Dragos Indicator's uuid. + type: string + - contextPath: Dragos.Indicators.value + description: The Dragos Indicator's value. + type: string - arguments: - - description: Serial number for the report to retrieve + - description: Serial number for the report to retrieve. name: serial required: true - description: Get the report file from the given serial number + description: Get the report file from the given serial number. name: dragos-get-full-report - arguments: - - description: Serial number of the report from which to get the file + - description: Serial number of the report from which to get the file. name: serial required: true - description: Get csv file with indicators from a given report + description: Get csv file with indicators from a given report. name: dragos-get-ioc-csv - arguments: - - description: Serial number of the report from which to retrieve the file + - description: Serial number of the report from which to retrieve the file. name: serial required: true - description: Get the stix2 json bundle of indicators from a given report + description: Get the stix2 json bundle of indicators from a given report. name: dragos-get-stix2 - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.78960 isFetchSamples: true isfetch: true script: '' subtype: python3 type: python + runonce: false fromversion: 6.2.0 tests: - No tests (auto formatted) diff --git a/Packs/DragosWorldview/Integrations/DragosWorldview/README.md b/Packs/DragosWorldview/Integrations/DragosWorldview/README.md index e75086c92347..963c7c3fdd07 100644 --- a/Packs/DragosWorldview/Integrations/DragosWorldview/README.md +++ b/Packs/DragosWorldview/Integrations/DragosWorldview/README.md @@ -9,17 +9,17 @@ This integration was integrated and tested with version 1.0 of Dragos Worldview | **Parameter** | **Description** | **Required** | | --- | --- | --- | - | Server URL (e.g. https://portal.dragos.com) | | True | - | API Token | | True | - | API Key | | True | - | First fetch time | | False | - | Trust any certificate (not secure) | | False | - | Use system proxy settings | | False | - | Incidents Fetch Interval | | False | + | Server URL (e.g. https://portal.dragos.com) | The Dragos server URL | True | + | API Token | The API token | True | + | API Key | The key for the API Token | True | + | First fetch time | The first time to run a fetch request | False | + | Trust any certificate (not secure) | If true trust any certicicate | False | + | Use system proxy settings | If true use system proxy settings | False | + | Incidents Fetch Interval | How often to fetch incidents | False | | Traffic Light Protocol Color | The Traffic Light Protocol \(TLP\) designation to apply to indicators | False | - | Fetch incidents | | False | - | Incident type | | False | - | Fetch Limit | | False | + | Fetch incidents | If true fetch incidents in a feed | False | + | Incident type | The incident type | False | + | Fetch Limit | The fetch limit | False | 4. Click **Test** to validate the URLs, token, and connection. ## Commands @@ -37,18 +37,51 @@ Get Indicators from the Dragos WorldView API | **Argument Name** | **Description** | **Required** | | --- | --- | --- | +| exclude_suspect_domain | Exclude indicators that are only associated with Suspect Domain Reports (API default false). | Optional | FContext +| page | Page number to start at (API default 1). | Optional | +| page_size | Page size (API default 500) (must be less than 1001). | Optional | | serial | Report serial number to get indicators from, if no serial number provided command will retrieve all indicators from the last 48 hours. | Optional | - +| tags | List of tags to search for indicators. | Optional | +| type | Search for indicators of a specific type. | Optional | +| updated_after | UTC timestamp in YYYY-mm-dd (optionally with HH:mm:ss) to filter to recent indicators (default is within the last 48 hours). | Optional | +| value | Search for indicators that match a specific value. | Optional | #### Context Output -There is no context output for this command. +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Dragos.Indicators.activity_groups | Unknown | A list of activity groups. | +| Dragos.Indicators.attack_techniques | Unknown | A list of attack techniques. | +| Dragos.Indicators.category | String | The Dragos Indicator's category. | +| Dragos.Indicators.comment | String | The Dragos Indicator's comment. | +| Dragos.Indicators.confidence | String | The Dragos Indicator's confidence. | +| Dragos.Indicators.first_seen | String | The first time the Indicator was seen in Dragos (yyyy-mm-ddThh:mm:ss.sssZ). | +| Dragos.Indicators.ics_attack_techniques | Unknown | A list of ics attack techniques. | +| Dragos.Indicators.indicator_id | Number | The Dragos Indicator's id. | +| Dragos.Indicators.indicator_type | String | The Dragos Indicator's type. | +| Dragos.Indicators.kill_chain | String | The Dragos Indicator's kill chain. | +| Dragos.Indicators.kill_chains | Unknown | A list of kill chains. | +| Dragos.Indicators.last_seen | String | The last time the Indicator was seen in Dragos (yyyy-mm-ddThh:mm:ss.sssZ). | +| Dragos.Indicators.pre_attack_techniques | Unknown | A list of pre-attack techniques. | +| Dragos.Indicators.products | Unknown | A list of dictionaries, usually containing the serial numbers of related Dragos reports. | +| Dragos.Indicators.products.serial | Unknown | The serial numbers of related Dragos reports. | +| Dragos.Indicators.severity | String | The Dragos Indicator's severity. | +| Dragos.Indicators.status | String | The Dragos Indicator's status. | +| Dragos.Indicators.threat_groups | Unknown | A list of threat groups. | +| Dragos.Indicators.updated_at | String | The last time the Indicator was updated in Dragos (yyyy-mm-ddThh:mm:ss.sssZ). | +| Dragos.Indicators.uuid | String | The Dragos Indicator's uuid. | +| Dragos.Indicators.value | String | The Dragos Indicator's value. | + #### Command Example -``` ``` +```!dragos-get-indicators exclude_suspect_domain=false page=1 page_size=500 serial=DOM-2023-37 tags=test type=domain updated_after=2023-12-31 value=example.com``` #### Human Readable Output +## Dragos Indicators +| activity_groups | attack_techniques | category | comment | confidence | first_seen | ics_attack_techniques | id | indicator_type | kill_chain | kill_chains | last_seen | pre_attack_techniques | products | severity | status | threat_groups | updated_at | uuid | value | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| | | | | moderate | 2018-04-06T00:00:00.000Z | | 0000 | domain | | | 2023-09-12T19:37:31.000Z | | {'serial': 'DOM-2023-37'} | | released | | 2024-09-12T21:31:51.000Z | | example.com | ### dragos-get-full-report @@ -71,7 +104,7 @@ Get the report file from the given serial number There is no context output for this command. #### Command Example -``` ``` +```!dragos-get-full-report serial=DOM-2023-37``` #### Human Readable Output @@ -97,7 +130,7 @@ Get csv file with indicators from a given report There is no context output for this command. #### Command Example -``` ``` +```!dragos-get-ioc-csv serial=DOM-2023-37``` #### Human Readable Output @@ -123,8 +156,6 @@ Get the stix2 json bundle of indicators from a given report There is no context output for this command. #### Command Example -``` ``` +```!dragos-get-stix2 serial=DOM-2023-37``` #### Human Readable Output - - diff --git a/Packs/DragosWorldview/ReleaseNotes/1_1_3.md b/Packs/DragosWorldview/ReleaseNotes/1_1_3.md new file mode 100644 index 000000000000..b474a3eeccad --- /dev/null +++ b/Packs/DragosWorldview/ReleaseNotes/1_1_3.md @@ -0,0 +1,9 @@ + +#### Integrations + +##### Dragos Worldview + +- Added support for api arguments to dragos-get-indicators + - Command is still backwards compatible, the previous behavior of returning all indicators from the last 48 hours is still supported when the command is run with no arguments +- Added support for using XSOAR credentials +- Updated the Docker image to: *demisto/python3:3.10.13.78960*. diff --git a/Packs/DragosWorldview/pack_metadata.json b/Packs/DragosWorldview/pack_metadata.json index d85e9a4e8cda..9d84fdbcdebd 100644 --- a/Packs/DragosWorldview/pack_metadata.json +++ b/Packs/DragosWorldview/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Dragos Worldview", "description": "The pack contains an integration the pulls from the Dragos Worldview API. The integration can be configured to fetch report as incidents. The has commands which can pull the indicators related to a report and any files associated with the report in the API.", "support": "community", - "currentVersion": "1.1.2", + "currentVersion": "1.1.3", "author": "Accenture", "url": "", "email": "",