Details
| ID | PICUS |
|---|---|
| Provider | PicusSecurity |
| Category | Network Security |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.10.12.63474 |
| Supported Modules | Agentix XSIAM |
README
Continuous Breach And Attack Simulation
Configure PICUS in Cortex
| Parameter | Description | Required |
|---|---|---|
| PICUS URL | For example : https://192.168.100.100/ | True |
| API Key - Refresh Token | Picus Interface - SETTINGS - ADVANCED - API TOKEN - Generate and Show Token | True |
| Trust any certificate (not secure) | ||
| Use system proxy settings |
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.
picus-vector-compare
Attack Result - Makes a comparison of the given vector’s results. Example Command: !picus-vector-compare begin_date=2020-01-20 end_date=2021-01-20 trusted=Trusted_Peer1 untrusted=Untrusted_Peer1
Base Command
picus-vector-compare
Input
| Argument Name | Description | Required |
|---|---|---|
| begin_date | Result begin date. | Required |
| end_date | Result end date. | Required |
| trusted | Victem Peer. | Required |
| untrusted | Attacker Peer. | Required |
Context Output
There is no context output for this command.
picus-attack-result-list
Returns the list of the attack results have optional parameters for pagination and filtration. \nExample Command:\n !picus-attack-result-list attack_result=insecure begin_date=2020-01-01 end_date=2020-09-05 vector1=Trusted-Peer1 vector2=Untrusted-Peer1
Base Command
picus-attack-result-list
Input
| Argument Name | Description | Required |
|---|---|---|
| attack_result | Attack results that should be filtered. Secure or Insecure. Possible values are: secure, insecure. Default is insecure. | Required |
| begin_date | Threat release date filter start of the date range. | Required |
| console_output_info | Default: false - Process Results of Scenario Details have console output information which can be in large sizes so this data is disabled by default. Default is False. | Optional |
| end_date | string Default: “Today’s date formatted YYYY-mm-dd” Threat release date filter end of the date range if a begin date is given and end date not, default will be used. | Required |
| from_time | Default: “null” allowed time formats RFC822, RFC822Z, RFC1123, RFC1123Z, RFC850, RFC3339. Default is null. | Optional |
| page | Default: 1 Requested page number. Default is 1. | Optional |
| size | Default: 50 Requested data size. Default is 50. | Optional |
| threat_parameters | “threat_parameters”: { “begin_date”: “2018-10-29”, “categories”: [ [ “Malicious Code” ], [ “Attack Scenario”, “Defense Evasion”, “Indicator Removal from Tools” ] ],. | Optional |
| vector1 | Array of objects (PeerPairParams) Vectors.(Trusted Peer). | Required |
| vector2 | Array of objects (PeerPairParams) Vectors.(Untrusted Peer). | Required |
Context Output
There is no context output for this command.
picus-specific-threats-results
Returns the list of the attack results of a single threat have optional parameters for pagination and filtration. Example Command: !picus-specific-threats-results threat_id=666059
Base Command
picus-specific-threats-results
Input
| Argument Name | Description | Required |
|---|---|---|
| cve | CVE code of the threat to be filtered. | Optional |
| md5 | The md5 of the threat. | Optional |
| page | integer <int64> - Default: 1 Requested page number. Default is 1. | Optional |
| sha256 | SHA256 hash of the threat. | Optional |
| size | integer <int64> - Default: 50 Requested data size. Default is 50. | Optional |
| threat_id | integer <int64> PID of the threat. | Required |
Context Output
There is no context output for this command.
picus-peer-list
Returns the peer list with current statuses
Base Command
picus-peer-list
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
picus-attack-all-vectors
Schedules given attack on all possible vectors
Base Command
picus-attack-all-vectors
Input
| Argument Name | Description | Required |
|---|---|---|
| threat_id | Example: threat_id=100682 PID of the threat. | Required |
Context Output
There is no context output for this command.
picus-attack-single
Schedules a single attack on requested vector
Base Command
picus-attack-single
Input
| Argument Name | Description | Required |
|---|---|---|
| threat_id | Example: threat_id=666059 PID of the threat. | Required |
| variant | Example: variant=HTTP. | Required |
| vector1 | Example: trusted=Trusted-Peer-Name Trusted peer name, if type is overall, it is not necessary. | Required |
| vector2 | Example: untrusted=Untrusted-Peer-Name Untrusted peer name, if type is overall, it is not necessary. | Required |
Context Output
There is no context output for this command.
picus-trigger-update
Triggers the update mechanism manually, returns if the update-command is taken successfully
Base Command
picus-trigger-update
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
picus-version
Returns the current version and the update time config
Base Command
picus-version
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
picus-mitigation-list
Returns the list of the mitigations of threats\nhave optional parameters for pagination and filtration, this route may not be used associated with your license. Example Command: !picus-mitigation-list begin_date=2021-01-01 end_date=2021-02-01 threat_id=528370 products=”McAfee IPS” signature_id=0x40208a00
Base Command
picus-mitigation-list
Input
| Argument Name | Description | Required |
|---|---|---|
| begin_date | Threat release date filter start of the date range. | Required |
| end_date | Default: “Today’s date formatted YYYY-mm-dd” Threat release date filter end of the date range if a begin date is given and end date not, default will be used. | Required |
| page | integer <int64> Default: 1 Requested page number. Default is 1. | Optional |
| products | Array of strings - Products info of the mitigation. Possible values are: , . | Required |
| signature_id | ID of the signature. | Required |
| size | integer <int64> - Default: 50 Requested data size. Default is 50. | Optional |
| threat_id | integer <int64> - PID of the threat. | Required |
Context Output
There is no context output for this command.
picus-mitre-matrix
Returns the mitre matrix metadata takes no parameters
Base Command
picus-mitre-matrix
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
picus-sigma-rules-list
Returns the list of the sigma rules of scenario actions have optional parameters for pagination and filtration, this route may not be used associated with your license
Base Command
picus-sigma-rules-list
Input
| Argument Name | Description | Required |
|---|---|---|
| size | Size of Displayed Rule. Default is 100. | Optional |
| page | Page of Displayed Rule. Default is 1. | Optional |
Context Output
There is no context output for this command.
picus-vector-list
Returns the list of the vectors all disabled and enabled ones have optional parameters for pagination
Base Command
picus-vector-list
Input
| Argument Name | Description | Required |
|---|---|---|
| add_user_details | boolean - Add vectors’ assigned user details to the response. Default is True. | Optional |
| page | Default: 1 Requested page number. Default is 1. | Optional |
| size | Default: 50 Requested data size. Default is 50. | Optional |
Context Output
There is no context output for this command.
Configuration parameters
server— PICUS URL (required)apikey— API Key - Refresh Token (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (12)
-
picus-attack-all-vectorsSchedules given attack on all possible vectors
-
picus-attack-result-listReturns the list of the attack results have optional parameters for pagination and filtration. \nExample Command:\n !picus-attack-result-list attack_result=insecure begin_date=2020-01-01 end_date=2020-09-05 vector1=Trusted-Peer1 vector2=Untrusted-Peer1
-
picus-attack-singleSchedules a single attack on requested vector
-
picus-mitigation-listReturns the list of the mitigations of threats\nhave optional parameters for pagination and filtration, this route may not be used associated with your license. Example Command: !picus-mitigation-list begin_date=2021-01-01 end_date=2021-02-01 threat_id=528370 products="McAfee IPS" signature_id=0x40208a00
-
picus-mitre-matrixReturns the mitre matrix metadata takes no parameters
-
picus-peer-listReturns the peer list with current statuses
-
picus-sigma-rules-listReturns the list of the sigma rules of scenario actions have optional parameters for pagination and filtration, this route may not be used associated with your license
-
picus-specific-threats-resultsReturns the list of the attack results of a single threat have optional parameters for pagination and filtration. Example Command: !picus-specific-threats-results threat_id=666059
-
picus-trigger-updateTriggers the update mechanism manually, returns if the update-command is taken successfully
-
picus-vector-compareAttack Result - Makes a comparison of the given vector's results. Example Command: !picus-vector-compare begin_date=2020-01-20 end_date=2021-01-20 trusted=Trusted_Peer1 untrusted=Untrusted_Peer1
-
picus-vector-listReturns the list of the vectors all disabled and enabled ones have optional parameters for pagination
-
picus-versionReturns the current version and the update time config
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import json import os import traceback import requests import urllib3 # disable insecure warnings urllib3.disable_warnings() ''' GLOBAL VARIABLES''' VERIFY_SSL = not demisto.params().get('insecure', False) DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ' if not demisto.params().get('proxy', False): del os.environ['HTTP_PROXY'] del os.environ['HTTPS_PROXY'] del os.environ['http_proxy'] del os.environ['https_proxy'] def test_module() -> 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. :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ try: SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') CREDENTIALS = demisto.params().get('apikey') # AUTH_HEADERS = {'Content-Type': 'application/json'} params = "Bearer " + CREDENTIALS headers = {"X-Refresh-Token": params} endpoint = "/authenticator/v1/access-tokens/generate" url = SERVER + endpoint req = requests.post(url, headers=headers, verify=VERIFY_SSL) status = req.status_code if status != 200: return str(status) except Exception as e: if ('Forbidden' in str(e)): return 'Authorization Error: make sure API Key is correctly set' else: raise e return 'ok' def getAccessToken(): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') ''' GLOBAL VARS ''' CREDENTIALS = demisto.params().get('apikey') params = "Bearer " + CREDENTIALS headers = {"X-Refresh-Token": params} endpoint = "/authenticator/v1/access-tokens/generate" url = SERVER + endpoint req = requests.post(url, headers=headers, verify=VERIFY_SSL) if req.status_code == 200: pass else: return_error(req.content) sys.exit(1) parsed = json.loads(req.content) data = parsed['data'] accessToken = data['access_token'] return accessToken def vectorCompare(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/attack-results/compare-a-vector" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint begin_date = demisto.args().get('begin_date') end_date = demisto.args().get('end_date') trusted = demisto.args().get('trusted') untrusted = demisto.args().get('untrusted') data = {'begin_date': begin_date, 'end_date': end_date, 'trusted': trusted, 'untrusted': untrusted, } req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) parsed = json.loads(req.content) result = parsed['data']['variants'][0] results_insecures = parsed['data']['variants'][0]['insecures'] if 'data' in parsed else '' results_insecure_to_secures = parsed['data']['variants'][0]['insecure_to_secures'] if 'data' in parsed else '' results_secure_to_insecures = parsed['data']['variants'][0]['secure_to_insecures'] if 'data' in parsed else '' results_secures = parsed['data']['variants'][0]['secures'] if 'data' in parsed else '' hr = tableToMarkdown('Insecures', results_insecures, removeNull=True) hr += tableToMarkdown('Insecure to Secures', results_insecure_to_secures, removeNull=True) hr += tableToMarkdown('Secures to Insecure', results_secure_to_insecures, removeNull=True) hr += tableToMarkdown('Secures', results_secures, removeNull=True) return { 'Type': entryTypes['note'], 'Contents': result, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': hr } '''Response: { "data": { "trusted": "string", "untrusted": "string", "variants": [ { "insecure_to_secures": [ { "md5": "string", "name": "string", "since": "string", "threat_id": "string" } ], "insecures": [ { "md5": "string", "name": "string", "since": "string", "threat_id": "string" } ], "secure_to_insecures": [ { "md5": "string", "name": "string", "since": "string", "threat_id": "string" } ], "secures": [ { "md5": "string", "name": "string", "since": "string", "threat_id": "string" } ], "variant_name": "string" } ] }, "success": true } ''' def attackResultList(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/attack-results/list" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint attack_result = demisto.args().get('attack_result') begin_date = demisto.args().get('begin_date') console_output_info = bool(demisto.args().get('console_output_info')) end_date = demisto.args().get('end_date') from_time = demisto.args().get('from_time') page = int(demisto.args().get('page')) size = int(demisto.args().get('size')) threat_parameters = demisto.args().get('threat_parameters') vector1 = demisto.args().get('vector1') vector2 = demisto.args().get('vector2') data = {'attack_result': attack_result, 'begin_date': begin_date, 'console_output_info': console_output_info, 'end_date': end_date, 'from_time': from_time, 'page': page, 'size': size, 'threat_parameters': threat_parameters, 'vectors': [{'trusted': vector1, 'untrusted': vector2 }] } req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data']['results'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Picus-Attack-Result-List', results) } '''Response: { "attack_result": "secure", "begin_date": "2018-10-29", "console_output_info": true, "end_date": "2019-10-29", "from_time": "2017-10-29T04:48:35.919615635Z", "page": 5, "size": 10, "threat_parameters": { "begin_date": "2018-10-29", "categories": [ [ "Malicious Code" ], [ "Attack Scenario", "Defense Evasion", "Indicator Removal from Tools" ] ], "cve": "string", "end_date": "2019-10-29", "kill_chains": [ "Delivery", "Compromise" ], "md5": "stringstringstringstringstringst", "method": "PCI and PII", "severity": "High", "sha256": "string", "threat_id": 100682 }, "vectors": [ { "trusted": "Trusted-Peer-Name", "untrusted": "Untrusted-Peer-Name" } ] } ''' def specificThreatsResults(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/attack-results/threat-specific-latest" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint cve = demisto.args().get('cve') md5 = demisto.args().get('md5') page = int(demisto.args().get('page')) sha256 = demisto.args().get('sha256') size = int(demisto.args().get('size')) threat_id = int(demisto.args().get('threat_id')) data = {'cve': cve, 'md5': md5, 'page': page, 'sha256': sha256, 'size': size, 'threat_id': threat_id, } req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data']['results'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Picus-Specific-Threats-Results', results) } '''Response: { "data": { "page_number": 2, "results": { "CVE": "string", "MD5": "string", "SHA256": "string", "l1_category_name": "string", "pid": "string", "threat_name": "string", "vectors": [ { "id": 0, "name": "string", "variants": [ { "destination_port": 443, "last_time": "2017-10-29T08:38:53.1035948Z", "name": "HTTP", "result": "Secure", "since": "2017-10-29T08:38:53.1035948Z", "source_port": 12255 } ] } ] }, "size": 5, "total_count": 548 }, "success": true } ''' def peerList(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/peers/list" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint req = requests.post(url, headers=headers, verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data']['peers'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('Picus-Peer-List', results) } '''Response: { "data": { "peers": [ { "is_alive": true, "latest_attack": "2020-09-04T13:26:03.524Z", "name": "Windows10-Peer", "registered_ip": "\"\"", "type": "Network" } ], "total_count": 0 }, "success": true } ''' def attackAllVectors(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/schedule/attack/all-possible-vectors" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint threat_id = int(demisto.args().get('threat_id')) data = {'threat_id': threat_id} try: req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) except Exception as e: return_error(e) parsed = json.loads(req.content) results = parsed['data']['vectors'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('PICUS-Attack-All-Vectors', results) } '''Response: { "data": { "vectors": [ { "trusted": "string", "untrusted": "string", "variants": [ { "name": "string", "result": "success" } ] } ] }, "success": true } ''' def attackSingle(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/schedule/attack/single" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint threat_id = int(demisto.args().get('threat_id')) variant = demisto.args().get('variant') vector1 = demisto.args().get('vector1') vector2 = demisto.args().get('vector2') data = {'threat_id': threat_id, 'variant': variant, 'trusted': vector1, 'untrusted': vector2 } req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('PICUS-Attack-Single', results) } '''Response: { "data": { "result": "success" }, "success": true } ''' def triggerUpdate(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/settings/trigger-update" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint req = requests.post(url, headers=headers, verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('PICUS-Trigger-Update', results) } '''Response: { "data": true, "success": true } ''' def version(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/settings/version" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint req = requests.post(url, headers=headers, verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('PICUS-Version', results) } '''Response: { "data": { "last_update_date": "string", "update_time": 0, "version": 0 }, "success": true } ''' def mitigationList(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/threats/mitigations/list" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint products = [] begin_date = demisto.args().get('begin_date') end_date = demisto.args().get('end_date') page = int(demisto.args().get('page')) products = [demisto.args().get('products')] signature_id = demisto.args().get('signature_id') size = int(demisto.args().get('size')) threat_id = int(demisto.args().get('threat_id')) data = {'begin_date': begin_date, 'end_date': end_date, 'page': page, 'products': products, 'signature_id': signature_id, 'size': size, 'threat_id': threat_id } req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data']['mitigations'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('PICUS-Mitigation-List', results) } '''Response: { "begin_date": "2018-10-29", "end_date": "2019-10-29", "page": 5, "products": "Product1", "signature_id": "12345", "size": 10, "threat_id": 123456 } ''' def mitreMatrix(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/threats/mitre-matrix" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint req = requests.get(url, headers=headers, verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data'] if 'data' in parsed else '' return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': tableToMarkdown('PICUS-Mitre-Matrix', results) } '''Response: { "data": [ { "tactic_id": 0, "tactic_name": "string", "techniques": [ { "actions": [ { "action_id": "string", "action_name": "string", "affected_platforms": [ { "architecture": "string", "platform": "string" } ], "description": "string", "is_critical": true } ], "technique_id": "string", "technique_name": "string" } ] } ], "success": true } ''' def sigmaRulesList(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/threats/sigma-rules/list" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint size = int(demisto.args().get('size')) page = int(demisto.args().get('page')) data = { 'Page Size': size, 'Page': page, } header = ['Sigma Rule List Count', 'Size', 'Page'] result_info = {} req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data']['sigma_rules'] if 'data' in parsed else '' result_info['Sigma Rule List Count'] = parsed['data']['total_count'] if 'data' in parsed else '' hr = tableToMarkdown('Sigma Rule List Info', result_info, header, removeNull=True) hr += tableToMarkdown('Sigma Rules', results) return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': hr } '''Response: { "data": { "page_number": 2, "sigma_rules": [ { "actions": [ { "description": "string", "id": 0, "name": "string" } ], "content": "title: Gathering PnP Device List Information via powershell status: experimental...", "id": 0 } ], "size": 5, "total_count": 548 }, "success": true } ''' def vectorList(requestContent): SERVER = demisto.params().get('server')[:-1] if str(demisto.params().get('server')).endswith('/') \ else demisto.params().get('server') endpoint = "/user-api/v1/vectors/list" accessToken = "Bearer " + requestContent headers = {"X-Api-Token": accessToken} url = SERVER + endpoint add_user_details = bool(demisto.args().get('add_user_details')) page = int(demisto.args().get('page')) size = int(demisto.args().get('size')) data = {'add_user_details': add_user_details, 'page': page, 'size': size } req = requests.post(url, headers=headers, data=json.dumps(data), verify=VERIFY_SSL) parsed = json.loads(req.content) results = parsed['data']['vectors'] if 'data' in parsed else '' header = ['name', 'description', 'trusted', 'untrusted', 'is_disabled', 'type'] hr = tableToMarkdown('Picus Vector List', results, header, removeNull=True) return { 'Type': entryTypes['note'], 'Contents': results, 'ContentsFormat': formats['json'], 'ReadableContentsFormat': formats['markdown'], 'HumanReadable': hr } '''Response: { "data": { "page_number": 2, "size": 5, "total_count": 548, "vectors": [ { "description": "string", "heartbeat_results": [ { "is_successful": true, "module": "PTS", "result_time": "2018-08-21T13:00:33.590599407Z", "variant": "HTTP" } ], "is_disabled": true, "name": "Email-Peer-2 - Email-Peer-1", "trusted": "Windows10-Peer", "type": "string", "untrusted": "Network-Peer", "users": [ { "role": "admin", "username": "oliver" } ] } ] }, "success": true } ''' def main() -> None: """main function, parses params and runs command functions :return: :rtype: """ ''' EXECUTION ''' # LOG('command is %s' % (demisto.command(), )) demisto.debug(f'Command being called is {demisto.command()}') try: LOG('Command being called is {command}'.format(command=demisto.command())) if demisto.command() == 'picus-get-access-token': getAccessToken() # Makes a comparison of the given vector's results elif demisto.command() == 'picus-vector-compare': token = getAccessToken() demisto.results(vectorCompare(token)) # Returns the list of the attack results\nhave optional parameters for pagination and filtration elif demisto.command() == 'picus-attack-result-list': token = getAccessToken() demisto.results(attackResultList(token)) # Returns the list of the attack results of a single threat\nhave optional elif demisto.command() == 'picus-specific-threats-results': token = getAccessToken() demisto.results(specificThreatsResults(token)) # Returns the peer list with current statuses elif demisto.command() == 'picus-peer-list': token = getAccessToken() demisto.results(peerList(token)) # Schedules given attack on all possible vectors elif demisto.command() == 'picus-attack-all-vectors': token = getAccessToken() demisto.results(attackAllVectors(token)) # Schedules a single attack on requested vector elif demisto.command() == 'picus-attack-single': token = getAccessToken() demisto.results(attackSingle(token)) # Triggers the update mechanism manually, returns if the update-command is taken successfully elif demisto.command() == 'picus-trigger-update': token = getAccessToken() demisto.results(triggerUpdate(token)) # Returns the current version and the update time config elif demisto.command() == 'picus-version': token = getAccessToken() demisto.results(version(token)) # Returns the list of the mitigations of threats\nhave optional parameters for pagination and filtration, # this route may not be used associated with your license elif demisto.command() == 'picus-mitigation-list': token = getAccessToken() demisto.results(mitigationList(token)) # Returns the mitre matrix metadata\ntakes no parameters elif demisto.command() == 'picus-mitre-matrix': token = getAccessToken() demisto.results(mitreMatrix(token)) # Returns the list of the sigma rules of scenario actions\nhave optional parameters for pagination and filtration, # this route may not be used associated with your license elif demisto.command() == 'picus-sigma-rules-list': token = getAccessToken() demisto.results(sigmaRulesList(token)) # Returns the list of the vectors all disabled and enabled ones\nhave optional parameters for pagination elif demisto.command() == 'picus-vector-list': token = getAccessToken() demisto.results(vectorList(token)) elif demisto.command() == 'test-module': demisto.results(test_module()) # 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{str(e)}') if __name__ in ('__main__', '__builtin__', 'builtins'): main()