From 41dfbc7e879147145e6e69ab491bc67ba95dbc1f Mon Sep 17 00:00:00 2001 From: roysagi <50295826+roysagi@users.noreply.github.com> Date: Mon, 8 Jun 2020 23:41:18 +0300 Subject: [PATCH 001/200] Content additional fix validations (#7445) * Content additional fix validations * updating gmail docker image * Update Packs/Digital_Defense_FrontlineVM/Playbooks/playbook-Digital_Defense_FrontlineVM_-_PAN-OS_block_assets.yml Co-authored-by: Bar Katzir <37335599+bakatzir@users.noreply.github.com> * adding changelogs Co-authored-by: Bar Katzir <37335599+bakatzir@users.noreply.github.com> --- Packs/Accessdata/.pack-ignore | 2 + Packs/ArcSightXML/README.md | 0 .../AzureSentinel/AzureSentinel.yml | 2 +- .../AzureSentinel_description.md | 2 + .../Integrations/AzureSentinel/CHANGELOG.md | 2 +- Packs/AzureSentinel/ReleaseNotes/1_0_1.md | 5 ++ Packs/AzureSentinel/pack_metadata.json | 34 ++++++------- .../.pack-ignore | 11 +++++ Packs/CommonTypes/.pack-ignore | 39 +++++++++++++++ .../IncidentFields/XDR_Description.json | 4 +- .../XDR_Description_CHANGELOG.md | 2 + Packs/CortexXDR/ReleaseNotes/1_0_3.md | 5 ++ Packs/CortexXDR/pack_metadata.json | 2 +- Packs/CrowdStrikeHost/.pack-ignore | 5 ++ Packs/Cylance_Protect/.pack-ignore | 2 + Packs/DeprecatedContent/.pack-ignore | 3 ++ ...ense_FrontlineVM_-_PAN-OS_block_assets.yml | 49 +++++++++++++++---- .../ReleaseNotes/1_0_1.md | 5 ++ .../pack_metadata.json | 30 ++++++------ Packs/EWS/.pack-ignore | 3 ++ Packs/Gmail/Integrations/Gmail/CHANGELOG.md | 2 +- Packs/Gmail/Integrations/Gmail/Gmail.yml | 2 +- Packs/Gmail/ReleaseNotes/1_0_2.md | 5 ++ Packs/Gmail/pack_metadata.json | 2 +- Packs/GoogleVault/.pack-ignore | 3 ++ .../MicrosoftGraphCalendar/pack_metadata.json | 3 +- .../ProofpointServerProtection/CHANGELOG.md | 2 +- .../ProofpointServerProtection.py | 2 +- .../ProofpointServerProtection.yml | 2 +- .../ReleaseNotes/1_0_1.md | 5 ++ .../pack_metadata.json | 32 ++++++------ Packs/Ransomware/.pack-ignore | 2 + .../Integrations/TrendMicroApex/CHANGELOG.md | 4 +- .../TrendMicroApex/TrendMicroApex.yml | 2 +- .../TrendMicroApex_description.md | 4 +- Packs/TrendMicroApex/ReleaseNotes/1_0_1.md | 5 ++ Packs/TrendMicroApex/pack_metadata.json | 32 ++++++------ Packs/VMRay/.pack-ignore | 2 + Packs/Volatility/ReleaseNotes/1_0_1.md | 29 +++++++++++ .../Scripts/script-AnalyzeMemImage.yml | 2 +- .../Volatility/Scripts/script-VolApihooks.yml | 2 +- .../Volatility/Scripts/script-VolConnscan.yml | 2 +- .../Volatility/Scripts/script-VolDlllist.yml | 2 +- .../script-VolGetProcWithMalNetConn.yml | 2 +- .../Scripts/script-VolImageinfo.yml | 2 +- .../Scripts/script-VolLDRModules.yml | 2 +- .../Volatility/Scripts/script-VolMalfind.yml | 2 +- .../Scripts/script-VolNetworkConnections.yml | 2 +- Packs/Volatility/Scripts/script-VolPSList.yml | 2 +- Packs/Volatility/Scripts/script-VolRaw.yml | 2 +- .../Volatility/Scripts/script-VolRunCmds.yml | 2 +- .../Volatility/Scripts/script-Volatility.yml | 2 +- Packs/Volatility/pack_metadata.json | 2 +- 53 files changed, 272 insertions(+), 103 deletions(-) create mode 100644 Packs/ArcSightXML/README.md create mode 100644 Packs/AzureSentinel/ReleaseNotes/1_0_1.md create mode 100644 Packs/CortexXDR/IncidentFields/XDR_Description_CHANGELOG.md create mode 100644 Packs/CortexXDR/ReleaseNotes/1_0_3.md create mode 100644 Packs/Digital_Defense_FrontlineVM/ReleaseNotes/1_0_1.md create mode 100644 Packs/Gmail/ReleaseNotes/1_0_2.md create mode 100644 Packs/ProofpointServerProtection/ReleaseNotes/1_0_1.md create mode 100644 Packs/TrendMicroApex/ReleaseNotes/1_0_1.md create mode 100644 Packs/Volatility/ReleaseNotes/1_0_1.md diff --git a/Packs/Accessdata/.pack-ignore b/Packs/Accessdata/.pack-ignore index e69de29bb2d1..b2e114bca9cc 100644 --- a/Packs/Accessdata/.pack-ignore +++ b/Packs/Accessdata/.pack-ignore @@ -0,0 +1,2 @@ +[file:playbook-Accessdata__Dump_memory_for_malicious_process.yml] +ignore=BA101 diff --git a/Packs/ArcSightXML/README.md b/Packs/ArcSightXML/README.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml b/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml index 7311f4dab485..3eac57926506 100644 --- a/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml +++ b/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml @@ -75,7 +75,7 @@ configuration: required: false type: 8 description: Use the Azure Sentinel integration to get and manage incidents and get related entity information for incidents. -display: Azure Sentinel +display: Azure Sentinel (Beta) name: Azure Sentinel script: commands: diff --git a/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel_description.md b/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel_description.md index ed7d7a287f8a..538687486053 100644 --- a/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel_description.md +++ b/Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel_description.md @@ -29,3 +29,5 @@ Follow these steps for a self-deployed configuration. ## Get the additional instance parameters To get the ***Subscription ID***, ***Workspace Name*** and ***Resource Group*** parameters, navigate in the Azure Portal to ***Azure Sentinel > YOUR-WORKSPACE > Settings*** and click on ***Workspace Settings*** tab. + +Note: This is a beta Integration, which lets you implement and test pre-release software. Since the integration is beta, it might contain bugs. Updates to the integration during the beta phase might include non-backward compatible features. We appreciate your feedback on the quality and usability of the integration to help us identify issues, fix them, and continually improve. diff --git a/Packs/AzureSentinel/Integrations/AzureSentinel/CHANGELOG.md b/Packs/AzureSentinel/Integrations/AzureSentinel/CHANGELOG.md index 8f82f3208ae4..e2391458ab46 100644 --- a/Packs/AzureSentinel/Integrations/AzureSentinel/CHANGELOG.md +++ b/Packs/AzureSentinel/Integrations/AzureSentinel/CHANGELOG.md @@ -1,5 +1,5 @@ ## [Unreleased] - +- ## [20.4.0] - 2020-04-14 - diff --git a/Packs/AzureSentinel/ReleaseNotes/1_0_1.md b/Packs/AzureSentinel/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..29459ad58200 --- /dev/null +++ b/Packs/AzureSentinel/ReleaseNotes/1_0_1.md @@ -0,0 +1,5 @@ + diff --git a/Packs/AzureSentinel/pack_metadata.json b/Packs/AzureSentinel/pack_metadata.json index 1c12129b15bc..489089855431 100644 --- a/Packs/AzureSentinel/pack_metadata.json +++ b/Packs/AzureSentinel/pack_metadata.json @@ -1,18 +1,18 @@ { - "name": "AzureSentinel", - "description": "Azure Sentinel is a cloud-native security information and event manager (SIEM) platform that uses built-in AI to help analyze large volumes of data across an enterprise.", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-03-28T12:58:02Z", - "categories": [ - "Analytics & SIEM" - ], - "tags": [], - "useCases": [], - "keywords": [ - "AzureSentinel" - ] -} + "name": "AzureSentinel", + "description": "Azure Sentinel is a cloud-native security information and event manager (SIEM) platform that uses built-in AI to help analyze large volumes of data across an enterprise.", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-03-28T12:58:02Z", + "categories": [ + "Analytics & SIEM" + ], + "tags": [], + "useCases": [], + "keywords": [ + "AzureSentinel" + ] +} \ No newline at end of file diff --git a/Packs/Carbon_Black_Enterprise_Response/.pack-ignore b/Packs/Carbon_Black_Enterprise_Response/.pack-ignore index e69de29bb2d1..2bc6dc0c23ba 100644 --- a/Packs/Carbon_Black_Enterprise_Response/.pack-ignore +++ b/Packs/Carbon_Black_Enterprise_Response/.pack-ignore @@ -0,0 +1,11 @@ +[file:playbook-Block_Endpoint_-_Carbon_Black_Response.yml] +ignore=BA101 + +[file:playbook-Get_File_Sample_By_Hash_-_Carbon_Black_Enterprise_Response.yml] +ignore=BA101 + +[file:playbook-Get_File_Sample_From_Path_-_Carbon_Black_Enterprise_Response.yml] +ignore=BA101 + +[file:playbook-Block_File_-_Carbon_Black_Response.yml] +ignore=BA101 diff --git a/Packs/CommonTypes/.pack-ignore b/Packs/CommonTypes/.pack-ignore index fcf49d67c92e..19af0b9b3617 100644 --- a/Packs/CommonTypes/.pack-ignore +++ b/Packs/CommonTypes/.pack-ignore @@ -90,3 +90,42 @@ ignore=IF107 [file:incidentfield-name.json] ignore=IF106 + +[file:reputation-cve.json] +ignore=RP102 + +[file:reputation-domain.json] +ignore=RP102 + +[file:reputation-host.json] +ignore=RP102 + +[file:reputation-account.json] +ignore=RP102 + +[file:reputation-email.json] +ignore=RP102 + +[file:reputation-url.json] +ignore=RP102 + +[file:reputation-file.json] +ignore=RP102 + +[file:reputation-hashRepSHA256.json] +ignore=RP102 + +[file:reputation-ip.json] +ignore=RP102 + +[file:reputation-ssdeepRep.json] +ignore=RP102 + +[file:reputation-hashRepSHA1.json] +ignore=RP102 + +[file:reputation-hashRepMD5.json] +ignore=RP102 + +[file:reputation-registryKey.json] +ignore=RP102 diff --git a/Packs/CortexXDR/IncidentFields/XDR_Description.json b/Packs/CortexXDR/IncidentFields/XDR_Description.json index b1be6324c710..ab31d409f99d 100644 --- a/Packs/CortexXDR/IncidentFields/XDR_Description.json +++ b/Packs/CortexXDR/IncidentFields/XDR_Description.json @@ -9,7 +9,7 @@ "cliName": "xdrdescription", "closeForm": false, "columns": null, - "content": false, + "content": true, "defaultRows": null, "description": "", "editForm": true, @@ -37,4 +37,4 @@ "validationRegex": "", "version": -1, "fromVersion": "5.0.0" -} \ No newline at end of file +} diff --git a/Packs/CortexXDR/IncidentFields/XDR_Description_CHANGELOG.md b/Packs/CortexXDR/IncidentFields/XDR_Description_CHANGELOG.md new file mode 100644 index 000000000000..63439c17f377 --- /dev/null +++ b/Packs/CortexXDR/IncidentFields/XDR_Description_CHANGELOG.md @@ -0,0 +1,2 @@ +## [Unreleased] +- diff --git a/Packs/CortexXDR/ReleaseNotes/1_0_3.md b/Packs/CortexXDR/ReleaseNotes/1_0_3.md new file mode 100644 index 000000000000..0ea78f3fd8fa --- /dev/null +++ b/Packs/CortexXDR/ReleaseNotes/1_0_3.md @@ -0,0 +1,5 @@ + diff --git a/Packs/CortexXDR/pack_metadata.json b/Packs/CortexXDR/pack_metadata.json index a884bd9dcc68..79ee2cfe5ec9 100644 --- a/Packs/CortexXDR/pack_metadata.json +++ b/Packs/CortexXDR/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Palo Alto Networks Cortex XDR - Investigation and Response", "description": "Cortex XDR is the world's first detection and response app that natively integrates network, endpoint and cloud data to stop sophisticated attacks.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "1.0.3", "author": "Cortex XSOAR ", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CrowdStrikeHost/.pack-ignore b/Packs/CrowdStrikeHost/.pack-ignore index e69de29bb2d1..f6a6e9d9282b 100644 --- a/Packs/CrowdStrikeHost/.pack-ignore +++ b/Packs/CrowdStrikeHost/.pack-ignore @@ -0,0 +1,5 @@ +[file:playbook-Search_Endpoints_By_Hash_-_CrowdStrike.yml] +ignore=BA101 + +[file:playbook-CrowdStrike_Endpoint_Enrichment.yml] +ignore=BA101 diff --git a/Packs/Cylance_Protect/.pack-ignore b/Packs/Cylance_Protect/.pack-ignore index e69de29bb2d1..2ed8f7a8013d 100644 --- a/Packs/Cylance_Protect/.pack-ignore +++ b/Packs/Cylance_Protect/.pack-ignore @@ -0,0 +1,2 @@ +[file:playbook-Get_File_Sample_By_Hash_-_Cylance_Protect.yml] +ignore=BA101 diff --git a/Packs/DeprecatedContent/.pack-ignore b/Packs/DeprecatedContent/.pack-ignore index bae33f5d39e7..5a6e669ea291 100644 --- a/Packs/DeprecatedContent/.pack-ignore +++ b/Packs/DeprecatedContent/.pack-ignore @@ -150,3 +150,6 @@ ignore=BA101 [file:playbook-PhishingAutomated.yml] ignore=BA101 + +[file:Access_Investigation_-_Generic.yml] +ignore=BA101 diff --git a/Packs/Digital_Defense_FrontlineVM/Playbooks/playbook-Digital_Defense_FrontlineVM_-_PAN-OS_block_assets.yml b/Packs/Digital_Defense_FrontlineVM/Playbooks/playbook-Digital_Defense_FrontlineVM_-_PAN-OS_block_assets.yml index 73fb1619900e..79259476c209 100644 --- a/Packs/Digital_Defense_FrontlineVM/Playbooks/playbook-Digital_Defense_FrontlineVM_-_PAN-OS_block_assets.yml +++ b/Packs/Digital_Defense_FrontlineVM/Playbooks/playbook-Digital_Defense_FrontlineVM_-_PAN-OS_block_assets.yml @@ -247,7 +247,9 @@ tasks: id: 963529eb-2f34-4072-801f-9eed161669d1 version: -1 name: PAN-OS - Block IP and URL - External Dynamic List - description: '' + description: |- + This playbook blocks IP addresses and URLs using PAN-OS External Dynamic Lists. + It checks if the EDL configuration is in place with the 'PAN-OS EDL Setup' sub-playbook (otherwise the list will be configured), and adds the input IPs and URLs to the relevant lists. playbookName: PAN-OS - Block IP and URL - External Dynamic List type: playbook iscommand: false @@ -276,7 +278,7 @@ tasks: view: |- { "position": { - "x": 50, + "x": -130, "y": 1790 } } @@ -407,8 +409,10 @@ tasks: iscommand: false brand: '' nexttasks: - 'Yes': - - '11' + "No": + - "20" + "Yes": + - "11" separatecontext: false view: |- { @@ -437,8 +441,35 @@ tasks: retriesinterval: 360 completeafterreplies: 1 replyOptions: - - 'Yes' - - 'No' + - "Yes" + - "No" + skipunavailable: false + quietmode: 0 + "20": + id: "20" + taskid: c7f0e8e6-a289-4533-8027-f11b67c15bf7 + type: title + task: + description: Playbook is done + id: c7f0e8e6-a289-4533-8027-f11b67c15bf7 + version: -1 + name: done + type: title + iscommand: false + brand: "" + separatecontext: false + view: |- + { + "position": { + "x": 290, + "y": 1805 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 view: |- { "linkLabelsPosition": { @@ -447,8 +478,8 @@ view: |- "paper": { "dimensions": { "height": 1835, - "width": 810, - "x": 50, + "width": 990, + "x": -130, "y": 50 } } @@ -456,4 +487,4 @@ view: |- inputs: [] outputs: [] tests: - - No test - manual task \ No newline at end of file + - No test - manual task diff --git a/Packs/Digital_Defense_FrontlineVM/ReleaseNotes/1_0_1.md b/Packs/Digital_Defense_FrontlineVM/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..cf1d06f34823 --- /dev/null +++ b/Packs/Digital_Defense_FrontlineVM/ReleaseNotes/1_0_1.md @@ -0,0 +1,5 @@ + diff --git a/Packs/Digital_Defense_FrontlineVM/pack_metadata.json b/Packs/Digital_Defense_FrontlineVM/pack_metadata.json index fe6cf1c6d92d..e8ad933441fd 100644 --- a/Packs/Digital_Defense_FrontlineVM/pack_metadata.json +++ b/Packs/Digital_Defense_FrontlineVM/pack_metadata.json @@ -1,16 +1,16 @@ { - "name": "Digital Defense Frontline VM", - "description": "Use the Digital Defense Frontline VM to identify and evaluate the security and business risks of network devices and applications deployed as premise, cloud, or hybrid network-based implementations.", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-04-14T00:00:00Z", - "categories": [ - "Vulnerability Management" - ], - "tags": [], - "useCases": [], - "keywords": [] -} + "name": "Digital Defense Frontline VM", + "description": "Use the Digital Defense Frontline VM to identify and evaluate the security and business risks of network devices and applications deployed as premise, cloud, or hybrid network-based implementations.", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-04-14T00:00:00Z", + "categories": [ + "Vulnerability Management" + ], + "tags": [], + "useCases": [], + "keywords": [] +} \ No newline at end of file diff --git a/Packs/EWS/.pack-ignore b/Packs/EWS/.pack-ignore index fd509604faf5..1e14a456dbb0 100644 --- a/Packs/EWS/.pack-ignore +++ b/Packs/EWS/.pack-ignore @@ -1,2 +1,5 @@ [file:playbook-Search_And_Delete_Emails_-_EWS.yml] ignore=BA101 + +[file:playbook-Process_Email_-_EWS.yml] +ignore=BA101 diff --git a/Packs/Gmail/Integrations/Gmail/CHANGELOG.md b/Packs/Gmail/Integrations/Gmail/CHANGELOG.md index d800fd22dc13..51c8ff6ad296 100644 --- a/Packs/Gmail/Integrations/Gmail/CHANGELOG.md +++ b/Packs/Gmail/Integrations/Gmail/CHANGELOG.md @@ -1,5 +1,5 @@ ## [Unreleased] - +- ## [20.5.0] - 2020-05-12 - diff --git a/Packs/Gmail/Integrations/Gmail/Gmail.yml b/Packs/Gmail/Integrations/Gmail/Gmail.yml index cafbaa0047f7..263fada326e7 100644 --- a/Packs/Gmail/Integrations/Gmail/Gmail.yml +++ b/Packs/Gmail/Integrations/Gmail/Gmail.yml @@ -1836,7 +1836,7 @@ script: - contextPath: Gmail.Role.Privilege.Name description: The name of the privilege. type: String - dockerimage: demisto/google-api:1.0 + dockerimage: demisto/google-api:1.0.0.8936 isfetch: true longRunning: false longRunningPort: false diff --git a/Packs/Gmail/ReleaseNotes/1_0_2.md b/Packs/Gmail/ReleaseNotes/1_0_2.md new file mode 100644 index 000000000000..739bc409fc6a --- /dev/null +++ b/Packs/Gmail/ReleaseNotes/1_0_2.md @@ -0,0 +1,5 @@ + diff --git a/Packs/Gmail/pack_metadata.json b/Packs/Gmail/pack_metadata.json index f8efad763c8c..47e1cd0ca07f 100644 --- a/Packs/Gmail/pack_metadata.json +++ b/Packs/Gmail/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Gmail", "description": "Gmail API and user management (This integration replaces the Gmail functionality in the GoogleApps API and G Suite integration).", "support": "xsoar", - "currentVersion": "1.0.1", + "currentVersion": "1.0.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GoogleVault/.pack-ignore b/Packs/GoogleVault/.pack-ignore index 742af0105fde..c918af15fd9d 100644 --- a/Packs/GoogleVault/.pack-ignore +++ b/Packs/GoogleVault/.pack-ignore @@ -6,3 +6,6 @@ ignore=BA101 [file:playbook-GVault_-_Search_Mail.yml] ignore=BA101 + +[file:playbook-Display_Results_-_GVault.yml] +ignore=BA101 diff --git a/Packs/MicrosoftGraphCalendar/pack_metadata.json b/Packs/MicrosoftGraphCalendar/pack_metadata.json index 8a106122cebf..82c8072967e2 100644 --- a/Packs/MicrosoftGraphCalendar/pack_metadata.json +++ b/Packs/MicrosoftGraphCalendar/pack_metadata.json @@ -2,6 +2,7 @@ "name": "Microsoft Graph Calendar", "description": "Microsoft Graph Calendar enables you to create and manage different calendars and events\n according to your requirements.", "currentVersion": "1.0.0", + "support": "xsoar", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -10,4 +11,4 @@ "tags": [], "useCases": [], "keywords": [] -} \ No newline at end of file +} diff --git a/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/CHANGELOG.md b/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/CHANGELOG.md index 15deda9fef65..57e65cb0be28 100644 --- a/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/CHANGELOG.md +++ b/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/CHANGELOG.md @@ -1,5 +1,5 @@ ## [Unreleased] - +- ## [20.5.2] - 2020-05-26 - diff --git a/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.py b/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.py index 562fa3cb9497..4f3a71f8b832 100644 --- a/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.py +++ b/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.py @@ -614,7 +614,7 @@ def get_senders_list(): elif demisto.command() == 'proofpoint-remove-from-safe-senders-list': remove_from_safe_senders_list_command() -except Exception, e: +except Exception as e: LOG(e.message) LOG.print_log() raise diff --git a/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.yml b/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.yml index 580e352c2ef1..1351e34be99b 100644 --- a/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.yml +++ b/Packs/ProofpointServerProtection/Integrations/ProofpointServerProtection/ProofpointServerProtection.yml @@ -2,7 +2,7 @@ commonfields: id: Proofpoint Server Protection version: -1 name: Proofpoint Server Protection -display: Proofpoint Protection Server +display: Proofpoint Protection Server (Beta) category: Email Gateway description: Proofpoint email security appliance. configuration: diff --git a/Packs/ProofpointServerProtection/ReleaseNotes/1_0_1.md b/Packs/ProofpointServerProtection/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..73aeaf251631 --- /dev/null +++ b/Packs/ProofpointServerProtection/ReleaseNotes/1_0_1.md @@ -0,0 +1,5 @@ + diff --git a/Packs/ProofpointServerProtection/pack_metadata.json b/Packs/ProofpointServerProtection/pack_metadata.json index 33ea685a7dea..727a38377f31 100644 --- a/Packs/ProofpointServerProtection/pack_metadata.json +++ b/Packs/ProofpointServerProtection/pack_metadata.json @@ -1,18 +1,18 @@ { - "name": "Proofpoint Protection Server", - "description": "Proofpoint email security appliance.", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-04-14T00:00:00Z", - "categories": [ - "Email Gateway" - ], - "tags": [ - "Proofpoint Protection Server" - ], - "useCases": [], - "keywords": [] + "name": "Proofpoint Protection Server", + "description": "Proofpoint email security appliance.", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-04-14T00:00:00Z", + "categories": [ + "Email Gateway" + ], + "tags": [ + "Proofpoint Protection Server" + ], + "useCases": [], + "keywords": [] } \ No newline at end of file diff --git a/Packs/Ransomware/.pack-ignore b/Packs/Ransomware/.pack-ignore index e69de29bb2d1..2cb1657ed070 100644 --- a/Packs/Ransomware/.pack-ignore +++ b/Packs/Ransomware/.pack-ignore @@ -0,0 +1,2 @@ +[file:playbook-ransomware.yml] +ignore=BA101 diff --git a/Packs/TrendMicroApex/Integrations/TrendMicroApex/CHANGELOG.md b/Packs/TrendMicroApex/Integrations/TrendMicroApex/CHANGELOG.md index 2977c3a6a293..48fb31d582ae 100644 --- a/Packs/TrendMicroApex/Integrations/TrendMicroApex/CHANGELOG.md +++ b/Packs/TrendMicroApex/Integrations/TrendMicroApex/CHANGELOG.md @@ -1,9 +1,9 @@ ## [Unreleased] - +- ## [20.5.0] - 2020-05-12 - ## [20.3.3] - 2020-03-18 #### New Integration -Trend Micro Apex central automation to manage agents and User-Defined Suspicious Objects \ No newline at end of file +Trend Micro Apex central automation to manage agents and User-Defined Suspicious Objects diff --git a/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex.yml b/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex.yml index 24b2e5057480..736c9c99838c 100644 --- a/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex.yml +++ b/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex.yml @@ -25,7 +25,7 @@ configuration: type: 8 description: Trend Micro Apex central automation to manage agents and User-Defined Suspicious Objects -display: Trend Micro Apex +display: Trend Micro Apex (Beta) name: Trend Micro Apex script: commands: diff --git a/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex_description.md b/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex_description.md index ae4069b7b8d4..c145fdcf2bfc 100644 --- a/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex_description.md +++ b/Packs/TrendMicroApex/Integrations/TrendMicroApex/TrendMicroApex_description.md @@ -1 +1,3 @@ -It is required to add an application in order to use the integration, follow the instructions [here](https://docs.trendmicro.com/en-us/enterprise/trend-micro-apex-central-2019-automation-api-guide/automation-api-guide/adding-an-applicatio.aspx) to do so. \ No newline at end of file +It is required to add an application in order to use the integration, follow the instructions [here](https://docs.trendmicro.com/en-us/enterprise/trend-micro-apex-central-2019-automation-api-guide/automation-api-guide/adding-an-applicatio.aspx) to do so. + +Note: This is a beta Integration, which lets you implement and test pre-release software. Since the integration is beta, it might contain bugs. Updates to the integration during the beta phase might include non-backward compatible features. We appreciate your feedback on the quality and usability of the integration to help us identify issues, fix them, and continually improve. diff --git a/Packs/TrendMicroApex/ReleaseNotes/1_0_1.md b/Packs/TrendMicroApex/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..7edc9e508e7a --- /dev/null +++ b/Packs/TrendMicroApex/ReleaseNotes/1_0_1.md @@ -0,0 +1,5 @@ + diff --git a/Packs/TrendMicroApex/pack_metadata.json b/Packs/TrendMicroApex/pack_metadata.json index 3f7f43e45a52..c5480c5299f4 100644 --- a/Packs/TrendMicroApex/pack_metadata.json +++ b/Packs/TrendMicroApex/pack_metadata.json @@ -1,18 +1,18 @@ { - "name": "Trend Micro Apex", - "description": "Trend Micro Apex central automation to manage agents and User-Defined Suspicious Objects", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-04-14T00:00:00Z", - "categories": [ - "Endpoint" - ], - "tags": [ - "Trend Micro Apex" - ], - "useCases": [], - "keywords": [] + "name": "Trend Micro Apex", + "description": "Trend Micro Apex central automation to manage agents and User-Defined Suspicious Objects", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-04-14T00:00:00Z", + "categories": [ + "Endpoint" + ], + "tags": [ + "Trend Micro Apex" + ], + "useCases": [], + "keywords": [] } \ No newline at end of file diff --git a/Packs/VMRay/.pack-ignore b/Packs/VMRay/.pack-ignore index e69de29bb2d1..5a2f0e3221e8 100644 --- a/Packs/VMRay/.pack-ignore +++ b/Packs/VMRay/.pack-ignore @@ -0,0 +1,2 @@ +[file:playbook-VMRay-Detonate-File.yml] +ignore=BA101 diff --git a/Packs/Volatility/ReleaseNotes/1_0_1.md b/Packs/Volatility/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..234d06fef140 --- /dev/null +++ b/Packs/Volatility/ReleaseNotes/1_0_1.md @@ -0,0 +1,29 @@ + diff --git a/Packs/Volatility/Scripts/script-AnalyzeMemImage.yml b/Packs/Volatility/Scripts/script-AnalyzeMemImage.yml index f82b56dce449..7e7a17f019b0 100644 --- a/Packs/Volatility/Scripts/script-AnalyzeMemImage.yml +++ b/Packs/Volatility/Scripts/script-AnalyzeMemImage.yml @@ -1,6 +1,6 @@ commonfields: id: AnalyzeMemImage - version: 1 + version: -1 name: AnalyzeMemImage script: |- var imginfo = executeCommand('Vol', {file:args.memdump, system: args.system, cmd:'imageinfo'}); diff --git a/Packs/Volatility/Scripts/script-VolApihooks.yml b/Packs/Volatility/Scripts/script-VolApihooks.yml index 4252b28984fa..0fc8c0a933c4 100644 --- a/Packs/Volatility/Scripts/script-VolApihooks.yml +++ b/Packs/Volatility/Scripts/script-VolApihooks.yml @@ -1,6 +1,6 @@ commonfields: id: VolApihooks - version: 1 + version: -1 name: VolApihooks script: |- var cmdline = 'apihooks -p ' + args.pid; diff --git a/Packs/Volatility/Scripts/script-VolConnscan.yml b/Packs/Volatility/Scripts/script-VolConnscan.yml index 056f48693195..d394ae80a9e8 100644 --- a/Packs/Volatility/Scripts/script-VolConnscan.yml +++ b/Packs/Volatility/Scripts/script-VolConnscan.yml @@ -1,6 +1,6 @@ commonfields: id: VolConnscan - version: 1 + version: -1 name: VolConnscan script: |- var cmdline = 'connscan'; diff --git a/Packs/Volatility/Scripts/script-VolDlllist.yml b/Packs/Volatility/Scripts/script-VolDlllist.yml index 20994fa20e42..ced894b2ee72 100644 --- a/Packs/Volatility/Scripts/script-VolDlllist.yml +++ b/Packs/Volatility/Scripts/script-VolDlllist.yml @@ -1,6 +1,6 @@ commonfields: id: VolDlllist - version: 1 + version: -1 name: VolDlllist script: |- var cmdline = 'dlllist -p ' + args.pid; diff --git a/Packs/Volatility/Scripts/script-VolGetProcWithMalNetConn.yml b/Packs/Volatility/Scripts/script-VolGetProcWithMalNetConn.yml index 963a4d9d5fe4..9202b9753b18 100644 --- a/Packs/Volatility/Scripts/script-VolGetProcWithMalNetConn.yml +++ b/Packs/Volatility/Scripts/script-VolGetProcWithMalNetConn.yml @@ -1,6 +1,6 @@ commonfields: id: VolGetProcWithMalNetConn - version: 1 + version: -1 name: VolGetProcWithMalNetConn script: |- // get all the network connections diff --git a/Packs/Volatility/Scripts/script-VolImageinfo.yml b/Packs/Volatility/Scripts/script-VolImageinfo.yml index 57576ee5798a..918be4fb81c9 100644 --- a/Packs/Volatility/Scripts/script-VolImageinfo.yml +++ b/Packs/Volatility/Scripts/script-VolImageinfo.yml @@ -1,6 +1,6 @@ commonfields: id: VolImageinfo - version: 1 + version: -1 name: VolImageinfo script: |- var cmdline = 'imageinfo'; diff --git a/Packs/Volatility/Scripts/script-VolLDRModules.yml b/Packs/Volatility/Scripts/script-VolLDRModules.yml index e777e7b51815..247921153574 100644 --- a/Packs/Volatility/Scripts/script-VolLDRModules.yml +++ b/Packs/Volatility/Scripts/script-VolLDRModules.yml @@ -1,6 +1,6 @@ commonfields: id: VolLDRModules - version: 1 + version: -1 name: VolLDRModules script: |- var cmdline = 'ldrmodules'; diff --git a/Packs/Volatility/Scripts/script-VolMalfind.yml b/Packs/Volatility/Scripts/script-VolMalfind.yml index 41acc816f112..5c1d1767a075 100644 --- a/Packs/Volatility/Scripts/script-VolMalfind.yml +++ b/Packs/Volatility/Scripts/script-VolMalfind.yml @@ -1,6 +1,6 @@ commonfields: id: VolMalfind - version: 1 + version: -1 name: VolMalfind script: |- var cmdline = 'malfind -p ' + args.pid; diff --git a/Packs/Volatility/Scripts/script-VolNetworkConnections.yml b/Packs/Volatility/Scripts/script-VolNetworkConnections.yml index 54d24c96c77a..28f5bb98087b 100644 --- a/Packs/Volatility/Scripts/script-VolNetworkConnections.yml +++ b/Packs/Volatility/Scripts/script-VolNetworkConnections.yml @@ -1,6 +1,6 @@ commonfields: id: VolNetworkConnections - version: 1 + version: -1 name: VolNetworkConnections script: |- var cmds = []; diff --git a/Packs/Volatility/Scripts/script-VolPSList.yml b/Packs/Volatility/Scripts/script-VolPSList.yml index b344e6d76736..eb666257bfc6 100644 --- a/Packs/Volatility/Scripts/script-VolPSList.yml +++ b/Packs/Volatility/Scripts/script-VolPSList.yml @@ -1,6 +1,6 @@ commonfields: id: VolPSList - version: 1 + version: -1 name: VolPSList script: |- var cmdline = 'pslist'; diff --git a/Packs/Volatility/Scripts/script-VolRaw.yml b/Packs/Volatility/Scripts/script-VolRaw.yml index 23457875565a..46a0d8617159 100644 --- a/Packs/Volatility/Scripts/script-VolRaw.yml +++ b/Packs/Volatility/Scripts/script-VolRaw.yml @@ -1,6 +1,6 @@ commonfields: id: VolRaw - version: 1 + version: -1 name: VolRaw script: packOutput('vol.py -f ' + args.file + ' ' + args.cmd); type: javascript diff --git a/Packs/Volatility/Scripts/script-VolRunCmds.yml b/Packs/Volatility/Scripts/script-VolRunCmds.yml index bf98213ae56f..10440c9b2668 100644 --- a/Packs/Volatility/Scripts/script-VolRunCmds.yml +++ b/Packs/Volatility/Scripts/script-VolRunCmds.yml @@ -1,6 +1,6 @@ commonfields: id: VolRunCmds - version: 1 + version: -1 name: VolRunCmds script: |- var cmds = args.cmds.split(','); diff --git a/Packs/Volatility/Scripts/script-Volatility.yml b/Packs/Volatility/Scripts/script-Volatility.yml index 90e048fb56bd..423dd586144a 100644 --- a/Packs/Volatility/Scripts/script-Volatility.yml +++ b/Packs/Volatility/Scripts/script-Volatility.yml @@ -1,6 +1,6 @@ commonfields: id: Volatility - version: 1 + version: -1 name: Volatility script: |- var cmdline = args.cmd; diff --git a/Packs/Volatility/pack_metadata.json b/Packs/Volatility/pack_metadata.json index 082f24282726..b89b0168f0ad 100644 --- a/Packs/Volatility/pack_metadata.json +++ b/Packs/Volatility/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Volatility", "description": "Volatility pack.", "support": "xsoar", - "currentVersion": "1.0.0", + "currentVersion": "1.0.1", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From cb1cf92cd1eeb2cbaf9ccbd27939d86df2ad2cf1 Mon Sep 17 00:00:00 2001 From: Bar Hochman <11165655+jochman@users.noreply.github.com> Date: Tue, 9 Jun 2020 09:53:20 +0300 Subject: [PATCH 002/200] fix lintings (#7454) --- Templates/Integrations/CaseManagement/CaseManagement_test.py | 2 +- Templates/Integrations/Database/Database.py | 2 +- Templates/Integrations/Database/Database.yml | 2 ++ Templates/Integrations/Database/Database_CHANGELOG.md | 2 ++ Tests/Marketplace/upload_packs.py | 3 +-- 5 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 Templates/Integrations/Database/Database_CHANGELOG.md diff --git a/Templates/Integrations/CaseManagement/CaseManagement_test.py b/Templates/Integrations/CaseManagement/CaseManagement_test.py index 93727fb1f65f..1bbb5456cd40 100644 --- a/Templates/Integrations/CaseManagement/CaseManagement_test.py +++ b/Templates/Integrations/CaseManagement/CaseManagement_test.py @@ -109,7 +109,7 @@ class TestInputs: ({}, 'Could not find', {}) ] INCIDENT = [{ - 'name': f'Case Management Integration - ticket number: 111', + 'name': 'Case Management Integration - ticket number: 111', 'rawJSON': json.dumps(TICKET_MOCK) }] FETCH_INCIDENTS_INPUT = [ diff --git a/Templates/Integrations/Database/Database.py b/Templates/Integrations/Database/Database.py index ad1d116b252c..6ef1d1ac4c28 100644 --- a/Templates/Integrations/Database/Database.py +++ b/Templates/Integrations/Database/Database.py @@ -55,7 +55,7 @@ def fetch_incidents_command(client: Client, last_run_dict: Optional[dict], first last_fetch, _ = parse_date_range(first_fetch_time, date_format=date_format, utc=True) else: last_fetch = last_run_dict.get('last_run') - query = f"SELECT " + query = "SELECT " for column in argToList(columns): query += f"{column}, " query = query.rstrip(',') diff --git a/Templates/Integrations/Database/Database.yml b/Templates/Integrations/Database/Database.yml index 5b1ecd7cc572..e66fdc1a2815 100644 --- a/Templates/Integrations/Database/Database.yml +++ b/Templates/Integrations/Database/Database.yml @@ -83,3 +83,5 @@ script: script: '-' subtype: python3 type: python +tests: +- No tests diff --git a/Templates/Integrations/Database/Database_CHANGELOG.md b/Templates/Integrations/Database/Database_CHANGELOG.md new file mode 100644 index 000000000000..4117bdc5e161 --- /dev/null +++ b/Templates/Integrations/Database/Database_CHANGELOG.md @@ -0,0 +1,2 @@ +## [Unreleased] +- \ No newline at end of file diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index d32fd3e2b595..8ad5ec37f036 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -315,8 +315,7 @@ def upload_id_set(storage_bucket, id_set_local_path=None): with open(id_set_local_path, mode='r') as f: blob.upload_from_file(f) - - print_color(f"Finished uploading id_set.json to storage.", LOG_COLORS.GREEN) + print_color("Finished uploading id_set.json to storage.", LOG_COLORS.GREEN) def get_private_packs(private_index_path): From 7301211cedaf67b386b0a05cc0577284197d1e6d Mon Sep 17 00:00:00 2001 From: hod <41257953+hod-alpert@users.noreply.github.com> Date: Tue, 9 Jun 2020 09:55:08 +0300 Subject: [PATCH 003/200] Improved empty response handling (#7296) Co-authored-by: halpert --- .../Integrations/FireEyeETP/CHANGELOG.md | 2 +- .../Integrations/FireEyeETP/FireEyeETP.py | 100 +++++++----------- .../FireEyeETP/FireEyeETP_test.py | 14 +++ Packs/FireEyeETP/ReleaseNotes/1_0_1.md | 4 + Packs/FireEyeETP/pack_metadata.json | 30 +++--- 5 files changed, 75 insertions(+), 75 deletions(-) create mode 100644 Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP_test.py create mode 100644 Packs/FireEyeETP/ReleaseNotes/1_0_1.md diff --git a/Packs/FireEyeETP/Integrations/FireEyeETP/CHANGELOG.md b/Packs/FireEyeETP/Integrations/FireEyeETP/CHANGELOG.md index 5330625b0527..7f76b8a2f9f4 100644 --- a/Packs/FireEyeETP/Integrations/FireEyeETP/CHANGELOG.md +++ b/Packs/FireEyeETP/Integrations/FireEyeETP/CHANGELOG.md @@ -1,5 +1,5 @@ ## [Unreleased] - +Improved empty response handling. ## [20.5.0] - 2020-05-12 Fixed an issue where the ***fireeye-etp-search-messages*** command failed. diff --git a/Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP.py b/Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP.py index cff229457541..a8547291af2c 100644 --- a/Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP.py +++ b/Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP.py @@ -2,7 +2,6 @@ from CommonServerPython import * from CommonServerUserPython import * - ''' IMPORTS ''' @@ -13,10 +12,10 @@ import re import copy import json + # disable insecure warnings requests.packages.urllib3.disable_warnings() - ''' GLOBAL VARS ''' @@ -29,7 +28,6 @@ USE_SSL = not demisto.params().get('unsecure') MESSAGE_STATUS = demisto.params().get('message_status') - ''' SEARCH ATTRIBUTES VALID VALUES ''' @@ -41,14 +39,12 @@ "dropped oob", "dropped (oob retroactive)", "permanent failure", "processing", "quarantined", "rejected", "temporary failure"] - ''' BASIC FUNCTIONS ''' def set_proxies(): - if not demisto.params().get('proxy', False): del os.environ['HTTP_PROXY'] del os.environ['HTTPS_PROXY'] @@ -57,14 +53,12 @@ def set_proxies(): def listify(comma_separated_list): - if isinstance(comma_separated_list, list): return comma_separated_list return comma_separated_list.split(',') def http_request(method, url, body=None, headers={}, url_params=None): - ''' returns the http response ''' @@ -96,7 +90,6 @@ def http_request(method, url, body=None, headers={}, url_params=None): def return_error_entry(message): - entry = { 'Type': entryTypes['error'], 'Contents': str(message), @@ -106,7 +99,6 @@ def return_error_entry(message): def to_search_attribute_object(value, filter=None, is_list=False, valid_values=None): - values = listify(value) if is_list else value if valid_values: for val in values: @@ -127,7 +119,6 @@ def format_search_attributes(from_email=None, from_email_not_in=None, recipients recipients_not_in=None, subject=None, from_accepted_date_time=None, to_accepted_date_time=None, rejection_reason=None, sender_ip=None, status=None, status_not_in=None, last_modified_date_time=None, domains=None): - search_attributes = {} # type: Dict # handle from_email attribute @@ -150,9 +141,11 @@ def format_search_attributes(from_email=None, from_email_not_in=None, recipients if status and status_not_in: raise ValueError('Only one of the followings can be specified: status, status_not_in') if status: - search_attributes['status'] = to_search_attribute_object(status, filter='in', is_list=True, valid_values=STATUS_VALUES) + search_attributes['status'] = to_search_attribute_object(status, filter='in', is_list=True, + valid_values=STATUS_VALUES) elif status_not_in: - search_attributes['status'] = to_search_attribute_object(status, filter='in', is_list=True, valid_values=STATUS_VALUES) + search_attributes['status'] = to_search_attribute_object(status, filter='in', is_list=True, + valid_values=STATUS_VALUES) if subject: search_attributes['subject'] = to_search_attribute_object(subject, filter='in', is_list=True) @@ -181,7 +174,6 @@ def format_search_attributes(from_email=None, from_email_not_in=None, recipients def readable_message_data(message): - return { 'Message ID': message['id'], 'Accepted Time': message['acceptedDateTime'], @@ -193,7 +185,6 @@ def readable_message_data(message): def message_context_data(message): - context_data = copy.deepcopy(message) # remove 'attributes' level @@ -218,7 +209,6 @@ def message_context_data(message): def search_messages_request(attributes={}, has_attachments=None, max_message_size=None): - url = '{}/messages/trace'.format(BASE_PATH) body = { 'attributes': attributes, @@ -240,7 +230,6 @@ def search_messages_request(attributes={}, has_attachments=None, max_message_siz def search_messages_command(): - args = demisto.args() if 'size' in args.keys(): # parse to int @@ -301,7 +290,6 @@ def search_messages_command(): def get_message_request(message_id): - url = '{}/messages/{}'.format(BASE_PATH, message_id) response = http_request( 'GET', @@ -313,7 +301,6 @@ def get_message_request(message_id): def get_message_command(): - # get raw data raw_message = get_message_request(demisto.args()['message_id']) @@ -361,7 +348,6 @@ def get_message_command(): def alert_readable_data_summery(alert): - return { 'Alert ID': alert['id'], 'Alert Timestamp': alert['alert']['timestamp'], @@ -377,7 +363,6 @@ def alert_readable_data_summery(alert): def alert_readable_data(alert): - return { 'Alert ID': alert['id'], 'Alert Timestamp': alert['alert']['timestamp'], @@ -393,20 +378,18 @@ def alert_readable_data(alert): def malware_readable_data(malware): - return { - 'Name': malware['name'], + 'Name': malware.get('name'), 'Domain': malware.get('domain'), - 'Downloaded At': malware['downloaded_at'], - 'Executed At': malware['executed_at'], - 'Type': malware['stype'], - 'Submitted At': malware['submitted_at'], - 'SID': malware['sid'] + 'Downloaded At': malware.get('downloaded_at'), + 'Executed At': malware.get('executed_at'), + 'Type': malware.get('stype'), + 'Submitted At': malware.get('submitted_at'), + 'SID': malware.get('sid') } def alert_context_data(alert): - context_data = copy.deepcopy(alert) # remove 'attributes' level context_data.update(context_data.pop('attributes', {})) @@ -414,7 +397,6 @@ def alert_context_data(alert): def get_alerts_request(legacy_id=None, from_last_modified_on=None, etp_message_id=None, size=None, raw_response=False): - url = '{}/alerts'.format(BASE_PATH) # constract the body for the request @@ -445,7 +427,6 @@ def get_alerts_request(legacy_id=None, from_last_modified_on=None, etp_message_i def get_alerts_command(): - args = demisto.args() if 'size' in args.keys(): @@ -498,7 +479,6 @@ def get_alerts_command(): def get_alert_request(alert_id): - url = '{}/alerts/{}'.format(BASE_PATH, alert_id) response = http_request( 'GET', @@ -510,10 +490,8 @@ def get_alert_request(alert_id): def get_alert_command(): - # get raw data alert_raw = get_alert_request(demisto.args()['alert_id']) - if alert_raw: # create context data alert_context = alert_context_data(alert_raw) @@ -556,7 +534,6 @@ def get_alert_command(): def parse_string_in_iso_format_to_datetime(iso_format_string): - alert_last_modified = None try: alert_last_modified = datetime.strptime(iso_format_string, "%Y-%m-%dT%H:%M:%S.%f") @@ -569,7 +546,6 @@ def parse_string_in_iso_format_to_datetime(iso_format_string): def parse_alert_to_incident(alert): - context_data = alert_context_data(alert) incident = { 'name': context_data['email']['headers']['subject'], @@ -579,7 +555,6 @@ def parse_alert_to_incident(alert): def fetch_incidents(): - last_run = demisto.getLastRun() week_ago = datetime.now() - timedelta(days=7) iso_format = "%Y-%m-%dT%H:%M:%S.%f" @@ -596,10 +571,11 @@ def fetch_incidents(): raw_response=True ) # end if no results returned - if not alerts_raw_response or 'data' not in alerts_raw_response.keys(): + if not alerts_raw_response or not alerts_raw_response.get('data'): + demisto.incidents([]) return - alerts = alerts_raw_response['data'] + alerts = alerts_raw_response.get('data', []) last_alert_created = parse_string_in_iso_format_to_datetime(last_run['last_created']) alert_creation_limit = parse_string_in_iso_format_to_datetime(last_run['last_created']) incidents = [] @@ -629,24 +605,30 @@ def fetch_incidents(): EXECUTION ''' -set_proxies() - -try: - if demisto.command() == 'test-module': - alerts = get_alerts_request(size=1) - # request was succesful - demisto.results('ok') - if demisto.command() == 'fetch-incidents': - fetch_incidents() - if demisto.command() == 'fireeye-etp-search-messages': - search_messages_command() - if demisto.command() == 'fireeye-etp-get-message': - get_message_command() - if demisto.command() == 'fireeye-etp-get-alerts': - get_alerts_command() - if demisto.command() == 'fireeye-etp-get-alert': - get_alert_command() -except ValueError as e: - LOG(e) - LOG.print_log() - return_error_entry(e) + +def main(): + set_proxies() + + try: + if demisto.command() == 'test-module': + get_alerts_request(size=1) + # request was succesful + demisto.results('ok') + if demisto.command() == 'fetch-incidents': + fetch_incidents() + if demisto.command() == 'fireeye-etp-search-messages': + search_messages_command() + if demisto.command() == 'fireeye-etp-get-message': + get_message_command() + if demisto.command() == 'fireeye-etp-get-alerts': + get_alerts_command() + if demisto.command() == 'fireeye-etp-get-alert': + get_alert_command() + except ValueError as e: + LOG(e) + LOG.print_log() + return_error_entry(e) + + +if __name__ in ('__main__', '__builtin__', 'builtins'): + main() diff --git a/Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP_test.py b/Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP_test.py new file mode 100644 index 000000000000..2b9e87b1b207 --- /dev/null +++ b/Packs/FireEyeETP/Integrations/FireEyeETP/FireEyeETP_test.py @@ -0,0 +1,14 @@ +def test_malware_readable_data(): + """ + Given: + A dict with only "name" key + When: + calling malware_readable_data method on it + Then: + Ensure execution does not raise exception on it + """ + from FireEyeETP import malware_readable_data + try: + malware_readable_data({'name': 'some-name'}) + except KeyError: + assert False, 'malware_readable_data method should not fail on dict with name key only' diff --git a/Packs/FireEyeETP/ReleaseNotes/1_0_1.md b/Packs/FireEyeETP/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..4ca116fe4382 --- /dev/null +++ b/Packs/FireEyeETP/ReleaseNotes/1_0_1.md @@ -0,0 +1,4 @@ + +#### Integrations +- __FireEye ETP__ +Improved empty response handling. diff --git a/Packs/FireEyeETP/pack_metadata.json b/Packs/FireEyeETP/pack_metadata.json index 99497824fbbe..9f8dc43a0eb1 100644 --- a/Packs/FireEyeETP/pack_metadata.json +++ b/Packs/FireEyeETP/pack_metadata.json @@ -1,16 +1,16 @@ { - "name": "FireEye ETP", - "description": "FireEye Email Threat Prevention (ETP Cloud) is a cloud-based platform that protects against advanced email attacks.", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-04-14T00:00:00Z", - "categories": [ - "Email Gateway" - ], - "tags": [], - "useCases": [], - "keywords": [] -} + "name": "FireEye ETP", + "description": "FireEye Email Threat Prevention (ETP Cloud) is a cloud-based platform that protects against advanced email attacks.", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-04-14T00:00:00Z", + "categories": [ + "Email Gateway" + ], + "tags": [], + "useCases": [], + "keywords": [] +} \ No newline at end of file From 33a6d98791dce452bb30a3c6ac376630d6dd5bd4 Mon Sep 17 00:00:00 2001 From: altmannyarden <61933087+altmannyarden@users.noreply.github.com> Date: Tue, 9 Jun 2020 10:31:17 +0300 Subject: [PATCH 004/200] [Enhancement] Search Search Endpoints By Hash - Carbon Black Response (#7399) * Deprecated Search Search Endpoints By Hash - Carbon Black Response. Created new playbook Search Search Endpoints By Hash - Carbon Black Response V2 instead. * added the playbook image. * added the playbook image. * Updated playbook image * Update playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.yml * Update playbook-Search_Endpoints_By_Hash_-_Generic_V2.yml * Update playbook-Hunt_Extracted_Hashes.yml * Update playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response.yml * updated release notes Co-authored-by: yaron-libman <43783884+yaron-libman@users.noreply.github.com> --- ...nts_By_Hash_-_Carbon_Black_Response_V2.yml | 278 ++++++++++++ ..._Hash_-_Carbon_Black_Response_V2_README.md | 35 ++ .../ReleaseNotes/1_0_2.md | 4 + .../ReleaseNotes/1_0_3.md | 4 + ...nts_By_Hash_-_Carbon_Black_Response_V2.png | Bin 0 -> 74810 bytes ...-Search_Endpoints_By_Hash_-_Generic_V2.yml | 418 ++++++++++++++++++ ...h_Endpoints_By_Hash_-_Generic_V2_README.md | 41 ++ .../Search_Endpoints_By_Hash_-_Generic_V2.png | Bin 0 -> 148667 bytes .../playbook-Hunt_Extracted_Hashes.yml | 2 +- ...laybook-Hunt_Extracted_Hashes_CHANGELOG.md | 2 +- .../playbook-Hunt_Extracted_Hashes_README.md | 2 +- ...points_By_Hash_-_Carbon_Black_Response.yml | 4 +- ..._Hash_-_Carbon_Black_Response_CHANGELOG.md | 2 + ..._By_Hash_-_Carbon_Black_Response_README.md | 2 +- ...Search_Endpoints_By_Hash_-_Generic_4_5.yml | 2 +- ...dpoints_By_Hash_-_Generic_4_5_CHANGELOG.md | 2 +- ..._Endpoints_By_Hash_-_Generic_4_5_README.md | 2 +- .../playbook-Hunt_Extracted_Hashes_V2.yml | 258 +++++++++++ ...laybook-Hunt_Extracted_Hashes_V2_README.md | 33 ++ .../doc_files/Hunt_Extracted_Hashes_V2.png | Bin 0 -> 73338 bytes ..._Hash_-_Carbon_Black_Response_CHANGELOG.md | 2 - 21 files changed, 1082 insertions(+), 11 deletions(-) create mode 100644 Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.yml create mode 100644 Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2_README.md create mode 100644 Packs/Carbon_Black_Enterprise_Response/doc_files/Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.png create mode 100644 Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2.yml create mode 100644 Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2_README.md create mode 100644 Packs/CommonPlaybooks/doc_files/Search_Endpoints_By_Hash_-_Generic_V2.png rename Packs/{Hunting => DeprecatedContent}/Playbooks/playbook-Hunt_Extracted_Hashes.yml (97%) rename Packs/{Hunting => DeprecatedContent}/Playbooks/playbook-Hunt_Extracted_Hashes_CHANGELOG.md (87%) rename Packs/{Hunting => DeprecatedContent}/Playbooks/playbook-Hunt_Extracted_Hashes_README.md (78%) rename Packs/{Legacy => DeprecatedContent}/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response.yml (97%) create mode 100644 Packs/DeprecatedContent/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_CHANGELOG.md rename Packs/{Legacy => DeprecatedContent}/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_README.md (86%) rename Packs/{CommonPlaybooks => DeprecatedContent}/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_4_5.yml (98%) rename Packs/{CommonPlaybooks => DeprecatedContent}/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_4_5_CHANGELOG.md (59%) rename Packs/{CommonPlaybooks => DeprecatedContent}/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_4_5_README.md (92%) create mode 100644 Packs/Hunting/Playbooks/playbook-Hunt_Extracted_Hashes_V2.yml create mode 100644 Packs/Hunting/Playbooks/playbook-Hunt_Extracted_Hashes_V2_README.md create mode 100644 Packs/Hunting/doc_files/Hunt_Extracted_Hashes_V2.png delete mode 100644 Packs/Legacy/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_CHANGELOG.md diff --git a/Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.yml b/Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.yml new file mode 100644 index 000000000000..c351d69d9962 --- /dev/null +++ b/Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.yml @@ -0,0 +1,278 @@ +id: Search Endpoints By Hash - Carbon Black Response V2 +version: -1 +name: Search Endpoints By Hash - Carbon Black Response V2 +description: Hunt for malicious indicators using Carbon Black +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: edc8b672-13e8-48fa-87c9-594118876ac4 + type: start + task: + id: edc8b672-13e8-48fa-87c9-594118876ac4 + version: -1 + name: "" + description: Playbook start point + iscommand: false + brand: "" + nexttasks: + '#none#': + - "2" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 50 + } + } + note: false + timertriggers: [] + ignoreworker: false + "1": + id: "1" + taskid: 71c8642a-2af7-4af6-8015-5a2f89fd40d2 + type: regular + task: + id: 71c8642a-2af7-4af6-8015-5a2f89fd40d2 + version: -1 + name: Hunt MD5 Hash + description: Query processes based on given parameters + script: '|||cb-get-processes' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "3" + scriptarguments: + facet: {} + group: {} + hostname: {} + md5: + complex: + root: inputs + accessor: Hash + name: {} + parent-process-name: {} + process-path: {} + query: {} + rows: {} + sort: {} + start: {} + separatecontext: false + view: |- + { + "position": { + "x": 500, + "y": 680 + } + } + note: false + timertriggers: [] + ignoreworker: false + "2": + id: "2" + taskid: a43ea7bf-d5e3-4c0b-8da7-5ce65cc1aae3 + type: condition + task: + id: a43ea7bf-d5e3-4c0b-8da7-5ce65cc1aae3 + version: -1 + name: Is Carbon Black enabled? + description: Is Carbon Black enabled? + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "7" + "yes": + - "5" + scriptarguments: + value: + simple: ${modules(val.brand == 'carbonblack' && val.state == 'active')} + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isExists + left: + value: + complex: + root: modules + filters: + - - operator: isEqualString + left: + value: + simple: modules.brand + iscontext: true + right: + value: + simple: carbonblack-v2 + - - operator: isEqualString + left: + value: + simple: modules.state + iscontext: true + right: + value: + simple: active + accessor: brand + iscontext: true + view: |- + { + "position": { + "x": 50, + "y": 195 + } + } + note: false + timertriggers: [] + ignoreworker: false + "3": + id: "3" + taskid: 108ba97d-b9da-4162-808d-025b5f6b7986 + type: title + task: + id: 108ba97d-b9da-4162-808d-025b5f6b7986 + version: -1 + name: Done + description: Done + type: title + iscommand: false + brand: "" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 865 + } + } + note: false + timertriggers: [] + ignoreworker: false + "5": + id: "5" + taskid: 00c09fd8-6352-4b6c-8e7a-5a2459544fc7 + type: condition + task: + id: 00c09fd8-6352-4b6c-8e7a-5a2459544fc7 + version: -1 + name: Is there an MD5 hash to hunt? + description: Checks if there is an MD5 hash to hunt. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "7" + "yes": + - "6" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + complex: + root: inputs.Hash + iscontext: true + view: |- + { + "position": { + "x": 290, + "y": 370 + } + } + note: false + timertriggers: [] + ignoreworker: false + "6": + id: "6" + taskid: 4fd8eec7-f7ec-4f53-8473-932db46cc0ec + type: title + task: + id: 4fd8eec7-f7ec-4f53-8473-932db46cc0ec + version: -1 + name: Hunt MD5 + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "1" + separatecontext: false + view: |- + { + "position": { + "x": 500, + "y": 540 + } + } + note: false + timertriggers: [] + ignoreworker: false + "7": + id: "7" + taskid: 863da4aa-ab0b-416b-8072-1f36602773aa + type: title + task: + id: 863da4aa-ab0b-416b-8072-1f36602773aa + version: -1 + name: No Integration \ No Hash + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "3" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 540 + } + } + note: false + timertriggers: [] + ignoreworker: false +view: |- + { + "linkLabelsPosition": { + "2_5_yes": 0.41, + "2_7_#default#": 0.42, + "5_6_yes": 0.47, + "5_7_#default#": 0.41 + }, + "paper": { + "dimensions": { + "height": 880, + "width": 830, + "x": 50, + "y": 50 + } + } + } +inputs: +- key: Hash + value: + complex: + root: File + accessor: MD5 + required: false + description: MD5 Hash +outputs: +- contextPath: Endpoint.Hostname + description: The device hostname + type: string +- contextPath: Endpoint + description: The endpoint + type: unknown +fromversion: 4.5.0 +tests: +- No tests diff --git a/Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2_README.md b/Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2_README.md new file mode 100644 index 000000000000..17a15fc24db8 --- /dev/null +++ b/Packs/Carbon_Black_Enterprise_Response/Playbooks/playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2_README.md @@ -0,0 +1,35 @@ +Hunt for malicious indicators using Carbon Black + +## Dependencies +This playbook uses the following sub-playbooks, integrations, and scripts. + +### Sub-playbooks +This playbook does not use any sub-playbooks. + +### Integrations +* integration-Carbon_Black_Enterprise_Response + +### Scripts +This playbook does not use any scripts. + +### Commands +* cb-get-processes + +## Playbook Inputs +--- + +| **Name** | **Description** | **Default Value** | **Required** | +| --- | --- | --- | --- | +| Hash | MD5 Hash | File.MD5 | Optional | + +## Playbook Outputs +--- + +| **Path** | **Description** | **Type** | +| --- | --- | --- | +| Endpoint.Hostname | The device hostname | string | +| Endpoint | The endpoint | unknown | + +## Playbook Image +--- +![Search Endpoints By Hash - Carbon Black Response V2](Insert the link to your image here) \ No newline at end of file diff --git a/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_2.md b/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_2.md index 49ea2d1f62c2..906c8f7a867b 100644 --- a/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_2.md +++ b/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_2.md @@ -5,3 +5,7 @@ - __CBEvents__ - --> + +### Playbook +- __Search Endpoints By Hash - Carbon Black Response V2__ +- Hunt for malicious indicators using Carbon Black diff --git a/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_3.md b/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_3.md index 33728ad8aaa1..deee8b7531d2 100644 --- a/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_3.md +++ b/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/1_0_3.md @@ -3,3 +3,7 @@ - __carbonblack-v2_ - Fixed an issue where the file context did not behave as expected in the ***cb-get-processes*** command. + +### Playbook +- __Search Endpoints By Hash - Carbon Black Response V2__ + - New playbook - Search Endpoints By Hash - Carbon Black Response V2 playbook with carbonblack-v2. diff --git a/Packs/Carbon_Black_Enterprise_Response/doc_files/Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.png b/Packs/Carbon_Black_Enterprise_Response/doc_files/Search_Endpoints_By_Hash_-_Carbon_Black_Response_V2.png new file mode 100644 index 0000000000000000000000000000000000000000..02849fb9c0c2ad043c7ed074d7e59221304bccf5 GIT binary patch literal 74810 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 literal 0 HcmV?d00001 diff --git a/Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2.yml b/Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2.yml new file mode 100644 index 000000000000..4f581f1c9658 --- /dev/null +++ b/Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2.yml @@ -0,0 +1,418 @@ +id: Search Endpoints By Hash - Generic V2 +version: -1 +name: Search Endpoints By Hash - Generic V2 +description: Hunt using available tools +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: c485e19b-c83a-48e4-892c-8bd91e17ced2 + type: start + task: + id: c485e19b-c83a-48e4-892c-8bd91e17ced2 + version: -1 + name: "" + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "9" + - "10" + separatecontext: false + view: |- + { + "position": { + "x": 690, + "y": -50 + } + } + note: false + timertriggers: [] + ignoreworker: false + "5": + id: "5" + taskid: f4b71101-7ae3-4ce8-87b7-10eeb13c1a79 + type: playbook + task: + id: f4b71101-7ae3-4ce8-87b7-10eeb13c1a79 + version: -1 + name: Search Endpoints By Hash - CrowdStrike + playbookName: Search Endpoints By Hash - CrowdStrike + type: playbook + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "12" + scriptarguments: + MD5Hash: + complex: + root: inputs + accessor: MD5Hash + SHA1Hash: + complex: + root: inputs + accessor: SHA1Hash + SHA256Hash: + complex: + root: inputs + accessor: SHA256Hash + separatecontext: true + loop: + iscommand: false + exitCondition: "" + wait: 1 + view: |- + { + "position": { + "x": 63, + "y": 320 + } + } + note: false + timertriggers: [] + ignoreworker: false + "8": + id: "8" + taskid: 912e992b-d3bd-4353-8177-5ea207ef2ac6 + type: playbook + task: + id: 912e992b-d3bd-4353-8177-5ea207ef2ac6 + version: -1 + name: Search Endpoints By Hash - Carbon Black Protection + playbookName: Search Endpoints By Hash - Carbon Black Protection + type: playbook + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "12" + scriptarguments: + Hash: + complex: + root: inputs + accessor: MD5Hash + separatecontext: true + loop: + iscommand: false + exitCondition: "" + wait: 1 + view: |- + { + "position": { + "x": 1350, + "y": 500 + } + } + note: false + timertriggers: [] + ignoreworker: false + "9": + id: "9" + taskid: 9510dbd8-98c3-4611-802f-333acf31875b + type: title + task: + id: 9510dbd8-98c3-4611-802f-333acf31875b + version: -1 + name: MD5 Only + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "11" + separatecontext: false + view: |- + { + "position": { + "x": 1148, + "y": 200 + } + } + note: false + timertriggers: [] + ignoreworker: false + "10": + id: "10" + taskid: ce67117f-133a-4da3-84be-14e4a831756a + type: title + task: + id: ce67117f-133a-4da3-84be-14e4a831756a + version: -1 + name: MD5 / SHA1 / SHA256 + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "5" + - "13" + - "15" + separatecontext: false + view: |- + { + "position": { + "x": 63, + "y": 160 + } + } + note: false + timertriggers: [] + ignoreworker: false + "11": + id: "11" + taskid: 05df1d6e-f77e-4b06-8c62-2750064f5b00 + type: condition + task: + id: 05df1d6e-f77e-4b06-8c62-2750064f5b00 + version: -1 + name: Is MD5 hash? + description: Is MD5 hash? + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "14" + "yes": + - "8" + - "16" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isExists + left: + value: + complex: + root: inputs + accessor: MD5Hash + iscontext: true + view: |- + { + "position": { + "x": 1148, + "y": 309 + } + } + note: false + timertriggers: [] + ignoreworker: false + "12": + id: "12" + taskid: f2a05482-2b17-4a09-8813-be48459935c3 + type: title + task: + id: f2a05482-2b17-4a09-8813-be48459935c3 + version: -1 + name: Done + type: title + iscommand: false + brand: "" + description: '' + separatecontext: false + view: |- + { + "position": { + "x": 790, + "y": 690 + } + } + note: false + timertriggers: [] + ignoreworker: false + "13": + id: "13" + taskid: a6785055-98d6-4b2e-8da8-c2e0c6b90887 + type: playbook + task: + id: a6785055-98d6-4b2e-8da8-c2e0c6b90887 + version: -1 + name: Search Endpoints By Hash - McAfee TIE + description: |- + Hunt for sightings of MD5, SHA1 and/or SHA256 hashes on endpoints, using McAfee TIE (requires ePO as well). + + Input: + * Hash (default, takes all different hashes from context) + + Output: + * All endpoints with TIE on which the file with the hash was found. + * Enrich Agents info from ePO + playbookName: Search Endpoints By Hash - TIE + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "12" + scriptarguments: + Hash: + simple: ${.=Object.keys(val.inputs).map(function(f) { return val.inputs[f]; + }).reduce(function(a, b){ return a.concat(b); }, [])} + separatecontext: true + loop: + iscommand: false + exitCondition: "" + wait: 1 + view: |- + { + "position": { + "x": 480, + "y": 320 + } + } + note: false + timertriggers: [] + ignoreworker: false + "14": + id: "14" + taskid: 974d2e04-3c66-445c-844d-be5ebdbc218e + type: title + task: + id: 974d2e04-3c66-445c-844d-be5ebdbc218e + version: -1 + name: No MD5 + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "12" + separatecontext: false + view: |- + { + "position": { + "x": 1770, + "y": 480 + } + } + note: false + timertriggers: [] + ignoreworker: false + "15": + id: "15" + taskid: 9a4ed50f-2387-466f-8d3f-a1b1c05c57d1 + type: playbook + task: + id: 9a4ed50f-2387-466f-8d3f-a1b1c05c57d1 + version: -1 + name: Search Endpoints By Hash - Cybereason + playbookName: Search Endpoints By Hash - Cybereason + type: playbook + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "12" + scriptarguments: + MD5Hash: + complex: + root: inputs.MD5Hash + SHA1Hash: + complex: + root: inputs.SHA1Hash + separatecontext: true + loop: + iscommand: false + exitCondition: "" + wait: 1 + view: |- + { + "position": { + "x": -350, + "y": 320 + } + } + note: false + timertriggers: [] + ignoreworker: false + "16": + id: "16" + taskid: 0776ac69-dbd9-4a61-8b55-7d721d2dafe7 + type: playbook + task: + id: 0776ac69-dbd9-4a61-8b55-7d721d2dafe7 + version: -1 + name: Search Endpoints By Hash - Carbon Black Response V2 + playbookName: Search Endpoints By Hash - Carbon Black Response V2 + type: playbook + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "12" + scriptarguments: + Hash: + complex: + root: File + accessor: MD5 + separatecontext: true + loop: + iscommand: false + exitCondition: "" + wait: 1 + view: |- + { + "position": { + "x": 920, + "y": 500 + } + } + note: false + timertriggers: [] + ignoreworker: false +view: |- + { + "linkLabelsPosition": { + "11_16_yes": 0.47, + "11_8_yes": 0.58 + }, + "paper": { + "dimensions": { + "height": 805, + "width": 2500, + "x": -350, + "y": -50 + } + } + } +inputs: +- key: MD5Hash + value: + complex: + root: File + accessor: MD5 + required: false + description: MD5 Hash +- key: SHA1Hash + value: + complex: + root: File + accessor: SHA1 + required: false + description: SHA1 Hash +- key: SHA256Hash + value: + complex: + root: File + accessor: SHA256 + required: false + description: SHA256 Hash +outputs: +- contextPath: Endpoint.Hostname + description: Device hostname + type: string +- contextPath: Endpoint + description: The endpoint + type: unknown +fromversion: 4.5.0 +tests: +- No tests diff --git a/Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2_README.md b/Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2_README.md new file mode 100644 index 000000000000..986d29033229 --- /dev/null +++ b/Packs/CommonPlaybooks/Playbooks/playbook-Search_Endpoints_By_Hash_-_Generic_V2_README.md @@ -0,0 +1,41 @@ +Hunt using available tools + +## Dependencies +This playbook uses the following sub-playbooks, integrations, and scripts. + +### Sub-playbooks +* Search Endpoints By Hash - CrowdStrike +* Search Endpoints By Hash - Cybereason +* Search Endpoints By Hash - TIE +* Search Endpoints By Hash - Carbon Black Response V2 +* Search Endpoints By Hash - Carbon Black Protection + +### Integrations +This playbook does not use any integrations. + +### Scripts +This playbook does not use any scripts. + +### Commands +This playbook does not use any commands. + +## Playbook Inputs +--- + +| **Name** | **Description** | **Default Value** | **Required** | +| --- | --- | --- | --- | +| MD5Hash | MD5 Hash | File.MD5 | Optional | +| SHA1Hash | SHA1 Hash | File.SHA1 | Optional | +| SHA256Hash | SHA256 Hash | File.SHA256 | Optional | + +## Playbook Outputs +--- + +| **Path** | **Description** | **Type** | +| --- | --- | --- | +| Endpoint.Hostname | Device hostname | string | +| Endpoint | The endpoint | unknown | + +## Playbook Image +--- +![Search Endpoints By Hash - Generic V2](Insert the link to your image here) \ No newline at end of file diff --git a/Packs/CommonPlaybooks/doc_files/Search_Endpoints_By_Hash_-_Generic_V2.png b/Packs/CommonPlaybooks/doc_files/Search_Endpoints_By_Hash_-_Generic_V2.png new file mode 100644 index 0000000000000000000000000000000000000000..d8b4016afba7bfd3bd340d6d9096d88d42a26e4e GIT binary patch literal 148667 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%0DOOZNB-?oQV`x0m-We();(O-MX-1n{DSrOa>Y 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

2TMAN>^)TU4i8R-5Z}%4e()T*1 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�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 Date: Tue, 9 Jun 2020 10:52:42 +0300 Subject: [PATCH 005/200] out of skipped tests (#7456) * out of skipped * parse email files out of skipped --- Tests/conf.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/Tests/conf.json b/Tests/conf.json index dcef88f43f6c..3ddc652c604f 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -2841,10 +2841,8 @@ "Test-Detonate URL - Crowdstrike": "Issue 19439", "Git_Integration-Test": "Issue 20029", "Symantec Data Loss Prevention - Test": "Issue 20134", - "Extract Indicators From File - Generic v2": "Issue 20143", "PAN-OS Create Or Edit Rule Test": "Issue 20037", "NetWitness Endpoint Test": "Issue 19878", - "TestParseEmailHeaders": "Issue 18815", "TestUptycs": "Issue 19750", "InfoArmorVigilanteATITest": "Test issue 17358", "Lastline - testplaybook": "Checking the integration via Generic detonation playbooks, don't want to load the daily quota", From 9078198025cb93cf5768f51262fb78bc212e3b3e Mon Sep 17 00:00:00 2001 From: Yana Orhov Date: Tue, 9 Jun 2020 12:01:39 +0300 Subject: [PATCH 006/200] Auto detect api modules (#7257) * changed docker image * changed docker image * changed docker image * changed docker image * changed docker image * updated conf json for nightly tests on generic feeds * updated None to '' * updated None to '' * updated conf json * updated conf json * updated conf json * updated conf json * updated rn * updated rn * updated pr * updated pr * fixed json ut * fixed json ut * fixed json ut * fixed json ut * updated pr * updated pr * updated pr * updated pr * updated pr Co-authored-by: yorhov --- Packs/ApiModules/ReleaseNotes/1_0_2.md | 8 +++++ .../Scripts/CSVFeedApiModule/CHANGELOG.md | 2 +- .../CSVFeedApiModule/CSVFeedApiModule.py | 33 ++++++++++-------- .../CSVFeedApiModule/CSVFeedApiModule.yml | 2 +- .../Scripts/HTTPFeedApiModule/CHANGELOG.md | 2 +- .../HTTPFeedApiModule/HTTPFeedApiModule.py | 31 ++++++++++++++--- .../HTTPFeedApiModule/HTTPFeedApiModule.yml | 2 +- .../JSONFeedApiModule/JSONFeedApiModule.py | 26 +++++++++++--- .../JSONFeedApiModule_test.py | 11 +++--- Packs/ApiModules/pack_metadata.json | 2 +- Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.py | 13 ++++++- .../FeedCSV/Integrations/FeedCSV/FeedCSV.yml | 12 +++++-- Packs/FeedCSV/ReleaseNotes/1_0_1.md | 4 +++ Packs/FeedCSV/pack_metadata.json | 34 +++++++++---------- .../Integrations/FeedJSON/FeedJSON.yml | 5 ++- Packs/FeedJSON/ReleaseNotes/1_0_1.md | 4 +++ Packs/FeedJSON/pack_metadata.json | 34 +++++++++---------- .../FeedPlainText/FeedPlainText.py | 11 ++++++ .../FeedPlainText/FeedPlainText.yml | 12 +++++-- Packs/FeedPlainText/ReleaseNotes/1_0_1.md | 4 +++ Packs/FeedPlainText/pack_metadata.json | 28 +++++++-------- Tests/conf.json | 28 +++++++++++++-- 22 files changed, 215 insertions(+), 93 deletions(-) create mode 100644 Packs/ApiModules/ReleaseNotes/1_0_2.md create mode 100644 Packs/FeedCSV/ReleaseNotes/1_0_1.md create mode 100644 Packs/FeedJSON/ReleaseNotes/1_0_1.md create mode 100644 Packs/FeedPlainText/ReleaseNotes/1_0_1.md diff --git a/Packs/ApiModules/ReleaseNotes/1_0_2.md b/Packs/ApiModules/ReleaseNotes/1_0_2.md new file mode 100644 index 000000000000..8d697d8197c3 --- /dev/null +++ b/Packs/ApiModules/ReleaseNotes/1_0_2.md @@ -0,0 +1,8 @@ + +### Scripts +- __JSONFeedApiModule__ + - Added support for auto detection of indicator types. +- __CSVFeedApiModule__ + - Added support for auto detection of indicator types. +- __HTTPFeedApiModule__ + - Added support for auto detection of indicator types. \ No newline at end of file diff --git a/Packs/ApiModules/Scripts/CSVFeedApiModule/CHANGELOG.md b/Packs/ApiModules/Scripts/CSVFeedApiModule/CHANGELOG.md index 9053f63c0516..b8d7d9f41503 100644 --- a/Packs/ApiModules/Scripts/CSVFeedApiModule/CHANGELOG.md +++ b/Packs/ApiModules/Scripts/CSVFeedApiModule/CHANGELOG.md @@ -1,5 +1,5 @@ ## [Unreleased] - +Added support for auto detection of indicator types. ## [20.4.1] - 2020-04-29 Fixed an issue where *firstseenbysource* and *lastseenbysource* fields were not formatted correctly. diff --git a/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.py b/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.py index e3fc23d83e8e..f975248c7bb4 100644 --- a/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.py +++ b/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.py @@ -181,21 +181,25 @@ def get_feed_content_divided_to_lines(self, url, raw_response): return response_content.decode(self.encoding).split('\n') -def determine_indicator_type(indicator_type, default_indicator_type, value): +def determine_indicator_type(indicator_type, default_indicator_type, auto_detect, value): + """ + Detect the indicator type of the given value. + Args: + indicator_type: (str) Indicator type given in the config. + default_indicator_type: Indicator type which was inserted as a param of the integration by user. + auto_detect: (bool) True whether auto detection of the indicator type is wanted. + value: (str) The value which we'd like to get indicator type of. + Returns: + Str which stands for the indicator type after detection. + """ + if auto_detect: + indicator_type = auto_detect_indicator_type(value) if not indicator_type: indicator_type = default_indicator_type - if indicator_type == FeedIndicatorType.Domain and '*' in value: - indicator_type = FeedIndicatorType.DomainGlob return indicator_type def module_test_command(client: Client, args): - if not client.feed_url_to_config: - indicator_type = args.get('indicator_type', demisto.params().get('indicator_type')) - if not FeedIndicatorType.is_valid_type(indicator_type): - supported_values = FeedIndicatorType.list_all_supported_indicators() - raise ValueError(f'Indicator type of {indicator_type} is not supported. Supported values are:' - f' {supported_values}') client.build_iterator() return 'ok', {}, {} @@ -240,7 +244,7 @@ def create_fields_mapping(raw_json: Dict[str, Any], mapping: Dict[str, Union[Tup return fields_mapping -def fetch_indicators_command(client: Client, default_indicator_type: str, **kwargs): +def fetch_indicators_command(client: Client, default_indicator_type: str, auto_detect: bool, **kwargs): iterator = client.build_iterator(**kwargs) indicators = [] config = client.feed_url_to_config or {} @@ -255,7 +259,8 @@ def fetch_indicators_command(client: Client, default_indicator_type: str, **kwar if value: raw_json['value'] = value conf_indicator_type = config.get(url, {}).get('indicator_type') - indicator_type = determine_indicator_type(conf_indicator_type, default_indicator_type, value) + indicator_type = determine_indicator_type(conf_indicator_type, default_indicator_type, auto_detect, + value) raw_json['type'] = indicator_type indicator = { 'value': value, @@ -264,14 +269,14 @@ def fetch_indicators_command(client: Client, default_indicator_type: str, **kwar 'fields': create_fields_mapping(raw_json, mapping) if mapping else {} } indicators.append(indicator) - return indicators def get_indicators_command(client, args): itype = args.get('indicator_type', demisto.params().get('indicator_type')) limit = int(args.get('limit')) - indicators_list = fetch_indicators_command(client, itype) + auto_detect = demisto.params().get('auto_detect_type') + indicators_list = fetch_indicators_command(client, itype, auto_detect) entry_result = indicators_list[:limit] hr = tableToMarkdown('Indicators', entry_result, headers=['value', 'type', 'fields']) return hr, {}, indicators_list @@ -294,7 +299,7 @@ def feed_main(feed_name, params=None, prefix=''): } try: if command == 'fetch-indicators': - indicators = fetch_indicators_command(client, params.get('indicator_type')) + indicators = fetch_indicators_command(client, params.get('indicator_type'), params.get('auto_detect_type')) # we submit the indicators in batches for b in batch(indicators, batch_size=2000): demisto.createIndicators(b) # type: ignore diff --git a/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.yml b/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.yml index 0f058f1089bc..422487fb007b 100644 --- a/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.yml +++ b/Packs/ApiModules/Scripts/CSVFeedApiModule/CSVFeedApiModule.yml @@ -13,4 +13,4 @@ system: true scripttarget: 0 dependson: {} timeout: 0s -dockerimage: demisto/python3:3.7.5.5420 \ No newline at end of file +dockerimage: demisto/jmespath:1.0.0.6980 \ No newline at end of file diff --git a/Packs/ApiModules/Scripts/HTTPFeedApiModule/CHANGELOG.md b/Packs/ApiModules/Scripts/HTTPFeedApiModule/CHANGELOG.md index b7fad792a33a..8d68ded81eba 100644 --- a/Packs/ApiModules/Scripts/HTTPFeedApiModule/CHANGELOG.md +++ b/Packs/ApiModules/Scripts/HTTPFeedApiModule/CHANGELOG.md @@ -1,5 +1,5 @@ ## [Unreleased] - +Added support for auto detection of indicator types. ## [20.5.0] - 2020-05-12 Fixed an issue where tag parsing did not work as expected. diff --git a/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.py b/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.py index 5f088bbf9fe1..d20e83546607 100644 --- a/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.py +++ b/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.py @@ -328,7 +328,7 @@ def get_indicator_fields(line, url, feed_tags: list, client: Client): return attributes, value -def fetch_indicators_command(client, feed_tags, itype, **kwargs): +def fetch_indicators_command(client, feed_tags, itype, auto_detect, **kwargs): iterators = client.build_iterator(**kwargs) indicators = [] for iterator in iterators: @@ -343,10 +343,11 @@ def fetch_indicators_command(client, feed_tags, itype, **kwargs): if 'firstseenbysource' in attributes.keys(): attributes['firstseenbysource'] = datestring_to_millisecond_timestamp( attributes['firstseenbysource']) - + indicator_type = determine_indicator_type( + client.feed_url_to_config.get(url, {}).get('indicator_type'), itype, auto_detect, value) indicator_data = { "value": value, - "type": client.feed_url_to_config.get(url, {}).get('indicator_type', itype), + "type": indicator_type, "rawJSON": attributes, } @@ -358,11 +359,30 @@ def fetch_indicators_command(client, feed_tags, itype, **kwargs): return indicators +def determine_indicator_type(indicator_type, default_indicator_type, auto_detect, value): + """ + Detect the indicator type of the given value. + Args: + indicator_type: (str) Indicator type given in the config. + default_indicator_type: Indicator type which was inserted as a param of the integration by user. + auto_detect: (bool) True whether auto detection of the indicator type is wanted. + value: (str) The value which we'd like to get indicator type of. + Returns: + Str which stands for the indicator type after detection. + """ + if auto_detect: + indicator_type = auto_detect_indicator_type(value) + if not indicator_type: + indicator_type = default_indicator_type + return indicator_type + + def get_indicators_command(client: Client, args): itype = args.get('indicator_type', client.indicator_type) limit = int(args.get('limit')) feed_tags = args.get('feedTags') - indicators_list = fetch_indicators_command(client, feed_tags, itype)[:limit] + auto_detect = demisto.params().get('auto_detect_type') + indicators_list = fetch_indicators_command(client, feed_tags, itype, auto_detect)[:limit] entry_result = camelize(indicators_list) hr = tableToMarkdown('Indicators', entry_result, headers=['Value', 'Type', 'Rawjson']) return hr, {}, indicators_list @@ -402,7 +422,8 @@ def feed_main(feed_name, params=None, prefix=''): } try: if command == 'fetch-indicators': - indicators = fetch_indicators_command(client, feed_tags, params.get('indicator_type')) + indicators = fetch_indicators_command(client, feed_tags, params.get('indicator_type'), + params.get('auto_detect_type')) # we submit the indicators in batches for b in batch(indicators, batch_size=2000): demisto.createIndicators(b) diff --git a/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.yml b/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.yml index f86bfecd4e33..41b263981afd 100644 --- a/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.yml +++ b/Packs/ApiModules/Scripts/HTTPFeedApiModule/HTTPFeedApiModule.yml @@ -13,4 +13,4 @@ system: true scripttarget: 0 dependson: {} timeout: 0s -dockerimage: demisto/python3:3.7.3.286 \ No newline at end of file +dockerimage: demisto/jmespath:1.0.0.6980 \ No newline at end of file diff --git a/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule.py b/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule.py index d4589f8d3061..9986e81d7e0f 100644 --- a/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule.py +++ b/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule.py @@ -100,7 +100,8 @@ def test_module(client, params) -> str: return 'ok' -def fetch_indicators_command(client: Client, indicator_type: str, feedTags: list, **kwargs) -> Union[Dict, List[Dict]]: +def fetch_indicators_command(client: Client, indicator_type: str, feedTags: list, auto_detect: bool, **kwargs)\ + -> Union[Dict, List[Dict]]: """ Fetches the indicators from client. :param client: Client of a JSON Feed @@ -120,7 +121,7 @@ def fetch_indicators_command(client: Client, indicator_type: str, feedTags: list item = {indicator_field: item} indicator_value = item.get(indicator_field) - current_indicator_type = indicator_type or auto_detect_indicator_type(indicator_value) + current_indicator_type = determine_indicator_type(indicator_type, auto_detect, indicator_value) if not current_indicator_type: continue @@ -143,6 +144,21 @@ def fetch_indicators_command(client: Client, indicator_type: str, feedTags: list return indicators +def determine_indicator_type(indicator_type, auto_detect, value): + """ + Detect the indicator type of the given value. + Args: + indicator_type: (str) Given indicator type. + auto_detect: (bool) True whether auto detection of the indicator type is wanted. + value: (str) The value which we'd like to get indicator type of. + Returns: + Str which stands for the indicator type after detection. + """ + if auto_detect: + indicator_type = auto_detect_indicator_type(value) + return indicator_type + + def extract_all_fields_from_indicator(indicator, indicator_key): """Flattens the JSON object to create one dictionary of values @@ -195,14 +211,16 @@ def feed_main(params, feed_name, prefix): return_outputs(test_module(client, params)) elif command == 'fetch-indicators': - indicators = fetch_indicators_command(client, indicator_type, feedTags) + indicators = fetch_indicators_command(client, params.get('indicator_type'), feedTags, + params.get('auto_detect_type')) for b in batch(indicators, batch_size=2000): demisto.createIndicators(b) elif command == f'{prefix}get-indicators': # dummy command for testing limit = int(demisto.args().get('limit', 10)) - indicators = fetch_indicators_command(client, indicator_type, feedTags)[:limit] + auto_detect = params.get('auto_detect_type') + indicators = fetch_indicators_command(client, indicator_type, feedTags, auto_detect)[:limit] hr = tableToMarkdown('Indicators', indicators, headers=['value', 'type', 'rawJSON']) return_outputs(hr, {}, indicators) diff --git a/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule_test.py b/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule_test.py index 5f1a8d101843..2329d1993153 100644 --- a/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule_test.py +++ b/Packs/ApiModules/Scripts/JSONFeedApiModule/JSONFeedApiModule_test.py @@ -19,7 +19,8 @@ def test_json_feed_no_config(): insecure=True ) - indicators = fetch_indicators_command(client=client, indicator_type='CIDR', feedTags=['test']) + indicators = fetch_indicators_command(client=client, indicator_type='CIDR', feedTags=['test'], + auto_detect=False) assert len(jmespath.search(expression="[].rawJSON.service", data=indicators)) == 1117 @@ -47,7 +48,8 @@ def test_json_feed_with_config(): insecure=True ) - indicators = fetch_indicators_command(client=client, indicator_type='CIDR', feedTags=['test']) + indicators = fetch_indicators_command(client=client, indicator_type='CIDR', feedTags=['test'], + auto_detect=False) assert len(jmespath.search(expression="[].rawJSON.service", data=indicators)) == 1117 @@ -78,7 +80,8 @@ def test_json_feed_with_config_mapping(): insecure=True ) - indicators = fetch_indicators_command(client=client, indicator_type='CIDR', feedTags=['test']) + indicators = fetch_indicators_command(client=client, indicator_type='CIDR', feedTags=['test'], + auto_detect=False) assert len(jmespath.search(expression="[].rawJSON.service", data=indicators)) == 1117 indicator = indicators[0] custom_fields = indicator['fields'] @@ -113,7 +116,7 @@ def test_list_of_indicators_with_no_json_object(): insecure=True ) - indicators = fetch_indicators_command(client=client, indicator_type=None, feedTags=['test']) + indicators = fetch_indicators_command(client=client, indicator_type=None, feedTags=['test'], auto_detect=True) assert len(indicators) == 3 assert indicators[0].get('value') == '1.1.1.1' assert indicators[0].get('type') == 'IP' diff --git a/Packs/ApiModules/pack_metadata.json b/Packs/ApiModules/pack_metadata.json index 7ceea77dffcb..b98165781835 100644 --- a/Packs/ApiModules/pack_metadata.json +++ b/Packs/ApiModules/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ApiModules", "description": "API Modules", "support": "xsoar", - "currentVersion": "1.0.1", + "currentVersion": "1.0.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.py b/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.py index 6bbc06bce179..f6003ee829e3 100644 --- a/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.py +++ b/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.py @@ -1,9 +1,20 @@ +import demistomock as demisto +from CommonServerPython import * + + def main(): + params = demisto.params() + # when auto_detect is not selected + if params.get('auto_detect_type') is False and not params.get('indicator_type'): + return_error('Indicator Type cannot be empty when Auto Detect Indicator Type is unchecked') + # when auto_detect does not exist - for previous integration instances + if params.get('auto_detect_type') is None and not params.get('indicator_type'): + return_error('Indicator Type cannot be empty') feed_main('CSV', prefix='csv') from CSVFeedApiModule import * # noqa: E402 -if __name__ == '__builtin__' or __name__ == 'builtins': +if __name__ in ('__builtin__', 'builtins', '__main__'): main() diff --git a/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.yml b/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.yml index 68c527f00767..6d4cec107c15 100644 --- a/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.yml +++ b/Packs/FeedCSV/Integrations/FeedCSV/FeedCSV.yml @@ -61,7 +61,13 @@ configuration: required: false type: 8 defaultvalue: "" -- additionalinfo: Type of the indicator in the feed. +- additionalinfo: If selected, the indicator type will be auto detected for each indicator. + defaultvalue: 'true' + display: Auto detect indicator type + name: auto_detect_type + required: false + type: 8 +- additionalinfo: Type of the indicator in the feed, If auto-detect is checked then the value set as Indicator Type will be ignored. display: Indicator Type name: indicator_type required: false @@ -143,7 +149,7 @@ script: required: false secret: false - default: false - description: The indicator type. + description: The indicator type. If the configuration parameter 'Auto detect indicator type' is marked true for the integration instance, then this value will be ignored. isArray: false name: indicator_type required: false @@ -162,7 +168,7 @@ script: - contextPath: CSV.Indicator.rawJSON description: The indicator rawJSON value. type: Unknown - dockerimage: demisto/python3:3.8.1.6120 + dockerimage: demisto/jmespath:1.0.0.6980 feed: true isfetch: false longRunning: false diff --git a/Packs/FeedCSV/ReleaseNotes/1_0_1.md b/Packs/FeedCSV/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..a974757d99b1 --- /dev/null +++ b/Packs/FeedCSV/ReleaseNotes/1_0_1.md @@ -0,0 +1,4 @@ + +### Integrations +- __CSVFeed__ + - Changed the docker image to support auto-detection function. \ No newline at end of file diff --git a/Packs/FeedCSV/pack_metadata.json b/Packs/FeedCSV/pack_metadata.json index 069df762a52f..41be4249c9ea 100644 --- a/Packs/FeedCSV/pack_metadata.json +++ b/Packs/FeedCSV/pack_metadata.json @@ -1,19 +1,19 @@ { - "name": "CSV Feed", - "description": "Indicators feed from a CSV file", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-03-09T16:04:45Z", - "categories": [ - "Data Enrichment & Threat Intelligence" - ], - "tags": [], - "useCases": [], - "keywords": [ - "CSV", - "Feed" - ] + "name": "CSV Feed", + "description": "Indicators feed from a CSV file", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-03-09T16:04:45Z", + "categories": [ + "Data Enrichment & Threat Intelligence" + ], + "tags": [], + "useCases": [], + "keywords": [ + "CSV", + "Feed" + ] } \ No newline at end of file diff --git a/Packs/FeedJSON/Integrations/FeedJSON/FeedJSON.yml b/Packs/FeedJSON/Integrations/FeedJSON/FeedJSON.yml index d22d011e4562..0cf0ec30f435 100644 --- a/Packs/FeedJSON/Integrations/FeedJSON/FeedJSON.yml +++ b/Packs/FeedJSON/Integrations/FeedJSON/FeedJSON.yml @@ -63,8 +63,7 @@ configuration: name: auto_detect_type required: false type: 8 -- additionalinfo: Type of the indicator in the feed. Relevant only if auto detect - is not selected. +- additionalinfo: Type of the indicator in the feed. If auto-detect is checked then the value set as Indicator Type will be ignored. display: Indicator Type name: indicator_type required: false @@ -133,4 +132,4 @@ script: type: python tests: - JSON_Feed_Test -fromversion: 5.5.0 +fromversion: 5.5.0 \ No newline at end of file diff --git a/Packs/FeedJSON/ReleaseNotes/1_0_1.md b/Packs/FeedJSON/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..59093ca75484 --- /dev/null +++ b/Packs/FeedJSON/ReleaseNotes/1_0_1.md @@ -0,0 +1,4 @@ + +### Integrations +- __JSON Feed__ + - updated description of indicator type field. \ No newline at end of file diff --git a/Packs/FeedJSON/pack_metadata.json b/Packs/FeedJSON/pack_metadata.json index 18d243cf75e7..22f617a74c3b 100644 --- a/Packs/FeedJSON/pack_metadata.json +++ b/Packs/FeedJSON/pack_metadata.json @@ -1,19 +1,19 @@ { - "name": "JSON Feed", - "description": "Indicators feed from a JSON file", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-03-09T16:04:45Z", - "categories": [ - "Data Enrichment & Threat Intelligence" - ], - "tags": [], - "useCases": [], - "keywords": [ - "JSON", - "Feed" - ] + "name": "JSON Feed", + "description": "Indicators feed from a JSON file", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-03-09T16:04:45Z", + "categories": [ + "Data Enrichment & Threat Intelligence" + ], + "tags": [], + "useCases": [], + "keywords": [ + "JSON", + "Feed" + ] } \ No newline at end of file diff --git a/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.py b/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.py index ceb620e49d19..d68f975342b9 100644 --- a/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.py +++ b/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.py @@ -1,4 +1,15 @@ +import demistomock as demisto +from CommonServerPython import * + + def main(): + params = demisto.params() + # when auto_detect is not selected + if params.get('auto_detect_type') is False and not params.get('indicator_type'): + return_error('Indicator Type cannot be empty when Auto Detect Indicator Type is unchecked') + # when auto_detect does not exist - for previous integration instances + if params.get('auto_detect_type') is None and not params.get('indicator_type'): + return_error('Indicator Type cannot be empty') feed_main('PlainText', prefix='plaintext') diff --git a/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.yml b/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.yml index 1e91b035a714..22edb82ca14a 100644 --- a/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.yml +++ b/Packs/FeedPlainText/Integrations/FeedPlainText/FeedPlainText.yml @@ -18,7 +18,13 @@ configuration: name: credentials required: false type: 9 -- additionalinfo: Type of indicator in the feed. +- additionalinfo: If selected, the indicator type will be auto detected for each indicator. + defaultvalue: 'true' + display: Auto detect indicator type + name: auto_detect_type + required: false + type: 8 +- additionalinfo: Type of the indicator in the feed. If auto-detect is checked then the value set as Indicator Type will be ignored. display: Indicator Type name: indicator_type options: @@ -157,7 +163,7 @@ script: required: false secret: false - default: false - description: The indicator type. + description: The indicator type. If the configuration parameter 'Auto detect indicator type' is marked true for the integration instance, then this value will be ignored. isArray: false name: indicator_type required: false @@ -166,7 +172,7 @@ script: description: Gets indicators from the feed. execution: false name: plaintext-get-indicators - dockerimage: demisto/python3:3.8.2.6981 + dockerimage: demisto/jmespath:1.0.0.6980 feed: true isfetch: false longRunning: false diff --git a/Packs/FeedPlainText/ReleaseNotes/1_0_1.md b/Packs/FeedPlainText/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..276c5787f673 --- /dev/null +++ b/Packs/FeedPlainText/ReleaseNotes/1_0_1.md @@ -0,0 +1,4 @@ + +### Integrations +- __Plain Text Feed__ + - Changed the docker image to support auto-detection function. \ No newline at end of file diff --git a/Packs/FeedPlainText/pack_metadata.json b/Packs/FeedPlainText/pack_metadata.json index 96f2b75401db..b4f3a2e1a599 100644 --- a/Packs/FeedPlainText/pack_metadata.json +++ b/Packs/FeedPlainText/pack_metadata.json @@ -1,16 +1,16 @@ { - "name": "Plain Text Feed", - "description": "Fetches indicators from a plain text feed.", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-03-09T16:35:16Z", - "categories": [ - "Data Enrichment & Threat Intelligence" - ], - "tags": [], - "useCases": [], - "keywords": [] + "name": "Plain Text Feed", + "description": "Fetches indicators from a plain text feed.", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-03-09T16:35:16Z", + "categories": [ + "Data Enrichment & Threat Intelligence" + ], + "tags": [], + "useCases": [], + "keywords": [] } \ No newline at end of file diff --git a/Tests/conf.json b/Tests/conf.json index 3ddc652c604f..202bc1bd1ada 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -66,7 +66,15 @@ { "integrations": "JSON Feed", "playbookID": "JSON_Feed_Test", - "fromversion": "5.5.0" + "fromversion": "5.5.0", + "instance_names": "JSON Feed no_auto_detect" + + }, + { + "integrations": "JSON Feed", + "playbookID": "JSON_Feed_Test", + "fromversion": "5.5.0", + "instance_names": "JSON Feed_auto_detect" }, { "integrations": "Google Cloud Functions", @@ -76,7 +84,14 @@ { "integrations": "Plain Text Feed", "playbookID": "PlainText Feed - Test", - "fromversion": "5.5.0" + "fromversion": "5.5.0", + "instance_names": "Plain Text Feed no_auto_detect" + }, + { + "integrations": "Plain Text Feed", + "playbookID": "PlainText Feed - Test", + "fromversion": "5.5.0", + "instance_names": "Plain Text Feed_auto_detect" }, { "integrations": "Silverfort", @@ -156,7 +171,14 @@ { "integrations": "CSVFeed", "playbookID": "CSV_Feed_Test", - "fromversion": "5.5.0" + "fromversion": "5.5.0", + "instance_names": "CSVFeed_no_auto_detect" + }, + { + "integrations": "CSVFeed", + "playbookID": "CSV_Feed_Test", + "fromversion": "5.5.0", + "instance_names": "CSVFeed_auto_detect" }, { "integrations": "ProofpointFeed", From 4ba778cd8cd5f215ae0bf0e845d54baf91ab4074 Mon Sep 17 00:00:00 2001 From: roysagi <50295826+roysagi@users.noreply.github.com> Date: Tue, 9 Jun 2020 12:25:19 +0300 Subject: [PATCH 007/200] small fix in content (#7462) --- Packs/DeprecatedContent/.pack-ignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Packs/DeprecatedContent/.pack-ignore b/Packs/DeprecatedContent/.pack-ignore index 5a6e669ea291..fef8dc5d6afd 100644 --- a/Packs/DeprecatedContent/.pack-ignore +++ b/Packs/DeprecatedContent/.pack-ignore @@ -153,3 +153,9 @@ ignore=BA101 [file:Access_Investigation_-_Generic.yml] ignore=BA101 + +[file:playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response.yml] +ignore=BA101 + +[file:playbook-Search_Endpoints_By_Hash_-_Generic_4_5.yml] +ignore=BA101 From 6310edb00ebeecb4040c4094825e22d5bf5b7169 Mon Sep 17 00:00:00 2001 From: roysagi <50295826+roysagi@users.noreply.github.com> Date: Tue, 9 Jun 2020 12:34:27 +0300 Subject: [PATCH 008/200] unskipping phishlabs (#7455) * unskipping phishlabs * fixing test playbook --- .../TestPlaybooks/playbook-PhishLabsIOC_TestPlaybook.yml | 2 +- Tests/conf.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Packs/PhishLabs/TestPlaybooks/playbook-PhishLabsIOC_TestPlaybook.yml b/Packs/PhishLabs/TestPlaybooks/playbook-PhishLabsIOC_TestPlaybook.yml index f1af1d7e0fd9..0ef2a914ea23 100644 --- a/Packs/PhishLabs/TestPlaybooks/playbook-PhishLabsIOC_TestPlaybook.yml +++ b/Packs/PhishLabs/TestPlaybooks/playbook-PhishLabsIOC_TestPlaybook.yml @@ -350,7 +350,7 @@ tasks: remove_protocol: {} remove_query: {} since: - simple: 365d + simple: 720d separatecontext: false view: |- { diff --git a/Tests/conf.json b/Tests/conf.json index 202bc1bd1ada..a9abf1a7f4a8 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -2850,7 +2850,6 @@ "Prisma_Access-Test": "unskip after we will get PrismaAccess instance", "PAN-OS EDL Setup V2 Test": "Issue 23854", "PAN-OS - Block IP and URL - External Dynamic List Test": "Issue 23854", - "PhishLabsIOC TestPlaybook": "integration bug (23926)", "Symantec Deepsight Test": "Issue 22971", "Akamai_WAF_SIEM-Test": "Issue 22225", "test_MsGraphFiles": "Issue 22853 ", From 17bdd88c048ef3169a39debf51bdd37aa4646b6b Mon Sep 17 00:00:00 2001 From: Bar Hochman <11165655+jochman@users.noreply.github.com> Date: Tue, 9 Jun 2020 15:07:17 +0300 Subject: [PATCH 009/200] RTIR: fix ID header bug (#7453) * RTIR: Fix ID header * fix lint and format * fix flake8 * added rns * fix cr * Update 1_0_2.md Co-authored-by: roysagi <50295826+roysagi@users.noreply.github.com> --- Packs/RTIR/Integrations/RTIR/RTIR.py | 148 ++++++++++++---------- Packs/RTIR/Integrations/RTIR/RTIR.yml | 1 + Packs/RTIR/Integrations/RTIR/RTIR_test.py | 41 +++++- Packs/RTIR/ReleaseNotes/1_0_2.md | 4 + Packs/RTIR/pack_metadata.json | 30 ++--- 5 files changed, 139 insertions(+), 85 deletions(-) create mode 100644 Packs/RTIR/ReleaseNotes/1_0_2.md diff --git a/Packs/RTIR/Integrations/RTIR/RTIR.py b/Packs/RTIR/Integrations/RTIR/RTIR.py index 0a0e4540acff..556ed8928584 100644 --- a/Packs/RTIR/Integrations/RTIR/RTIR.py +++ b/Packs/RTIR/Integrations/RTIR/RTIR.py @@ -2,35 +2,25 @@ ''' IMPORTS ''' import requests -import os import json import re import urllib -if not demisto.params()['proxy']: - del os.environ['HTTP_PROXY'] - del os.environ['HTTPS_PROXY'] - del os.environ['http_proxy'] - del os.environ['https_proxy'] - -# disable insecure warnings -requests.packages.urllib3.disable_warnings() - ''' GLOBAL VARS ''' -SERVER = demisto.params()['server'][:-1] if demisto.params()['server'].endswith('/') else demisto.params()['server'] -USERNAME = demisto.params()['credentials']['identifier'] -PASSWORD = demisto.params()['credentials']['password'] -BASE_URL = SERVER + '/REST/1.0/' -USE_SSL = not demisto.params().get('unsecure', False) -FETCH_PRIORITY = int(demisto.params()['fetch_priority']) - 1 -FETCH_STATUS = demisto.params()['fetch_status'] -FETCH_QUEUE = demisto.params()['fetch_queue'] +SERVER = None +BASE_URL = None +USERNAME = None +PASSWORD = None +USE_SSL = None +FETCH_PRIORITY = 0 +FETCH_STATUS = None +FETCH_QUEUE = None CURLY_BRACKETS_REGEX = r'\{(.*?)\}' # Extracts string in curly brackets, e.g. '{string}' -> 'string' apostrophe = "'" SESSION = requests.session() SESSION.verify = USE_SSL -REFERER = demisto.params().get('referer') -HEADERS = {'Referer': REFERER} if REFERER else {} +REFERER = None +HEADERS = {'Referer': REFERER} if REFERER else {} # type: dict ''' HELPER FUNCTIONS ''' @@ -123,15 +113,7 @@ def parse_ticket_data(raw_query): id_ticket = search_ticket[0].upper() search_ticket[0] = id_ticket - current_ticket_search = {} - for entity in search_ticket: - if ': ' in entity: - header, content = entity.split(': ', 1) - if 'ID' in header: - content = ticket_string_to_id(content) - if header in {'ID', 'Subject', 'Status', 'Priority', 'Created', 'Queue', 'Creator', 'Owner', - 'InitialPriority', 'FinalPriority'}: - current_ticket_search[header] = content + current_ticket_search = build_ticket(search_ticket) for key in search_ticket: # Adding ticket custom fields to outputs if key.startswith('CF.'): @@ -334,6 +316,19 @@ def build_search_query(): return raw_query +def build_ticket(rtir_search_ticket): + current_ticket_search = {} + for entity in rtir_search_ticket: + if ': ' in entity: + header, content = entity.split(': ', 1) + if 'ID' == header: + content = ticket_string_to_id(content) + if header in {'ID', 'Subject', 'Status', 'Priority', 'Created', 'Queue', 'Creator', 'Owner', + 'InitialPriority', 'FinalPriority'}: + current_ticket_search[header] = content + return current_ticket_search + + def search_ticket(): raw_query = build_search_query() @@ -358,15 +353,7 @@ def search_ticket(): else: search_ticket = empty_line_response - current_ticket_search = {} - for entity in search_ticket: - if ': ' in entity: - header, content = entity.split(': ', 1) - if 'ID' in header: - content = ticket_string_to_id(content) - if header in {'ID', 'Subject', 'Status', 'Priority', 'Created', 'Queue', 'Creator', 'Owner', - 'InitialPriority', 'FinalPriority'}: - current_ticket_search[header] = content + current_ticket_search = build_ticket(search_ticket) for key in search_ticket: # Adding ticket custom fields to outputs if key.startswith('CF.'): @@ -876,44 +863,69 @@ def fetch_incidents(): ''' EXECUTION CODE ''' -LOG('command is %s' % (demisto.command(),)) -try: - if demisto.command() == 'test-module': - login() - logout() - demisto.results('ok') - if demisto.command() in {'fetch-incidents'}: - fetch_incidents() +def main(): + handle_proxy() + + # disable insecure warnings + requests.packages.urllib3.disable_warnings() + + ''' GLOBAL VARS ''' + global SERVER, USERNAME, PASSWORD, BASE_URL, USE_SSL, FETCH_PRIORITY, FETCH_STATUS, FETCH_QUEUE, HEADERS, REFERER + SERVER = demisto.params().get('server', '')[:-1] if demisto.params().get('server', '').endswith( + '/') else demisto.params().get('server', '') + USERNAME = demisto.params()['credentials']['identifier'] + PASSWORD = demisto.params()['credentials']['password'] + BASE_URL = urljoin(SERVER, '/REST/1.0/') + USE_SSL = not demisto.params().get('unsecure', False) + FETCH_PRIORITY = int(demisto.params()['fetch_priority']) - 1 + FETCH_STATUS = demisto.params()['fetch_status'] + FETCH_QUEUE = demisto.params()['fetch_queue'] + REFERER = demisto.params().get('referer') + HEADERS = {'Referer': REFERER} if REFERER else {} + + LOG('command is %s' % (demisto.command(),)) + try: + if demisto.command() == 'test-module': + login() + logout() + demisto.results('ok') + + if demisto.command() in {'fetch-incidents'}: + fetch_incidents() + + elif demisto.command() == 'rtir-create-ticket': + create_ticket() + + elif demisto.command() == 'rtir-search-ticket': + search_ticket() - elif demisto.command() == 'rtir-create-ticket': - create_ticket() + elif demisto.command() == 'rtir-resolve-ticket': + close_ticket() - elif demisto.command() == 'rtir-search-ticket': - search_ticket() + elif demisto.command() == 'rtir-edit-ticket': + edit_ticket() - elif demisto.command() == 'rtir-resolve-ticket': - close_ticket() + elif demisto.command() == 'rtir-ticket-history': + get_ticket_history_command() - elif demisto.command() == 'rtir-edit-ticket': - edit_ticket() + elif demisto.command() == 'rtir-ticket-attachments': + get_ticket_attachments_command() - elif demisto.command() == 'rtir-ticket-history': - get_ticket_history_command() + elif demisto.command() == 'rtir-get-ticket': + get_ticket() - elif demisto.command() == 'rtir-ticket-attachments': - get_ticket_attachments_command() + elif demisto.command() == 'rtir-add-comment': + add_comment() - elif demisto.command() == 'rtir-get-ticket': - get_ticket() + elif demisto.command() == 'rtir-add-reply': + add_reply() - elif demisto.command() == 'rtir-add-comment': - add_comment() + except Exception, e: + LOG(e.message) + LOG.print_log() + raise - elif demisto.command() == 'rtir-add-reply': - add_reply() -except Exception, e: - LOG(e.message) - LOG.print_log() - raise +if __name__ in ('__builtin__', 'builtins'): + main() diff --git a/Packs/RTIR/Integrations/RTIR/RTIR.yml b/Packs/RTIR/Integrations/RTIR/RTIR.yml index 7bc96b74a862..f5a34492ee86 100644 --- a/Packs/RTIR/Integrations/RTIR/RTIR.yml +++ b/Packs/RTIR/Integrations/RTIR/RTIR.yml @@ -585,3 +585,4 @@ script: subtype: python2 tests: - RTIR Test +fromversion: 4.1.0 diff --git a/Packs/RTIR/Integrations/RTIR/RTIR_test.py b/Packs/RTIR/Integrations/RTIR/RTIR_test.py index e99b2ceaac88..af1f6c738b54 100644 --- a/Packs/RTIR/Integrations/RTIR/RTIR_test.py +++ b/Packs/RTIR/Integrations/RTIR/RTIR_test.py @@ -5,8 +5,8 @@ class DotDict(dict): """dot.notation access to dictionary attributes""" __getattr__ = dict.get - __setattr__ = dict.__setitem__ - __delattr__ = dict.__delitem__ + __setattr__ = dict.__setitem__ # noqa: type: ignore[assignment] + __delattr__ = dict.__delitem__ # noqa: type: ignore[assignment] def test_query_formatting(mocker): @@ -90,3 +90,40 @@ def test_parse_ticket_links(): response = parse_ticket_links(RAW_LINKS) expected = [{'ID': '65461'}, {'ID': '65462'}, {'ID': '65463'}] assert response == expected + + +def test_build_ticket_id_in_headers(): + """ + + Given: + - A ticket containing 'ID' in its keys + + When: + - building a search ticket + + Then: + - Validate the ticket ID parsed correctly + + """ + from RTIR import build_ticket + ticket = build_ticket(['ID: ticket/1']) + expected = {'ID': 1} + assert expected == ticket + + +def test_build_ticket_contains_id_in_headers(): + """ + + Given: + - A ticket contains a key with 'ID' substring. + + When: + - building a search ticket + + Then: + - Validate nothing returns + + """ + from RTIR import build_ticket + ticket = build_ticket(['ThisIsAID: ofNotID']) + assert {} == ticket diff --git a/Packs/RTIR/ReleaseNotes/1_0_2.md b/Packs/RTIR/ReleaseNotes/1_0_2.md new file mode 100644 index 000000000000..952267025790 --- /dev/null +++ b/Packs/RTIR/ReleaseNotes/1_0_2.md @@ -0,0 +1,4 @@ + +#### Integrations +- __RTIR__ +Fixed an issue where headers with 'ID' in their name got malformed when running ***rtir-search-ticket*** command and in ***fetch-incidents***. diff --git a/Packs/RTIR/pack_metadata.json b/Packs/RTIR/pack_metadata.json index 0a11202699bb..de8efcee15bf 100644 --- a/Packs/RTIR/pack_metadata.json +++ b/Packs/RTIR/pack_metadata.json @@ -1,16 +1,16 @@ { - "name": "RTIR", - "description": "Request Tracker for Incident Response is a ticketing system which provides pre-configured queues and workflows designed for incident response teams.", - "support": "xsoar", - "currentVersion": "1.0.1", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-04-14T00:00:00Z", - "categories": [ - "Case Management" - ], - "tags": [], - "useCases": [], - "keywords": [] -} + "name": "RTIR", + "description": "Request Tracker for Incident Response is a ticketing system which provides pre-configured queues and workflows designed for incident response teams.", + "support": "xsoar", + "currentVersion": "1.0.2", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-04-14T00:00:00Z", + "categories": [ + "Case Management" + ], + "tags": [], + "useCases": [], + "keywords": [] +} \ No newline at end of file From 9df8ad40aadc2a296d6f0536f34e368aa2ffffd2 Mon Sep 17 00:00:00 2001 From: Guy Freund <53565845+guyfreund@users.noreply.github.com> Date: Tue, 9 Jun 2020 15:50:49 +0300 Subject: [PATCH 010/200] fortisiem bug fix (#7469) * disabled the request to trigger an event, made queryData hardcoded * changelog * Updated. * Updated * Updated Co-authored-by: Alex Fiedler <38628621+kirbles19@users.noreply.github.com> --- .../Integrations/FortiSIEM/CHANGELOG.md | 3 +- .../Integrations/FortiSIEM/FortiSIEM.py | 33 ++++++++++++++----- Packs/FortiSIEM/ReleaseNotes/1_0_0.md | 3 +- Packs/FortiSIEM/ReleaseNotes/1_0_1.md | 4 +++ Packs/FortiSIEM/pack_metadata.json | 30 ++++++++--------- 5 files changed, 46 insertions(+), 27 deletions(-) create mode 100644 Packs/FortiSIEM/ReleaseNotes/1_0_1.md diff --git a/Packs/FortiSIEM/Integrations/FortiSIEM/CHANGELOG.md b/Packs/FortiSIEM/Integrations/FortiSIEM/CHANGELOG.md index 955e7af772c2..c47817688669 100644 --- a/Packs/FortiSIEM/Integrations/FortiSIEM/CHANGELOG.md +++ b/Packs/FortiSIEM/Integrations/FortiSIEM/CHANGELOG.md @@ -1,5 +1,6 @@ ## [Unreleased] -Fixed an issue where the authentication did not work properly. + - Fixed an issue where the authentication did not work properly. + - Fixed an issue where the ***fortisiem-get-events-by-incident*** command did not return results. ## [20.5.0] - 2020-05-12 diff --git a/Packs/FortiSIEM/Integrations/FortiSIEM/FortiSIEM.py b/Packs/FortiSIEM/Integrations/FortiSIEM/FortiSIEM.py index a20cc7996c1a..1a7751d32a76 100644 --- a/Packs/FortiSIEM/Integrations/FortiSIEM/FortiSIEM.py +++ b/Packs/FortiSIEM/Integrations/FortiSIEM/FortiSIEM.py @@ -132,15 +132,30 @@ def clear_incident(incident_id, reason): @logger def getEventsByIncident(incident_id, max_results, extended_data, max_wait_time): session = login() - response = session.get(HOST + '/phoenix/rest/h5/report/triggerEvent?rawMsg=' + incident_id) - validateSuccessfulResponse(response, "triggering events report") - - try: - jsonRes = response.json() - queryData = jsonRes[0]['right'] - except (ValueError, KeyError): - return_error("Got wrong response format when triggering events report. " - "Expected a json array but got:\n" + response.text) + # response = session.get(HOST + '/phoenix/rest/h5/report/triggerEvent?rawMsg=' + incident_id) + # validateSuccessfulResponse(response, "triggering events report") + # + # try: + # jsonRes = response.json() + # queryData = jsonRes[0]['right'] + # except (ValueError, KeyError): + # return_error("Got wrong response format when triggering events report. " + # "Expected a json array but got:\n" + response.text) + + queryData = { + "isReportService": True, + "selectClause": "eventSeverityCat,incidentLastSeen,eventName,incidentRptDevName,incidentSrc,incidentTarget," + "incidentDetail,incidentStatus,incidentReso,incidentId,eventType,incidentTicketStatus," + "bizService,count,incidentClearedTime,incidentTicketUser,incidentNotiRecipients," + "incidentClearedReason,incidentComments,eventSeverity,incidentFirstSeen,incidentRptIp," + "incidentTicketId,customer,incidentNotiStatus,incidentClearedUser,incidentExtUser," + "incidentExtClearedTime,incidentExtResoTime,incidentExtTicketId,incidentExtTicketState," + "incidentExtTicketType,incidentViewStatus,rawEventMsg,phIncidentCategory,phSubIncidentCategory," + "incidentRptDevStatus", + "eventFilters": [{"name": "Filter_OVERALL_STATUS", + "singleConstraint": "(phEventCategory = 1) AND incidentId = {}".format(incident_id)}], + "hints": "IgnoreTime", + } return getEventsByQuery(session, queryData, max_results, extended_data, max_wait_time, "FortiSIEM events for Incident " + incident_id, incident_id=incident_id) diff --git a/Packs/FortiSIEM/ReleaseNotes/1_0_0.md b/Packs/FortiSIEM/ReleaseNotes/1_0_0.md index c6755098e333..4590a74731e9 100644 --- a/Packs/FortiSIEM/ReleaseNotes/1_0_0.md +++ b/Packs/FortiSIEM/ReleaseNotes/1_0_0.md @@ -1,5 +1,4 @@ -### Integrations +#### Integrations - __FortiSIEM__ Fixed an issue where the authentication did not work properly. - diff --git a/Packs/FortiSIEM/ReleaseNotes/1_0_1.md b/Packs/FortiSIEM/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..77eb678f4f75 --- /dev/null +++ b/Packs/FortiSIEM/ReleaseNotes/1_0_1.md @@ -0,0 +1,4 @@ + +#### Integrations +- __FortiSIEM__ +Fixed an issue where the ***fortisiem-get-events-by-incident*** command did not return results. diff --git a/Packs/FortiSIEM/pack_metadata.json b/Packs/FortiSIEM/pack_metadata.json index fae96c74107e..cf004d879caa 100644 --- a/Packs/FortiSIEM/pack_metadata.json +++ b/Packs/FortiSIEM/pack_metadata.json @@ -1,16 +1,16 @@ { - "name": "FortiSIEM", - "description": "Search and update events of FortiSIEM and manage resource lists.", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-04-14T00:00:00Z", - "categories": [ - "Analytics & SIEM" - ], - "tags": [], - "useCases": [], - "keywords": [] -} + "name": "FortiSIEM", + "description": "Search and update events of FortiSIEM and manage resource lists.", + "support": "xsoar", + "currentVersion": "1.0.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-04-14T00:00:00Z", + "categories": [ + "Analytics & SIEM" + ], + "tags": [], + "useCases": [], + "keywords": [] +} \ No newline at end of file From a54d5529af47d3241fb8e7ffd6654ea9cd18ea82 Mon Sep 17 00:00:00 2001 From: Anar Azadaliyev Date: Tue, 9 Jun 2020 16:11:10 +0300 Subject: [PATCH 011/200] remove old regexes from content (#7398) * remove old regexes from content * use demisto-sdk from master * Update dev-requirements-py3.txt Co-authored-by: reut shalem <50294648+reutshal@users.noreply.github.com> * Update dev-requirements-py3.txt * replace old regexes * sdk release 1-1-2 test * sdk release 1-1-2 test * sdk release 1-1-2 test * sdk release 1-1-2 Co-authored-by: reut shalem <50294648+reutshal@users.noreply.github.com> Co-authored-by: rshalem --- ...onfigure_and_test_integration_instances.py | 5 +-- .../collect_tests_and_content_packs.py | 33 ++++++++----------- Tests/scripts/validate.sh | 6 +++- dev-requirements-py3.txt | 4 +-- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/Tests/configure_and_test_integration_instances.py b/Tests/configure_and_test_integration_instances.py index 10f432da2881..877144cfc0df 100644 --- a/Tests/configure_and_test_integration_instances.py +++ b/Tests/configure_and_test_integration_instances.py @@ -15,14 +15,12 @@ from demisto_sdk.commands.common.tools import print_error, print_warning, print_color, LOG_COLORS, run_threads_list, \ run_command, get_last_release_version, checked_type, get_yaml, str2bool, server_version_compare from demisto_sdk.commands.validate.file_validator import FilesValidator -from demisto_sdk.commands.common.constants import YML_INTEGRATION_REGEXES, INTEGRATION_REGEX, PACKS_INTEGRATION_REGEX, \ - BETA_INTEGRATION_REGEX, RUN_ALL_TESTS_FORMAT +from demisto_sdk.commands.common.constants import YML_INTEGRATION_REGEXES, RUN_ALL_TESTS_FORMAT from Tests.test_integration import __get_integration_config, __test_integration_instance, \ __disable_integrations_instances from Tests.test_content import load_conf_files, extract_filtered_tests, ParallelPrintsManager, \ get_server_numeric_version - from Tests.update_content_data import update_content from Tests.Marketplace.search_and_install_packs import search_and_install_packs_and_their_dependencies @@ -198,7 +196,6 @@ def get_new_and_modified_integration_files(git_sha1): change_log = run_command('git diff --name-status {}'.format(git_sha1)) modified_files, added_files, _, _ = file_validator.get_modified_files(change_log, tag) all_integration_regexes = YML_INTEGRATION_REGEXES - all_integration_regexes.extend([INTEGRATION_REGEX, PACKS_INTEGRATION_REGEX, BETA_INTEGRATION_REGEX]) new_integration_files = [ file_path for file_path in added_files if checked_type(file_path, all_integration_regexes) diff --git a/Tests/scripts/collect_tests_and_content_packs.py b/Tests/scripts/collect_tests_and_content_packs.py index 5f91b3ad0003..a71737907f50 100755 --- a/Tests/scripts/collect_tests_and_content_packs.py +++ b/Tests/scripts/collect_tests_and_content_packs.py @@ -4,7 +4,6 @@ Overview can be found at: https://confluence.paloaltonetworks.com/display/DemistoContent/Configure+Test+Filter """ import os -import re import sys import json import glob @@ -34,9 +33,8 @@ TEST_DATA_INTEGRATION_YML_REGEX = r'Tests\/scripts\/infrastructure_tests\/tests_data\/mock_integrations\/.*\.yml' INTEGRATION_REGEXES = [ - INTEGRATION_REGEX, - BETA_INTEGRATION_REGEX, - PACKS_INTEGRATION_REGEX, + PACKS_INTEGRATION_PY_REGEX, + PACKS_INTEGRATION_PS_TEST_REGEX, TEST_DATA_INTEGRATION_YML_REGEX ] TEST_DATA_SCRIPT_YML_REGEX = r'Tests/scripts/infrastructure_tests/tests_data/mock_scripts/.*.yml' @@ -44,8 +42,7 @@ TEST_DATA_SCRIPT_YML_REGEX ] INCIDENT_FIELD_REGEXES = [ - INCIDENT_FIELD_REGEX, - PACKS_INCIDENT_FIELDS_REGEX + PACKS_INCIDENT_FIELD_JSON_REGEX ] FILES_IN_SCRIPTS_OR_INTEGRATIONS_DIRS_REGEXES = [ FILE_IN_INTEGRATIONS_DIR_REGEX, @@ -55,20 +52,19 @@ ] CHECKED_TYPES_REGEXES = [ # Integrations - INTEGRATION_REGEX, - INTEGRATION_YML_REGEX, - BETA_INTEGRATION_REGEX, - PACKS_INTEGRATION_REGEX, + PACKS_INTEGRATION_PY_REGEX, PACKS_INTEGRATION_YML_REGEX, + PACKS_INTEGRATION_NON_SPLIT_YML_REGEX, + PACKS_INTEGRATION_PS_REGEX, + # Scripts - SCRIPT_REGEX, - SCRIPT_YML_REGEX, PACKS_SCRIPT_REGEX, PACKS_SCRIPT_YML_REGEX, + PACKS_SCRIPT_NON_SPLIT_YML_REGEX, + # Playbooks PLAYBOOK_REGEX, - BETA_PLAYBOOK_REGEX, - PACKS_PLAYBOOK_YML_REGEX + PLAYBOOK_YML_REGEX ] # File names @@ -159,8 +155,7 @@ def get_modified_files(files_string): # reputations.json elif re.match(INDICATOR_TYPES_REPUTATIONS_REGEX, file_path, re.IGNORECASE) or \ re.match(PACKS_INDICATOR_TYPES_REPUTATIONS_REGEX, file_path, re.IGNORECASE) or \ - re.match(INDICATOR_TYPES_REGEX, file_path, re.IGNORECASE) or \ - re.match(PACKS_INDICATOR_TYPES_REGEX, file_path, re.IGNORECASE): + re.match(PACKS_INDICATOR_TYPE_JSON_REGEX, file_path, re.IGNORECASE): is_reputations_json = True elif checked_type(file_path, INCIDENT_FIELD_REGEXES): @@ -870,7 +865,7 @@ def get_test_conf_from_conf(test_id, server_version, conf=None): # return None if nothing is found test_conf = next((test_conf for test_conf in test_conf_lst if ( test_conf.get('playbookID') == test_id - and is_runnable_in_server_version(from_v=test_conf.get('fromversion', '0'), + and is_runnable_in_server_version(from_v=test_conf.get('fromversion', '0.0'), server_v=server_version, to_v=test_conf.get('toversion', '99.99.99')) )), None) @@ -894,7 +889,7 @@ def extract_matching_object_from_id_set(obj_id, obj_set, server_version='0'): continue # check if object is runnable - fromversion = obj.get('fromversion', '0') + fromversion = obj.get('fromversion', '0.0') toversion = obj.get('toversion', '99.99.99') if is_runnable_in_server_version(from_v=fromversion, server_v=server_version, to_v=toversion): return obj @@ -962,7 +957,7 @@ def is_test_runnable(test_id, id_set, conf, server_version): if not test_conf: print_warning(f'{warning_prefix} - couldn\'t find test in conf.json') return False - conf_fromversion = test_conf.get('fromversion', '0') + conf_fromversion = test_conf.get('fromversion', '0.0') conf_toversion = test_conf.get('toversion', '99.99.99') test_playbooks_set = id_set.get('TestPlaybooks', []) test_playbook_obj = extract_matching_object_from_id_set(test_id, test_playbooks_set, server_version) diff --git a/Tests/scripts/validate.sh b/Tests/scripts/validate.sh index 58927ad40c12..958a53f4bdc6 100755 --- a/Tests/scripts/validate.sh +++ b/Tests/scripts/validate.sh @@ -1,7 +1,11 @@ #!/usr/bin/env bash set -e -if [ "${CHECK_BACKWARD}" = "true" ] ; +if [[ $CIRCLE_BRANCH = master ]]; + then + demisto-sdk validate -a + +elif [ "${CHECK_BACKWARD}" = "true" ] ; then demisto-sdk validate -g --post-commit diff --git a/dev-requirements-py3.txt b/dev-requirements-py3.txt index 2c5f5f4c4088..b05ea822fe3e 100644 --- a/dev-requirements-py3.txt +++ b/dev-requirements-py3.txt @@ -1,7 +1,7 @@ flake8==3.7.9 bandit==1.6.2 demisto-py==2.0.11 -demisto-sdk==1.1.1 +demisto-sdk==1.1.2 pytest==5.2.1 pytest-mock==1.11.1 requests-mock==1.7.0 @@ -14,4 +14,4 @@ beautifulsoup4==4.8.1 pypdf2==1.26.0 freezegun==0.3.12 vulture==1.5 -git+https://github.com/coyo8/parinx.git@6493798ceba8089345d970f71be4a896eb6b081d +git+https://github.com/coyo8/parinx.git@6493798ceba8089345d970f71be4a896eb6b081d \ No newline at end of file From 3493acf5fca856b365a8c8c0c578fe5b32528acc Mon Sep 17 00:00:00 2001 From: roysagi <50295826+roysagi@users.noreply.github.com> Date: Tue, 9 Jun 2020 19:14:41 +0300 Subject: [PATCH 012/200] changing playbook name (#7474) * changing playbook name * changing playbook name --- ...> playbook-SANS_-_Incident_Handlers_Handbook_Template.yml} | 0 ...k-SANS_-_Incident_Handlers_Handbook_Template_CHANGELOG.md} | 4 ++-- ...book-SANS_-_Incident_Handlers_Handbook_Template_README.md} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename Packs/SANS/Playbooks/{playbook-SANS_-_Incident_Handler's_Handbook_Template.yml => playbook-SANS_-_Incident_Handlers_Handbook_Template.yml} (100%) rename Packs/SANS/Playbooks/{playbook-SANS_-_Incident_Handler's_Handbook_Template_CHANGELOG.md => playbook-SANS_-_Incident_Handlers_Handbook_Template_CHANGELOG.md} (96%) rename Packs/SANS/Playbooks/{playbook-SANS_-_Incident_Handler's_Handbook_Template_README.md => playbook-SANS_-_Incident_Handlers_Handbook_Template_README.md} (100%) diff --git a/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handler's_Handbook_Template.yml b/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handlers_Handbook_Template.yml similarity index 100% rename from Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handler's_Handbook_Template.yml rename to Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handlers_Handbook_Template.yml diff --git a/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handler's_Handbook_Template_CHANGELOG.md b/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handlers_Handbook_Template_CHANGELOG.md similarity index 96% rename from Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handler's_Handbook_Template_CHANGELOG.md rename to Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handlers_Handbook_Template_CHANGELOG.md index 1d988fa806e7..4afaa8cfafa9 100644 --- a/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handler's_Handbook_Template_CHANGELOG.md +++ b/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handlers_Handbook_Template_CHANGELOG.md @@ -1,5 +1,5 @@ ## [Unreleased] - +- ## [20.5.0] - 2020-05-12 - @@ -11,4 +11,4 @@ This playbook contains the phases for handling an incident as they are described https://www.sans.org/reading-room/whitepapers/incident/incident-handlers-handbook-33901 -***Disclaimer: This playbook does not ensure compliance to SANS regulations. \ No newline at end of file +***Disclaimer: This playbook does not ensure compliance to SANS regulations. diff --git a/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handler's_Handbook_Template_README.md b/Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handlers_Handbook_Template_README.md similarity index 100% rename from Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handler's_Handbook_Template_README.md rename to Packs/SANS/Playbooks/playbook-SANS_-_Incident_Handlers_Handbook_Template_README.md From 80d8916bb260e3ee23d39309b08cf64f1f4aad0b Mon Sep 17 00:00:00 2001 From: yuvalbenshalom Date: Tue, 9 Jun 2020 20:29:32 +0300 Subject: [PATCH 013/200] fix rastarize name in core packs list (#7471) --- Tests/Marketplace/marketplace_services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Marketplace/marketplace_services.py b/Tests/Marketplace/marketplace_services.py index 7ed38c85c987..9f348e72f71c 100644 --- a/Tests/Marketplace/marketplace_services.py +++ b/Tests/Marketplace/marketplace_services.py @@ -37,7 +37,7 @@ class GCPConfig(object): INDEX_NAME = "index" # main index folder name CORE_PACK_FILE_NAME = "corepacks.json" # core packs file name CORE_PACKS_LIST = [BASE_PACK, - "Rasterize", + "rasterize", "DemistoRESTAPI", "DemistoLocking", "ImageOCR", From 8c5354dcdeed60e224371e0a58aee797100f967b Mon Sep 17 00:00:00 2001 From: Dan Tavori <38749041+dantavori@users.noreply.github.com> Date: Tue, 9 Jun 2020 20:53:36 +0300 Subject: [PATCH 014/200] Nightly Marketplace (#7467) * remove old regexes from content * use demisto-sdk from master * Update dev-requirements-py3.txt Co-authored-by: reut shalem <50294648+reutshal@users.noreply.github.com> * Update dev-requirements-py3.txt * replace old regexes * use sdk master * conflicts fix * changed sdk branch * changed sdk branch to master * fixed config.yml, added developerTools pack to packs_to_install * reduced flake8 version * moved test playbooks to packs * removed Extract Indicators From File - test from conf.json * reverted changes in collect_tests and dev-requirements-py3 Co-authored-by: Anar Azadaliyev Co-authored-by: reut shalem <50294648+reutshal@users.noreply.github.com> Co-authored-by: ybenshalom Co-authored-by: Shai Yaakovi <30797606+yaakovi@users.noreply.github.com> --- .circleci/config.yml | 8 ++++---- .../playbook-Send-Email-To-Recipients-Test.yml | 0 .../ExifRead/TestPlaybooks}/playbook-ExifReadTest.yml | 0 .../playbook-GCS_Bucket_Management_Test.yml | 0 .../playbook-GCS_Bucket_Policy_(ACL)_Test.yml | 0 .../playbook-GCS_Object_Operations_Test.yml | 0 .../playbook-GCS_Object_Policy_(ACL)_Test.yml | 0 ...book-Palo_Alto_Networks_-_Malware_Remediation_Test.yml | 0 Tests/conf.json | 8 +++++--- 9 files changed, 9 insertions(+), 7 deletions(-) rename {TestPlaybooks/NonCircleTests => Packs/EWS/TestPlaybooks}/playbook-Send-Email-To-Recipients-Test.yml (100%) rename {TestPlaybooks => Packs/ExifRead/TestPlaybooks}/playbook-ExifReadTest.yml (100%) rename {TestPlaybooks/NonCircleTests => Packs/GoogleCloudStorage/TestPlaybooks}/playbook-GCS_Bucket_Management_Test.yml (100%) rename {TestPlaybooks/NonCircleTests => Packs/GoogleCloudStorage/TestPlaybooks}/playbook-GCS_Bucket_Policy_(ACL)_Test.yml (100%) rename {TestPlaybooks/NonCircleTests => Packs/GoogleCloudStorage/TestPlaybooks}/playbook-GCS_Object_Operations_Test.yml (100%) rename {TestPlaybooks/NonCircleTests => Packs/GoogleCloudStorage/TestPlaybooks}/playbook-GCS_Object_Policy_(ACL)_Test.yml (100%) rename {TestPlaybooks => Packs/PANWComprehensiveInvestigation/TestPlaybooks}/playbook-Palo_Alto_Networks_-_Malware_Remediation_Test.yml (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1fc1c2346a60..4bd800667026 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -476,9 +476,9 @@ jobs: echo "Skipping instance tests for forked PRs" exit 0 fi - if [ -n "${INSTANCE_TESTS}" ] || [ $CIRCLE_NODE_INDEX -ne 0 ] ; + if [ -n "${INSTANCE_TESTS}" ] || [ $CIRCLE_NODE_INDEX -ne 0 ] || [ -n "${NIGHTLY}" ]; then - echo "Skipping - not running in INSTANCE_TESTS build or unit-tests container" + echo "Skipping - not running in INSTANCE_TESTS build, unit-tests container or Nightly run" exit 0 fi export TEMP=$(cat ./Tests/filter_envs.json | jq '."Demisto PreGA"') @@ -508,9 +508,9 @@ jobs: echo "Skipping instance tests for forked PRs" exit 0 fi - if [ -n "${INSTANCE_TESTS}" ] || [ $CIRCLE_NODE_INDEX -ne 0 ] || [ -n "${NIGHTLY}" ]; + if [ -n "${INSTANCE_TESTS}" ] || [ $CIRCLE_NODE_INDEX -ne 0 ] ; then - echo "Skipping - not running in INSTANCE_TESTS build, unit-tests container or Nightly run" + echo "Skipping - not running in INSTANCE_TESTS build or unit-tests container" exit 0 fi export TEMP=$(cat ./Tests/filter_envs.json | jq '."Demisto Marketplace"') diff --git a/TestPlaybooks/NonCircleTests/playbook-Send-Email-To-Recipients-Test.yml b/Packs/EWS/TestPlaybooks/playbook-Send-Email-To-Recipients-Test.yml similarity index 100% rename from TestPlaybooks/NonCircleTests/playbook-Send-Email-To-Recipients-Test.yml rename to Packs/EWS/TestPlaybooks/playbook-Send-Email-To-Recipients-Test.yml diff --git a/TestPlaybooks/playbook-ExifReadTest.yml b/Packs/ExifRead/TestPlaybooks/playbook-ExifReadTest.yml similarity index 100% rename from TestPlaybooks/playbook-ExifReadTest.yml rename to Packs/ExifRead/TestPlaybooks/playbook-ExifReadTest.yml diff --git a/TestPlaybooks/NonCircleTests/playbook-GCS_Bucket_Management_Test.yml b/Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Bucket_Management_Test.yml similarity index 100% rename from TestPlaybooks/NonCircleTests/playbook-GCS_Bucket_Management_Test.yml rename to Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Bucket_Management_Test.yml diff --git a/TestPlaybooks/NonCircleTests/playbook-GCS_Bucket_Policy_(ACL)_Test.yml b/Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Bucket_Policy_(ACL)_Test.yml similarity index 100% rename from TestPlaybooks/NonCircleTests/playbook-GCS_Bucket_Policy_(ACL)_Test.yml rename to Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Bucket_Policy_(ACL)_Test.yml diff --git a/TestPlaybooks/NonCircleTests/playbook-GCS_Object_Operations_Test.yml b/Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Object_Operations_Test.yml similarity index 100% rename from TestPlaybooks/NonCircleTests/playbook-GCS_Object_Operations_Test.yml rename to Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Object_Operations_Test.yml diff --git a/TestPlaybooks/NonCircleTests/playbook-GCS_Object_Policy_(ACL)_Test.yml b/Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Object_Policy_(ACL)_Test.yml similarity index 100% rename from TestPlaybooks/NonCircleTests/playbook-GCS_Object_Policy_(ACL)_Test.yml rename to Packs/GoogleCloudStorage/TestPlaybooks/playbook-GCS_Object_Policy_(ACL)_Test.yml diff --git a/TestPlaybooks/playbook-Palo_Alto_Networks_-_Malware_Remediation_Test.yml b/Packs/PANWComprehensiveInvestigation/TestPlaybooks/playbook-Palo_Alto_Networks_-_Malware_Remediation_Test.yml similarity index 100% rename from TestPlaybooks/playbook-Palo_Alto_Networks_-_Malware_Remediation_Test.yml rename to Packs/PANWComprehensiveInvestigation/TestPlaybooks/playbook-Palo_Alto_Networks_-_Malware_Remediation_Test.yml diff --git a/Tests/conf.json b/Tests/conf.json index a9abf1a7f4a8..d47e1c14a51e 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -2814,9 +2814,6 @@ "playbookID": "EvaluateMLModllAtProduction-Test", "fromversion": "4.5.0" }, - { - "playbookID": "Extract Indicators From File - test" - }, { "integrations": "Zabbix", "playbookID": "Zabbix - Test" @@ -2887,6 +2884,11 @@ "Panorama Query Logs - Test": "Issue #23505", "palo_alto_panorama_test_pb": "Issue #22835", "VxStream Test": "Issue #23795", + "GCS Bucket Management - Test": "used in GCS - Test as sub playbook", + "GCS Object Operations - Test": "used in GCS - Test as sub playbook", + "GCS Bucket Policy (ACL) - Test": "used in GCS - Test as sub playbook", + "GCS Object Policy (ACL) - Test": "used in GCS - Test as sub playbook", + "Send Email To Recipients": "used in EWS Mail Sender Test 2 as sub playbook", "_comment": "~~~ DEPRECATED ~~~", "Endpoint Enrichment - Generic v2 - Test": "DEPRECATED" From a4cba0cef8c13c57afa043b5053f82feed314598 Mon Sep 17 00:00:00 2001 From: Bar Hochman <11165655+jochman@users.noreply.github.com> Date: Wed, 10 Jun 2020 00:06:28 +0300 Subject: [PATCH 015/200] bump content and sha1 versions (#7470) --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4bd800667026..ba6b54e49143 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,9 +6,9 @@ jobs: resource_class: medium+ parallelism: 2 environment: - CONTENT_VERSION: "20.5.3" + CONTENT_VERSION: "20.6.0" SERVER_VERSION: "5.5.0" - GIT_SHA1: "bb4ac8b7943a6cba0c22935ebad6b6e17939840d" # guardrails-disable-line disable-secrets-detection + GIT_SHA1: "63646dff0fba977f91d6d9fc2d7fd233bfb5561b" # guardrails-disable-line disable-secrets-detection steps: - checkout - setup_remote_docker From 9c625060d01ff70530458617c0b89b3a73550b12 Mon Sep 17 00:00:00 2001 From: Shai Yaakovi <30797606+yaakovi@users.noreply.github.com> Date: Wed, 10 Jun 2020 07:39:10 +0300 Subject: [PATCH 016/200] reverted instance tests to run on server 5.5 (#7465) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ba6b54e49143..7521cc95ff43 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -352,7 +352,7 @@ jobs: export IFRA_ENV_TYPE=Nightly # disable-secrets-detection elif [ -n "${INSTANCE_TESTS}" ] ; then - export IFRA_ENV_TYPE="Demisto Marketplace" # disable-secrets-detection + export IFRA_ENV_TYPE="Demisto PreGA" # disable-secrets-detection else export IFRA_ENV_TYPE=Content-Env # disable-secrets-detection From 32a8e490ed873b300963797858e06390c498f7c4 Mon Sep 17 00:00:00 2001 From: Bar Hochman <11165655+jochman@users.noreply.github.com> Date: Wed, 10 Jun 2020 10:08:58 +0300 Subject: [PATCH 017/200] Return of cofense feed (#7481) --- Tests/conf.json | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/conf.json b/Tests/conf.json index d47e1c14a51e..9d026efcd39f 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -2850,7 +2850,6 @@ "Symantec Deepsight Test": "Issue 22971", "Akamai_WAF_SIEM-Test": "Issue 22225", "test_MsGraphFiles": "Issue 22853 ", - "TestCofenseFeed": "Issue 22854", "Cybereason Test": "Issue 22683", "Bluecat Address Manager test": "Issue 22616", "test-Expanse": "Expanse should provide domain that they have in their system", From 2c6c1fc5a24c395f67ec406d9c0eef4dfa5d673c Mon Sep 17 00:00:00 2001 From: eli sharf Date: Wed, 10 Jun 2020 10:10:17 +0300 Subject: [PATCH 018/200] Updated Cortex XDR IOCs pack names - 20.6.0 (#7437) (#7457) * Updated Cortex XDR IOCs pack names - 20.6.0 (#7437) * updated pack name, integration name, and command names of "Cortex XDR - IOC" * fixed bug * update tests * update pack & integration description * update pack & integration description * updated descriptions * update integration format * fixup! update integration format * adding ioc triger to push command * update README * fix CR * fixup! fix CR * Update Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml Co-authored-by: Shai Yaakovi <30797606+yaakovi@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Guy Lichtman <1395797+glicht@users.noreply.github.com> * update readme with a better description * updated descriptions and display name in yml * Update Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml * Update Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml * Apply suggestions from technical writer review * fix * fixup! fix * fixinig * last fix * add sleep time * add sleep time Co-authored-by: eli sharf Co-authored-by: esharf Co-authored-by: Guy Lichtman <1395797+glicht@users.noreply.github.com> * adding empty release notes * Update CHANGELOG.md Co-authored-by: Shai Yaakovi <30797606+yaakovi@users.noreply.github.com> Co-authored-by: esharf Co-authored-by: Guy Lichtman <1395797+glicht@users.noreply.github.com> --- .../Integrations/XDR_iocs/CHANGELOG.md | 2 + .../XDR_iocs/Integrations/XDR_iocs/README.md | 72 ++++----- .../Integrations/XDR_iocs/XDR_iocs.py | 68 +++++++-- .../Integrations/XDR_iocs/XDR_iocs.yml | 104 +++++++------ .../XDR_iocs/XDR_iocs_description.md | 7 +- .../Integrations/XDR_iocs/XDR_iocs_test.py | 17 ++- .../Integrations/XDR_iocs/commands.txt | 7 +- .../Playbooks/XDR_iocs_every_minute.yml | 138 ----------------- .../Playbooks/XDR_iocs_nightly_job.yml | 140 ------------------ .../TestPlaybooks/XDR_iocs_-_Test.yml | 51 ++++--- .../TestPlaybooks/XDR_test_helper.yml | 3 +- Packs/XDR_iocs/pack_metadata.json | 4 +- Tests/conf.json | 6 +- 13 files changed, 195 insertions(+), 424 deletions(-) create mode 100644 Packs/XDR_iocs/Integrations/XDR_iocs/CHANGELOG.md delete mode 100644 Packs/XDR_iocs/Playbooks/XDR_iocs_every_minute.yml delete mode 100644 Packs/XDR_iocs/Playbooks/XDR_iocs_nightly_job.yml diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/CHANGELOG.md b/Packs/XDR_iocs/Integrations/XDR_iocs/CHANGELOG.md new file mode 100644 index 000000000000..ddb2854d8905 --- /dev/null +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/CHANGELOG.md @@ -0,0 +1,2 @@ +## [Unreleased] +- diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/README.md b/Packs/XDR_iocs/Integrations/XDR_iocs/README.md index 0839d27301df..1a8b1c54ab4d 100644 --- a/Packs/XDR_iocs/Integrations/XDR_iocs/README.md +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/README.md @@ -1,10 +1,14 @@ +Cortex XDR is the world's first detection and response app that natively integrates network, endpoint and cloud data to stop sophisticated attacks. -XDR handle indicators -This integration was integrated and tested with Branch: stable-50 of XDR -## Configure XDR iocs on Cortex XSOAR +Use the Cortex XDR - IOCs feed integration to sync indicators between Cortex XSOAR and Cortex XDR. The integration will sync indicators according to the defined fetch interval. At each interval, the integration will push new and modified indicators defined in the **Sync Query** from Cortex XSOAR to Cortex XDR. Additionally, the integration will check if there are manual modifications of indicators on Cortex XDR and sync back to Cortex XSOAR. Once per day, the integration will perform a *complete sync* which will also remove indicators that have been deleted/expired in Cortex XSOAR, from Cortex XDR. + + +This integration was integrated and tested with Branch: stable-50 of XDR. + +## Configure Cortex XDR - IOC on Cortex XSOAR 1. Navigate to **Settings** > **Integrations** > **Servers & Services**. -2. Search for XDR iocs. +2. Search for Cortex XDR - IOC. 3. Click **Add instance** to create and configure a new integration instance. | **Parameter** | **Description** | **Required** | @@ -13,8 +17,8 @@ This integration was integrated and tested with Branch: stable-50 of XDR | apikey_id | API Key ID | True | | apikey | API Key | True | | feed | Fetch indicators | False | -| severity | the severity in XDR | True | -| query | query | True | +| severity | the severity in Cortex XDR | True | +| query | Sync Query | True | | insecure | Trust any certificate \(not secure\) | False | | proxy | Use system proxy settings | False | | feedReputation | Indicator Reputation | False | @@ -46,65 +50,44 @@ There is no context output for this command. #### Command Example ```!xdr-iocs-sync``` - #### Human Readable Output - ->sync with XDR completed. - -### xdr-iocs-iocs-to-keep -*** -Update all iocs to keep and delete the other. -run this ones a day in 01:00 - 3:00 utc time. - - -#### Base Command - -`xdr-iocs-to-keep` -#### Input - -There are no input arguments for this command. - -#### Context Output - -There is no context output for this command. - -#### Command Example -```xdr-iocs-to-keep``` - #### Human Readable Output - >sync with XDR completed. +>sync with XDR completed. -### xdr-push-iocs +### xdr-iocs-push *** -Push new iocs to XDR run this ones a min. +Push new IOCs to XDR. run This every minute (without indicator argument) or ioc trigerd (using indicator argument). #### Base Command -`xdr-push-iocs` +`xdr-iocs-push` #### Input -There are no input arguments for this command. - +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| indicator | the indicators | Optional | + + #### Context Output There is no context output for this command. #### Command Example -```xdr-push-iocs``` +```xdr-iocs-push``` #### Human Readable Output +>push success. - -### xdr-enable-iocs +### xdr-iocs-enable *** Enable iocs in XDR server #### Base Command -`xdr-enable-iocs` +`xdr-iocs-enable` #### Input | **Argument Name** | **Description** | **Required** | @@ -116,20 +99,20 @@ Enable iocs in XDR server There is no context output for this command. #### Command Example -```!xdr-enable-iocs indicator=11.11.11.11``` +```!xdr-iocs-enable indicator=11.11.11.11``` #### Human Readable Output >indicators 11.11.11.11 enabled. -### xdr-disable-iocs +### xdr-iocs-disable *** Disable iocs in XDR server #### Base Command -`xdr-disable-iocs` +`xdr-iocs-disable` #### Input | **Argument Name** | **Description** | **Required** | @@ -141,9 +124,8 @@ Disable iocs in XDR server There is no context output for this command. #### Command Example -```!xdr-disable-iocs indicator=22.22.22.22``` +```!xdr-iocs-disable indicator=22.22.22.22``` #### Human Readable Output >indicators 22.22.22.22 disabled. - \ No newline at end of file diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.py b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.py index 4ec01ec65ab1..cd391d85d695 100644 --- a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.py +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.py @@ -33,7 +33,7 @@ class Client: severity: str = '' - query: str = 'type:File or type:Domain or type:IP' + query: str = 'reputation:Bad and (type:File or type:Domain or type:IP)' error_codes: Dict[int, str] = { 500: 'XDR internal server error.', 401: 'Unauthorized access. An issue occurred during authentication. This can indicate an ' + # noqa: W504 @@ -182,11 +182,10 @@ def demisto_ioc_to_xdr(ioc: Dict) -> Dict: xdr_ioc: Dict = { 'indicator': ioc['value'], 'severity': Client.severity, - 'type': demisto_types_to_xdr(ioc['indicator_type']), + 'type': demisto_types_to_xdr(str(ioc['indicator_type'])), 'reputation': demisto_score_to_xdr.get(ioc.get('score', 0), 'UNKNOWN'), 'expiration_date': demisto_expiration_to_xdr(ioc.get('expiration')) } - # get last 'IndicatorCommentRegular' comment: Dict = next(filter(lambda x: x.get('type') == 'IndicatorCommentRegular', reversed(ioc.get('comments', []))), {}) if comment: @@ -214,7 +213,8 @@ def sync(client: Client): path: str = 'sync_tim_iocs' client.http_request(path, requests_kwargs) demisto.setIntegrationContext({'ts': int(datetime.now(timezone.utc).timestamp() * 1000), - 'time': datetime.now(timezone.utc).strftime(DEMISTO_TIME_FORMAT)}) + 'time': datetime.now(timezone.utc).strftime(DEMISTO_TIME_FORMAT), + 'iocs_to_keep_time': create_iocs_to_keep_time()}) return_outputs('sync with XDR completed.') @@ -247,14 +247,22 @@ def get_last_iocs(batch_size=200) -> List: def tim_insert_jsons(client: Client): - iocs = get_last_iocs() + indicators = demisto.args().get('indicator') + if not indicators: + iocs = get_last_iocs() + else: + iocs = [] + for indicator in indicators.split(','): + iocs.append(demisto.searchIndicators(query=f'value:{indicator}').get('iocs')[0]) + path = 'tim_insert_jsons/' requests_kwargs: Dict = get_requests_kwargs(_json=list(map(lambda ioc: demisto_ioc_to_xdr(ioc), iocs))) client.http_request(url_suffix=path, requests_kwargs=requests_kwargs) + return_outputs('push success.') def iocs_command(client: Client): - command = demisto.command().split('-')[1] + command = demisto.command().split('-')[-1] indicators = demisto.args().get('indicator', '') if command == 'enable': path, iocs = prepare_enable_iocs(indicators) @@ -322,6 +330,38 @@ def module_test(client: Client): demisto.results('ok') +def fetch_indicators(client: Client, auto_sync: bool = False): + if not demisto.getIntegrationContext() and auto_sync: + xdr_iocs_sync_command(client, first_time=True) + else: + get_changes(client) + if auto_sync: + tim_insert_jsons(client) + if iocs_to_keep_time(): + # first_time=False will call iocs_to_keep + xdr_iocs_sync_command(client) + + +def xdr_iocs_sync_command(client: Client, first_time: bool = False): + if first_time or not demisto.getIntegrationContext(): + sync(client) + else: + iocs_to_keep(client) + + +def iocs_to_keep_time(): + hour, minute = demisto.getIntegrationContext().get('iocs_to_keep_time', (0, 0)) + time_now = datetime.now(timezone.utc) + return time_now.hour == hour and time_now.min == minute + + +def create_iocs_to_keep_time(): + offset = secrets.randbelow(115) + hour, minute, = divmod(offset, 60) + hour += 1 + return hour, minute + + def main(): # """ # Executes an integration command @@ -332,18 +372,18 @@ def main(): client = Client(params) commands = { 'test-module': module_test, - 'xdr-iocs-sync': sync, - 'xdr-iocs-to-keep': iocs_to_keep, - 'xdr-enable-iocs': iocs_command, - 'xdr-disable-iocs': iocs_command, - 'xdr-push-iocs': tim_insert_jsons, - 'fetch-indicators': get_changes, + 'xdr-iocs-enable': iocs_command, + 'xdr-iocs-disable': iocs_command, + 'xdr-iocs-push': tim_insert_jsons, } - command = demisto.command() try: - if command in commands: + if command == 'fetch-indicators': + fetch_indicators(client, params.get('autoSync', False)) + elif command in commands: commands[command](client) + elif command == 'xdr-iocs-sync': + xdr_iocs_sync_command(client, bool(demisto.args().get('firstTime', False))) else: raise NotImplementedError(command) except Exception as error: diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml index 1f7ae1b79c77..dc271068a153 100644 --- a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml @@ -1,6 +1,6 @@ category: Data Enrichment & Threat Intelligence commonfields: - id: XDR iocs + id: Cortex XDR - IOC version: -1 configuration: - display: Server URL (e.g. https://example.net) @@ -20,19 +20,26 @@ configuration: name: feed required: false type: 8 -- display: the severity in XDR +- defaultvalue: 'true' + additionalinfo: When enabled, indicators will be synced from Cortex XSOAR to Cortex XDR. Disable if you prefer to use a playbook to sync indicators. + display: Auto Sync + name: autoSync + required: false + type: 8 +- additionalinfo: Map the severity of each indicator that will be synced to Cortex XDR. + display: Cortex XDR Severity hidden: false name: severity options: - - 'info' - - 'low' - - 'med' - - 'high' + - info + - low + - med + - high required: true type: 15 -- additionalinfo: The query used to collect indicators. - defaultvalue: type:File or type:Domain or type:IP - display: query +- additionalinfo: The query used to collect indicators to sync from Cortex XSOAR to Cortex XDR. + defaultvalue: reputation:Bad and (type:File or type:Domain or type:IP) + display: Sync Query hidden: false name: query required: true @@ -50,10 +57,10 @@ configuration: display: Indicator Reputation name: feedReputation options: - - None - - Good - - Suspicious - - Bad + - None + - Good + - Suspicious + - Bad required: false type: 18 - additionalinfo: Reliability of the source providing the intelligence data @@ -61,12 +68,12 @@ configuration: display: Source Reliability name: feedReliability options: - - A - Completely reliable - - B - Usually reliable - - C - Fairly reliable - - D - Not usually reliable - - E - Unreliable - - F - Reliability cannot be judged + - A - Completely reliable + - B - Usually reliable + - C - Fairly reliable + - D - Not usually reliable + - E - Unreliable + - F - Reliability cannot be judged required: true type: 15 - display: '' @@ -82,43 +89,56 @@ configuration: name: feedExpirationInterval required: false type: 1 -- display: '' +- defaultvalue: 'true' + hidden: true name: feedIncremental - defaultvalue: true required: false type: 8 - display: Feed Fetch Interval name: feedFetchInterval required: false type: 19 -- additionalinfo: When selected, the exclusion list is ignored for indicators from this - feed. This means that if an indicator from this feed is on the exclusion list, the - indicator might still be added to the system. +- additionalinfo: When selected, the exclusion list is ignored for indicators from + this feed. This means that if an indicator from this feed is on the exclusion + list, the indicator might still be added to the system. display: Bypass exclusion list name: feedBypassExclusionList required: false type: 8 -description: XDR handele indicators -display: XDR iocs -name: XDR iocs +description: Use the Cortex XDR - IOCs feed integration to sync indicators from Cortex XSOAR to Cortex XDR and back to Cortex XSOAR. Cortex XDR is the world's first detection and response app that natively integrates network, endpoint and cloud data to stop sophisticated attacks. +display: Cortex XDR - IOC +name: Cortex XDR - IOC script: commands: - - deprecated: false + - arguments: + - auto: PREDEFINED + default: true + defaultValue: 'false' + description: For first sync, set to true. + isArray: false + name: firstTime + predefined: + - 'true' + - 'false' + required: false + secret: false + deprecated: false description: |- Run once when you configure the integration (do NOT run this twice!). will all the indicators that were synced with XDR and then resync. execution: false name: xdr-iocs-sync - - deprecated: false - description: |- - Update all IOCs to keep and delete the other. - Run this one time per day in 01:00 - 3:00 UTC time. - execution: false - name: xdr-iocs-to-keep - - deprecated: false - description: Push new IOCs to XDR. This runs every minute. + - arguments: + - default: false + description: IOCs to push. leave empty to push all recently modified IOCs.the indicators + isArray: true + name: indicator + required: false + secret: false + deprecated: false + description: Push modified IOCs to Cortex XDR. execution: false - name: xdr-push-iocs + name: xdr-iocs-push - arguments: - default: false description: The indicator to enable. @@ -129,10 +149,10 @@ script: deprecated: false description: Enables IOCs in the XDR server. execution: false - name: xdr-enable-iocs + name: xdr-iocs-enable - arguments: - default: false - description: The indicator to enable. + description: The indicator to disable. isArray: true name: indicator required: true @@ -140,7 +160,7 @@ script: deprecated: false description: Disables IOCs in the XDR server. execution: false - name: xdr-disable-iocs + name: xdr-iocs-disable dockerimage: demisto/python3:3.8.3.8715 feed: true isfetch: false @@ -150,6 +170,6 @@ script: script: '-' subtype: python3 type: python -fromversion: 5.5.0 tests: -- XDR iocs - Test +- Cortex XDR - IOC - Test +fromversion: 5.5.0 diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_description.md b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_description.md index 12ce54529c74..d5a9b5d97d02 100644 --- a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_description.md +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_description.md @@ -1,4 +1,5 @@ -## XDR iocs +## Cortex XDR - IOC +Use the Cortex XDR - IOCs feed integration to sync indicators from XSOAR to XDR. Cortex XDR is the world's first detection and response app that natively integrates network, endpoint and cloud data to stop sophisticated attacks. ### Generate an API Key and API Key ID @@ -15,9 +16,5 @@ Cortex XDR is the world's first detection and response app that natively integra ### Query The query to find indicators. -### Playbooks -Configure **XDR iocs every minute** to run every minute. -Configure **XDR iocs nightly job** to run every night (1:00 - 3:00 in UTC). - ### Important Do not use more then one instance. Instances will override each other. diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_test.py b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_test.py index 4b36bdb48bc8..123da4b596ca 100644 --- a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_test.py +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs_test.py @@ -414,7 +414,12 @@ def test_demisto_vendors_to_xdr(self, demisto_vendor, xdr_vendor): data_test_demisto_ioc_to_xdr = [ ( {'value': '11.11.11.11', 'indicator_type': 'IP', 'score': 2}, - {'expiration_date': -1, 'indicator': '11.11.11.11', 'reputation': 'SUSPICIOUS', 'severity': 'INFO', 'type': 'IP'} + {'expiration_date': -1, 'indicator': '11.11.11.11', 'reputation': 'SUSPICIOUS', 'severity': 'INFO', + 'type': 'IP'} + ), + ( + {'value': '11.11.11.11', 'indicator_type': 100, 'score': 2}, + {'expiration_date': -1, 'indicator': '11.11.11.11', 'reputation': 'SUSPICIOUS', 'severity': 'INFO', 'type': '100'} ), ( {'value': '11.11.11.11', 'indicator_type': 'IP'}, @@ -537,7 +542,7 @@ def test_xdr_expiration_to_demisto(self, xdr_expiration, demisto_expiration): 'RULE_STATUS': 'ENABLED', 'BS_STATUS': 'DONE', 'BS_TS': 1591165801784, 'BS_RETRIES': 1, 'RULE_EXPIRATION_TIME': -1, 'IOC_TYPE': 'DOMAIN_NAME', 'RULE_INDICATOR': 'test.co.il', 'REPUTATION': 'SUSPICIOUS', 'RELIABILITY': 'A', - 'VENDORS': [{'vendor_name': 'XDR iocs', 'reputation': 'SUSPICIOUS', 'reliability': 'A'}], + 'VENDORS': [{'vendor_name': 'Cortex XDR - IOC', 'reputation': 'SUSPICIOUS', 'reliability': 'A'}], 'KLASS': None, 'IS_DEFAULT_TTL': False, 'RULE_TTL': -1, 'MARKED_DELETED': 0 }, @@ -582,7 +587,7 @@ def test_iocs_command_with_enable(self, mocker): Then: - Verify enable command is called. """ - mocker.patch.object(demisto, 'command', return_value='xdr-enable-iocs') + mocker.patch.object(demisto, 'command', return_value='xdr-iocs-enable') mocker.patch.object(demisto, 'args', return_value={'indicator': '11.11.11.11'}) mocker.patch('XDR_iocs.Client.http_request', return_value={}) outputs = mocker.patch('XDR_iocs.return_outputs') @@ -601,7 +606,7 @@ def test_iocs_command_with_disable(self, mocker): - Verify disable command is called. """ - mocker.patch.object(demisto, 'command', return_value='xdr-disable-iocs') + mocker.patch.object(demisto, 'command', return_value='xdr-iocs-disable') mocker.patch.object(demisto, 'args', return_value={'indicator': '11.11.11.11'}) mocker.patch('XDR_iocs.Client.http_request', return_value={}) outputs = mocker.patch('XDR_iocs.return_outputs') @@ -630,7 +635,7 @@ def test_iocs_to_keep(self, mocker): def test_tim_insert_jsons(self, mocker): http_request = mocker.patch.object(Client, 'http_request') - mocker.patch.object(demisto, 'getIntegrationContext', return_value={'time': '2020-06-03T00:00:00Z'}) + mocker.patch.object(demisto, 'getLastRun', return_value={'time': '2020-06-03T00:00:00Z'}) iocs, _ = TestCreateFile.get_all_iocs(TestCreateFile.data_test_create_file_sync, 'json') mocker.patch.object(demisto, 'searchIndicators', returnvalue=iocs) mocker.patch('XDR_iocs.return_outputs') @@ -638,7 +643,7 @@ def test_tim_insert_jsons(self, mocker): assert http_request.call_args.kwargs['url_suffix'] == 'tim_insert_jsons/', 'tim_insert_jsons command url changed' def test_get_changes(self, mocker): - mocker.patch.object(demisto, 'getIntegrationContext', return_value={'ts': 1591142400000}) + mocker.patch.object(demisto, 'getLastRun', return_value={'ts': 1591142400000}) mocker.patch.object(demisto, 'createIndicators', return_value={'ts': 1591142400000}) xdr_res = {'reply': list(map(lambda xdr_ioc: xdr_ioc[0], TestXDRIOCToDemisto.data_test_xdr_ioc_to_demisto))} mocker.patch.object(Client, 'http_request', return_value=xdr_res) diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/commands.txt b/Packs/XDR_iocs/Integrations/XDR_iocs/commands.txt index d24e1c39fb79..4b761d2398bf 100644 --- a/Packs/XDR_iocs/Integrations/XDR_iocs/commands.txt +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/commands.txt @@ -1,5 +1,4 @@ !xdr-iocs-sync -!xdr-iocs-to-keep -!xdr-enable-iocs indicator=11.11.11.11 -!xdr-disable-iocs indicator=22.22.22.22 -!xdr-push-iocs \ No newline at end of file +!xdr-iocs-enable indicator=11.11.11.11 +!xdr-iocs-disable indicator=22.22.22.22 +!xdr-iocs-push indicator='test.com' diff --git a/Packs/XDR_iocs/Playbooks/XDR_iocs_every_minute.yml b/Packs/XDR_iocs/Playbooks/XDR_iocs_every_minute.yml deleted file mode 100644 index 5c9dad46f595..000000000000 --- a/Packs/XDR_iocs/Playbooks/XDR_iocs_every_minute.yml +++ /dev/null @@ -1,138 +0,0 @@ -id: XDR iocs every minute -version: -1 -name: XDR iocs every minute -description: Push IOCs to XDR -starttaskid: "0" -tasks: - "0": - id: "0" - taskid: 912d4cb4-6a61-489f-8d4c-6a98204afc1a - type: start - task: - id: 912d4cb4-6a61-489f-8d4c-6a98204afc1a - version: -1 - name: "" - iscommand: false - brand: "" - description: "" - nexttasks: - '#none#': - - "1" - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 50 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - "1": - id: "1" - taskid: 7c863a42-c2ac-420c-8a44-779c074ae6dd - type: regular - task: - id: 7c863a42-c2ac-420c-8a44-779c074ae6dd - version: -1 - name: xdr-push-iocs - description: Push new IOCs to XDR. This runs once a min. - script: XDR iocs|||xdr-push-iocs - type: regular - iscommand: true - brand: XDR iocs - nexttasks: - '#none#': - - "3" - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 230 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - "2": - id: "2" - taskid: 22ff87c0-5bc9-407b-88e7-bb7308ba11ad - type: title - task: - id: 22ff87c0-5bc9-407b-88e7-bb7308ba11ad - version: -1 - name: Done - type: title - iscommand: false - brand: "" - description: "" - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 610 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - "3": - id: "3" - taskid: a02a9572-8ffb-4130-8a56-9813d455b84d - type: regular - task: - id: a02a9572-8ffb-4130-8a56-9813d455b84d - version: -1 - name: closeInvestigation - description: Close the current incident - script: Builtin|||closeInvestigation - type: regular - iscommand: true - brand: Builtin - nexttasks: - '#none#': - - "2" - scriptarguments: - closeNotes: {} - closeReason: {} - id: - simple: ${incident.id} - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 430 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 -view: |- - { - "linkLabelsPosition": {}, - "paper": { - "dimensions": { - "height": 625, - "width": 380, - "x": 450, - "y": 50 - } - } - } -inputs: [] -outputs: [] -fromversion: '5.5.0' -tests: - - No tests diff --git a/Packs/XDR_iocs/Playbooks/XDR_iocs_nightly_job.yml b/Packs/XDR_iocs/Playbooks/XDR_iocs_nightly_job.yml deleted file mode 100644 index 7080ccf29ecb..000000000000 --- a/Packs/XDR_iocs/Playbooks/XDR_iocs_nightly_job.yml +++ /dev/null @@ -1,140 +0,0 @@ -id: XDR iocs nightly job -version: -1 -name: XDR iocs nightly job -description: Remove deleted IOCs from XDR -starttaskid: "0" -tasks: - "0": - id: "0" - taskid: 3c3a1ca1-a1cc-4d9d-833d-0ac6c9695a31 - type: start - task: - id: 3c3a1ca1-a1cc-4d9d-833d-0ac6c9695a31 - version: -1 - name: "" - iscommand: false - brand: "" - description: "" - nexttasks: - '#none#': - - "1" - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 50 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - "1": - id: "1" - taskid: e93c0a7d-a0ad-4e65-8827-6aa1f5e6518b - type: regular - task: - id: e93c0a7d-a0ad-4e65-8827-6aa1f5e6518b - version: -1 - name: xdr-iocs-to-keep - description: |- - Update all IOCs to keep and delete the other. - Run this one time per day in 01:00 - 3:00 UTC time. - script: XDR iocs|||xdr-iocs-to-keep - type: regular - iscommand: true - brand: XDR iocs - nexttasks: - '#none#': - - "3" - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 240 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - "2": - id: "2" - taskid: 0ca0c273-28b0-45a6-828c-482b7b5844e1 - type: title - task: - id: 0ca0c273-28b0-45a6-828c-482b7b5844e1 - version: -1 - name: Done - type: title - iscommand: false - brand: "" - description: "" - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 620 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - "3": - id: "3" - taskid: 36f868bb-0f72-4f93-862c-bff94064fe3a - type: regular - task: - id: 36f868bb-0f72-4f93-862c-bff94064fe3a - version: -1 - name: closeInvestigation - description: Close the current incident - script: Builtin|||closeInvestigation - type: regular - iscommand: true - brand: Builtin - nexttasks: - '#none#': - - "2" - scriptarguments: - closeNotes: {} - closeReason: {} - id: - simple: ${incident.id} - separatecontext: false - view: |- - { - "position": { - "x": 450, - "y": 420 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 -view: |- - { - "linkLabelsPosition": {}, - "paper": { - "dimensions": { - "height": 635, - "width": 380, - "x": 450, - "y": 50 - } - } - } -inputs: [] -outputs: [] -fromversion: '5.5.0' -tests: - - No tests diff --git a/Packs/XDR_iocs/TestPlaybooks/XDR_iocs_-_Test.yml b/Packs/XDR_iocs/TestPlaybooks/XDR_iocs_-_Test.yml index 8844a5e67c54..4693da95dede 100644 --- a/Packs/XDR_iocs/TestPlaybooks/XDR_iocs_-_Test.yml +++ b/Packs/XDR_iocs/TestPlaybooks/XDR_iocs_-_Test.yml @@ -1,6 +1,6 @@ -id: XDR iocs - Test +id: Cortex XDR - IOC - Test version: -1 -name: XDR iocs - Test +name: Cortex XDR - IOC - Test starttaskid: "0" tasks: "0": @@ -164,7 +164,9 @@ tasks: id: 3748e1e4-d9eb-4fd0-8aef-c61bedce4981 version: -1 name: xdr-iocs-sync - description: run once when configure the integration (do NOT use this twice!). + description: |- + Run once when you configure the integration (do NOT run this twice!). + will all the indicators that were synced with XDR and then resync. script: 'xdr-iocs-sync' type: regular iscommand: true @@ -172,6 +174,9 @@ tasks: nexttasks: '#none#': - "7" + scriptarguments: + firstTime: + simple: "true" separatecontext: false view: |- { @@ -266,7 +271,7 @@ tasks: task: id: fdf8f5e4-a22a-415d-8d5d-7a186488eeb4 version: -1 - name: Sleep (60) + name: Sleep (120) description: Sleep for X seconds scriptName: Sleep type: regular @@ -279,7 +284,7 @@ tasks: - "11" scriptarguments: seconds: - simple: "60" + simple: "120" separatecontext: false view: |- { @@ -300,9 +305,9 @@ tasks: task: id: 12c5f3ea-5c81-42ea-8985-69e957165379 version: -1 - name: xdr-disable-iocs (test.com) + name: xdr-iocs-disable (test.com) description: Disable iocs in XDR server - script: 'xdr-disable-iocs' + script: 'xdr-iocs-disable' type: regular iscommand: true brand: "" @@ -332,9 +337,9 @@ tasks: task: id: c2a2117a-b4e6-4e20-8176-712f12172f13 version: -1 - name: xdr-disable-iocs (88.88.88.88) + name: xdr-iocs-disable (88.88.88.88) description: Disable iocs in XDR server - script: 'xdr-disable-iocs' + script: 'xdr-iocs-disable' type: regular iscommand: true brand: "" @@ -364,9 +369,9 @@ tasks: task: id: ddc92f88-ce5c-4f06-8911-8694c3d6e1bd version: -1 - name: xdr-disable-iocs (fa66f1e0e318b6d7b595b6cee580dc0d8e4ac38fbc8dbfcac6ad66dbe282832e) + name: xdr-iocs-disable (fa66f1e0e318b6d7b595b6cee580dc0d8e4ac38fbc8dbfcac6ad66dbe282832e) description: Disable iocs in XDR server - script: 'xdr-disable-iocs' + script: 'xdr-iocs-disable' type: regular iscommand: true brand: "" @@ -396,7 +401,7 @@ tasks: task: id: c9a9ecd7-afef-46ff-8240-fd4d9af54fed version: -1 - name: Sleep (60) + name: Sleep (120) description: Sleep for X seconds scriptName: Sleep type: regular @@ -409,7 +414,7 @@ tasks: - "15" scriptarguments: seconds: - simple: "60" + simple: "120" separatecontext: false view: |- { @@ -681,9 +686,9 @@ tasks: task: id: 030fa5e9-09a9-4a01-816c-1aa154b0d186 version: -1 - name: xdr-enable-iocs (test.com) + name: xdr-iocs-enable (test.com) description: Enable iocs in XDR server - script: 'xdr-enable-iocs' + script: 'xdr-iocs-enable' type: regular iscommand: true brand: "" @@ -713,9 +718,9 @@ tasks: task: id: 54064545-7bd5-4dd1-87dd-29a5f1a7c3e3 version: -1 - name: xdr-enable-iocs (88.88.88.88) + name: xdr-iocs-enable (88.88.88.88) description: Enable iocs in XDR server - script: 'xdr-enable-iocs' + script: 'xdr-iocs-enable' type: regular iscommand: true brand: "" @@ -745,9 +750,9 @@ tasks: task: id: b22de31d-afad-415c-8153-b355eccee4aa version: -1 - name: xdr-enable-iocs (fa66f1e0e318b6d7b595b6cee580dc0d8e4ac38fbc8dbfcac6ad66dbe282832e) + name: xdr-iocs-enable (fa66f1e0e318b6d7b595b6cee580dc0d8e4ac38fbc8dbfcac6ad66dbe282832e) description: Enable iocs in XDR server - script: 'xdr-enable-iocs' + script: 'xdr-iocs-enable' type: regular iscommand: true brand: "" @@ -777,7 +782,7 @@ tasks: task: id: 76bcb0bb-5758-4998-868a-ef00f1817b53 version: -1 - name: Sleep (60) + name: Sleep (120) description: Sleep for X seconds scriptName: Sleep type: regular @@ -790,7 +795,7 @@ tasks: - "26" scriptarguments: seconds: - simple: "60" + simple: "120" separatecontext: false view: |- { @@ -1077,7 +1082,7 @@ tasks: task: id: bfcd05f4-9f1e-4493-8389-b55c04795134 version: -1 - name: Sleep (60) + name: Sleep (120) description: Sleep for X seconds scriptName: Sleep type: regular @@ -1088,7 +1093,7 @@ tasks: - "4" scriptarguments: seconds: - simple: "60" + simple: "120" separatecontext: false view: |- { diff --git a/Packs/XDR_iocs/TestPlaybooks/XDR_test_helper.yml b/Packs/XDR_iocs/TestPlaybooks/XDR_test_helper.yml index 60d5218743a7..8ce064726918 100644 --- a/Packs/XDR_iocs/TestPlaybooks/XDR_test_helper.yml +++ b/Packs/XDR_iocs/TestPlaybooks/XDR_test_helper.yml @@ -6,9 +6,8 @@ script: |+ args = demisto.args() indicator = args['indicator'] data = demisto.searchIndicators(value=indicator)['iocs'][0]['moduleToFeedMap'] - xdr_reputation = None for indicator_reputation in data.values(): - if indicator_reputation.get('sourceBrand') == 'XDR iocs': + if indicator_reputation.get('sourceBrand') == 'Cortex XDR - IOC': return_outputs('', outputs={indicator.replace('.', '_'): indicator_reputation['fields']['xdr']}) break diff --git a/Packs/XDR_iocs/pack_metadata.json b/Packs/XDR_iocs/pack_metadata.json index 7d45e2c26776..0cc075445949 100644 --- a/Packs/XDR_iocs/pack_metadata.json +++ b/Packs/XDR_iocs/pack_metadata.json @@ -1,6 +1,6 @@ { - "name": "XDR iocs", - "description": "XDR iocs", + "name": "Cortex XDR - IOC", + "description": "Sync your indicators with Cortex XDR.", "support": "xsoar", "currentVersion": "1.0.0", "author": "Cortex XSOAR", diff --git a/Tests/conf.json b/Tests/conf.json index 9d026efcd39f..5d31bdafcb1a 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -324,10 +324,10 @@ "fromversion": "4.1.0" }, { - "integrations": "XDR iocs", - "playbookID": "XDR iocs - Test", + "integrations": "Cortex XDR - IOC", + "playbookID": "Cortex XDR - IOC - Test", "fromversion": "5.5.0", - "timeout": 300 + "timeout": 600 }, { "integrations": "Cloaken", From fea875bbc2103f17ca0a76a74bbe01e1ab0d5ee6 Mon Sep 17 00:00:00 2001 From: Ika Gabashvili <45535078+IkaDemisto@users.noreply.github.com> Date: Wed, 10 Jun 2020 10:14:55 +0300 Subject: [PATCH 019/200] deleted Legacy pack (#7463) --- Packs/Legacy/.pack-ignore | 14 - Packs/Legacy/.secrets-ignore | 1702 ------------------------------- Packs/Legacy/CHANGELOG.md | 2 - Packs/Legacy/README.md | 2 - Packs/Legacy/pack_metadata.json | 16 - 5 files changed, 1736 deletions(-) delete mode 100644 Packs/Legacy/.pack-ignore delete mode 100644 Packs/Legacy/.secrets-ignore delete mode 100644 Packs/Legacy/CHANGELOG.md delete mode 100644 Packs/Legacy/README.md delete mode 100644 Packs/Legacy/pack_metadata.json diff --git a/Packs/Legacy/.pack-ignore b/Packs/Legacy/.pack-ignore deleted file mode 100644 index 7d1c7c6d2680..000000000000 --- a/Packs/Legacy/.pack-ignore +++ /dev/null @@ -1,14 +0,0 @@ -[file:playbook-Search_Endpoints_By_Hash_-_Carbon_Black_Response.yml] -ignore=BA101 - -[file:playbook-Add_Indicator_to_Miner_-_Palo_Alto_MineMeld.yml] -ignore=BA101 - -[file:playbook-Display_Results_-_GVault.yml] -ignore=BA101 - -[file:playbook-ransomware.yml] -ignore=BA101 - -[file:playbook-Get_File_Sample_From_Path_-_Carbon_Black_Enterprise_Response.yml] -ignore=BA101 diff --git a/Packs/Legacy/.secrets-ignore b/Packs/Legacy/.secrets-ignore deleted file mode 100644 index 197f6fc5531b..000000000000 --- a/Packs/Legacy/.secrets-ignore +++ /dev/null @@ -1,1702 +0,0 @@ -0.0.0.0 -0.0.0.255 -0.0.0.31 -0.0.0.8 -0.1.0.0 -0.154.17.105 -0.245.1.2 -0.255.255.255 -000::000 -000::1 -001toxic@gmail.com -1.0.0.127 -1.0.0.128 -1.0.0.91 -1.0.0.98 -1.1.1.0 -1.1.1.1 -1.1.1.2 -1.1.1.3 -1.1.1.69 -1.1.22.22 -1.2.3.3 -1.2.3.4 -1.2.3.5 -1.2.3.7 -1.2.3.8 -1.3.2.007 -1.3.4.5 -1.4.5.6 -1.7.41.5 -1.90.149.220 -10.0.0.1 -10.0.0.2 -10.0.0.4 -10.0.0.5 -10.0.0.98 -10.0.2.2 -10.0.9.117 -10.1.1.0 -10.1.1.1 -10.1.77.0 -10.1.77.3 -10.10.10.0 -10.10.10.1 -10.10.10.10 -10.10.10.13 -10.10.10.20 -10.10.10.25 -10.10.10.255 -10.10.10.29 -10.10.24.1 -10.10.24.20 -10.100.63.1 -10.132.1.9 -10.16.0.3 -10.16.1.3 -10.16.2.4 -10.16.3.3 -10.19.120.67 -10.19.251.29 -10.238.89.39 -10.240.250.42 -10.244.0.6 -10.244.1.4 -10.245.1.2 -10.245.1.3 -10.245.1.4 -10.254.7.24 -10.255.180.79 -10.5.5.5 -10.64.49.14 -10.80.80.0 -10.95.252.182 -100.64.0.0 -1000:: -100:: -101.43.52.224 -104.131.92.15 -104.197.27.250 -104.197.33.61 -104.210.33.180 -104.218.120.128 -107.161.186.90 -111.90.149.220 -1111@evil.zz -116.145.139.179 -12.12.12.12 -120.0.0.1 -123.123.123.65 -127.0.0.0 -127.0.0.1 -127.0.0.2 -128.238.25.159 -130.211.103.14 -14.14.14.14 -147.75.33.100 -169.254.0.0 -171.17.128.2 -172.0.0.0 -172.0.0.2 -172.16.0.0 -172.16.0.1 -172.16.20.207 -172.16.20.234 -172.16.200.80 -172.16.34.11 -172.16.34.152 -172.16.34.161 -172.16.34.23 -172.16.34.231 -172.17.0.0 -172.17.0.1 -172.17.0.10 -172.17.0.12 -172.17.0.13 -172.17.0.14 -172.17.0.2 -172.17.0.3 -172.17.0.5 -172.17.0.6 -172.17.127.254 -172.17.128.0 -172.17.128.1 -172.17.255.254 -172.17.42.0 -172.17.42.1 -172.17.42.3 -172.17.8.100 -172.17.8.101 -172.17.8.102 -172.17.8.103 -172.17.8.104 -172.21.0.3 -172.21.0.4 -172.21.0.5 -172.21.0.6 -172.21.0.9 -172.31.39.254 -172.40.5.10 -188.166.228.244 -188.166.23.215 -188.192.67.232 -19.12.13.11 -190.102.154.131 -190.60.103.178 -190.85.247.140 -191.97.1.40 -192.0.0.0 -192.0.0.1 -192.0.0.170 -192.0.0.2 -192.0.2.0 -192.0.2.1 -192.0.2.128 -192.0.2.130 -192.0.2.192 -192.0.2.2 -192.0.2.32 -192.0.2.4 -192.0.2.64 -192.0.2.8 -192.12.12.3 -192.168.0.0 -192.168.0.1 -192.168.0.2 -192.168.1.1 -192.168.1.100 -192.168.1.2 -192.168.1.222 -192.168.1.254 -192.168.10.1 -192.168.10.23 -192.168.100.32 -192.168.100.33 -192.168.100.55 -192.168.11.11 -192.168.2.0 -192.168.33.1 -192.168.33.10 -192.168.33.11 -192.168.33.12 -192.168.33.13 -192.168.34.1 -192.168.34.10 -192.168.34.11 -192.168.56.101 -192.168.56.108 -192.168.59.103 -192.168.99.103 -192.241.175.250 -193.169.5.14 -193.34.161.137 -193.56.28.196 -194.12.18.147 -194.126.183.171 -194.228.227.157 -195.154.27.50 -195.22.26.248 -195.69.135.78 -198.144.108.117 -198.18.0.0 -198.51.100.0 -2.0.5.1 -2.12.2.9 -2.2.2.2 -2.84.107.193 -20.178.251.203 -20.36.37.97 -200.77.186.170 -2001:10:: -2001:2:: -2001:4860:4860::8888 -2001:: -2001:db8:8000:: -2001:db8:: -2001:db8::1 -2001:db8::1000 -2001:db8::100f -2001:db8::2 -2001:db8::2000 -2001:db8::4 -2001:db8::8 -200:: -201.161.58.245 -201.219.197.138 -202.200.142.251 -203.0.113.0 -203.147.71.11 -203.147.74.216 -206.189.129.38 -206.189.229.112 -207.107.67.67 -207.246.249.197 -207.248.62.98 -208.113.210.246 -208.97.189.248 -210.51.167.245 -212.115.110.19 -212.220.204.238 -213.100.209.39 -213.109.235.231 -213.177.121.139 -213.182.138.224 -216.3.128.82 -21f27jk08d1a487fa0f5467779619827@thread.skype -22.21.20.19 -22.22.22.22 -2222@evil.zz -224.0.0.0 -24@192.168.1.254This -24@192.168.1.254Warning -25.24.23.22 -255.0.0.0 -255.255.0.0 -255.255.255.0 -255.255.255.224 -255.255.255.255 -2603:10b6:208:160::47 -2603:10b6:3:10::10 -27.0.0.1 -2FC50179-3666-4770-A365-744882CDA54C@demisto.com -2a01:111:f400:7e46::204 -2cbad0d78c624400ef83a5750534448g@thread.skype -2cbad0d78c624400ef83a5750539998g@thread.skype -3.3.3.3 -3.3.3.4 -3.4.5.6 -3.7.3.221 -31.207.62.145 -34.17.197.127 -35.158.26.15 -35.165.118.153 -4.2.2.2 -4.4.4.4 -4.4.4.5 -4000:: -400:: -41.79.151.82 -45.19.214.161 -45.55.160.223 -5.5.5.111 -5.6.0.0 -5.6.7.8 -50.204.142.130 -52.1.224.245 -52.18.234.151 -53.132.37.52 -54.152.108.134 -54.154.68.31 -54.194.31.39 -5b4831d0-5322-ea23-6312-864ff419a1f1@test.com -5be9245893ff486d98c3640879bb2657.protect@whoisguard.com -5c530c1b.1c69fb81.bd826.0eff@mx.google.com -6.7.8.9 -6000:: -66.34.253.56 -67pd3967e74g45f28d0c65f1689132bb@thread.skype -67pd3967e74g45f28d0c65f1689132bo@thread.skype -69:aa:64:4b:72:50:ee:15 -7.7.7.6 -72.17.0.2 -72.17.8.103 -77069121-C854-4CA3-ABC0-C98D010A8209@demisto.com -78.125.0.209 -7a:a5:94:7d:4b:2a:9f:61 -8.3.3.3 -8.8.4.4 -8.8.8.8 -8000:: -800:: -9.9.9.9 -92.0.0.1 -92.12.12.3 -92.168.0.1 -92.168.1.115 -92.168.1.136 -92.168.10.1 -92.168.10.23 -92.168.100.55 -92.168.33.10 -92.168.33.11 -93.184.216.34 -95.181.53.78 -98.137.246.8 -9a:da:71:4e:44:cd:db:c0 -9b:10:32:10:ac:46:62:b4 -9d4f::1548 -9facbf452def2d7efc5b5c48cdb837fa@badguy.zz -::a1:72:38:36 -::ffff:0:0 -A000:: -ANOMALOUSjohn.doe@devo.com294.755774516937950.008372777777777778Secaucus40 -C000:: -C718CB8A-E78C-4EA8-AB24-61B8DCD8C8D4@demisto.com -CAJaFoefy_acEKaqSMGfojbLzKoUnzfpPcnNemuD6K0oQZ2PikQ@mail.gmail.com -DemistoTeam@demistodev.onmicrosoft.com -E000:: -E2831654DAE4B545854ACEE617A297E3@namprd11.prod.outlook.com -E3AE306E-13D7-4D19-AB84-A182205D07E6@demisto.com -F000:: -F800:: -FE00:: -FE80::0202:B3FF:FE1E:8329 -IncapsulaUpdates@demisto.com -KHatul@example.com -S@a.com -Userthatdoesnotexist2@demisto.com -Userthatdoesnotexist3@demisto.com -a@a.co.il -a@demisto.com -ada@ada.lt -admin@google.com -agent_7377e1fa-d49d-44bf-84ef-4e1dfb8e4748@demisto.com -foo@test.com -anspdcp@dataprotection.ro -azop@azop.hr -badguy@evil.zz -bob@demisto.int -bpa@paloaltonetworks.com. -bruce.wayne@pharmtech.zz -bruce.wayne@university-of-education.zz -bwillis@email.com -cindy@corp.example.com -cj@corp.example.com -clark.kent@pharmtech.zz -commission@privacycommission.be -commissioner.dataprotection@gov.mt -commissioner@dataprotection.gov.cy -contact20@edoeb.admin.ch -contact@dpa.gr -content-test-service-acc@content-test-236508.iam.gserviceaccount.com -datainspektionen@datainspektionen.se -dave@acme.com -demisto_user@company.net -desiwm@giodo.gov.pl -dfoo@demisto.com -diana.prince@pharmtech.zz -dns-admin@google.comPacks/HelloWorld/IncidentFields/incidentfield-Hello_World_ID_CHANGELOG.md -docker-maint@nginx.com -doo@demisto.com -dsb@dsb.gv.at -dt@datatilsynet.dk -dummy1@rec.com -dummy2@rec.com -dummy3@rec.com -dummy@mailbox.com -dummy@recipient.com -dummyBCC@recipient.com -dummyCC@recipient.com -dummysender@works.com -dwashinton@email.com -e99d7ed5580193f36a51f597bc2c0210@evil.zz -ec2-user@52.1.224.245... -ec2-user@54.152.108.134... -ec2-user@54.194.31.39The -ex@example.com -example1@example.com -example2@example.com -example3@example.com -example@demisto.com -example@example.com -example@gmail.com -fake@test.com -fakeemail@test.com -fakeemail@test.com] -fc00:: -fd60:e22:f1b9::2 -fd60:e32:f1b9::2 -fe00::0 -fe80:: -fe80::c423:879c:b2fc:fc5d -fec0:: -fedora@52.18.234.151 -ff00:: -ff02::1 -ff02::2 -ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0 -filterme@nowhere.com -foo@demisto.com -freddy@queen.com -fromfoo@demisto.com -garante@garanteprivacy.it -geral@cnpd.pt -goo@demisto.com -gp.ip@ip-rs.si -hostmaster@charter.com -how2dock@gmail.com -how2dock@gmail.comLogin -http://.1 -http://0 -http://0fertas-do-dia-24hr-com.umbler.net -http://1 -http://1.2.3.7 -http://10..10 -http://111.90.149.220 -http://123-fake-api.com -http://147.75.33.100 -http://172.17.0.2 -http://172.17.8.100 -http://172.17.8.101 -http://172.17.8.102 -http://172.17.8.103 -http://172.17.8.104 -http://192.168.33.10 -http://192.168.33.1071d8297c1538The -http://192.168.33.108eaab9c31e1a -http://192.168.33.10a970ec6274ca -http://192.168.33.10a970ec6274caUp -http://192.168.33.11 -http://20.36.37.97 -http://256.1.1.1 -http://41.10 -http://41.79.151.82 -http://8eaab9c31e1a -http://a970ec6274ca -http://a970ec6274caUp -http://activelist.model.v1.service.resource.manager.product.a -http://adaptivecards.io -http://ahahahahah.buzz -http://api.domaintools.com -http://api.giphy.com -http://archer-tech.com -http://asdheguhadaasd.com -http://badguy.zz -http://bit.ly -http://bugs.python.org -http://buildlogs.centos.org -http://chase-2sconfirm.com -http://client.webservice.sepm.symantec.com -http://clienteofertaoonline.com -http://clinicaskin.cl -http://command.client.webservice.sepm.symantec.com -http://cve.circl.lu -http://cylance.com -http://data.phishtank.com -http://demisto.com -http://developer.okta.com -http://docs.aws.amazon.com -http://docs.oasis-open.org -http://docs.python-requests.org -http://downloads.hypriot.com -http://dreamhouse.in.th -http://elb -http://en.wikipedia.org -http://exabeam.com -http://exam.karthikeyaiasacademy.com -http://example.com -http://facebook.com -http://forums.bbc.co.uk -http://forums.news.cnn.com -http://galera -http://genuineautoparts.co.uk -http://google.com -http://hackedwebsite.com -http://hailataxii.com -http://inspireddds.com -http://jppost-ki.co -http://json-schema.org -http://kernel.ubuntu.com -http://link -http://localhost -http://logspout -http://magalufimdesemana.com -http://malware.com -http://medimobility.es -http://mindspring.com -http://model.v1.service.resource.manager.product.arcsight.co -http://nginx-app..xip.ioOnce -http://nginx-app.192.168.11.11.xip.ioOnce -http://novasmelhoresluiza.com -http://oreilly.com -http://paypal.co.uk.useriq3sr4wszak.settingsppup.com -http://platform.risksense.com -http://polyswarm-fake-api.com -http://prod1.example.com -http://receptfritt-cialis.com -http://regexr.com -http://safaribooksonline.com -http://schemas.microsoft.com -http://schemas.openxmlformats.org -http://schemas.xmlsoap.org -http://sdfgress.info -http://strftime.org -http://taxii.mitre.org -http://telesomonline.com -http://testsafebrowsing.appspot.com -http://this.is.test.com -http://tools.ietf.org -http://train -http://twitter.com -http://ui.threatstream.com -http://update.nai.com -http://wharfee.comwharfee -http://whois.domaintools.com -http://wiki.servicenow.com -http://wordpress.org -http://ws.v1.service.resource.manager.product.arcsight.com -http://www.ablenew.biz -http://www.ada.lt -http://www.aki.ee -http://www.alexa.com -http://www.antennahouse.com -http://www.azop.hr -http://www.bbc.co.uk -http://www.bfdi.bund.de -http://www.botvrij.eu -http://www.cnil.fr -http://www.cnpd.lu -http://www.cnpd.pt -http://www.cpdp.bg -http://www.datainspektionen.se -http://www.dataprotection.gov.cy -http://www.dataprotection.gov.mt -http://www.dataprotection.gov.sk -http://www.dataprotection.ie -http://www.dataprotection.ro -http://www.datatilsynet.dk -http://www.demisto.com -http://www.dpa.gr -http://www.dsb.gv.at -http://www.dvi.gov.lv -http://www.example.com -http://www.fotoidea.com -http://www.garanteprivacy.it -http://www.giodo.gov.pl -http://www.google.com -http://www.kloshpro.com -http://www.lifetmeda.ru -http://www.logrhythm.com -http://www.mahmoudghoneim.com -http://www.msn.com -http://www.naih.hu -http://www.oreilly.com -http://www.phishtank.com -http://www.privacycommission.be -http://www.sdmiramar.edu -http://www.tietosuoja.fi -http://www.uoou.cz -http://www.w3.org -http://www.worldbank.org.kg -http://www.youtube.com -http://zero.webappsecurity.com -https://1 -https://1.2.3.4 -https://10.245.1.2 -https://10.245.1.2KubeDNS -https://10.245.1.2The -https://123.123.123.65 -https://15 -https://192.0.0.1 -https://192.12.12.3 -https://192.168.0.1 -https://192.168.10.1 -https://192.168.10.23 -https://192.168.100.55 -https://216.3.128.82 -https://3.4.5.6 -https://35.158.26.15 -https://36 -https://3fdzgtam4qk625n6.fi -https://KubeDNS -https://The -https://a1.gymtracker.net -https://a1000-server-name-or-ip -https://a1000.reversinglabs.com -https://account.box.com -https://accounts.google.com -https://addventures.reclaimbetasite.com -https://admin.google.com -https://adservice.google.com -https://akaa-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx.luna.akamaiapis.net -https://akab-hnanog6ge5or6biz-ukavvo4zvqliqhlw.cloudsecurity.akamaiapis.net -https://alphasoc.com -https://analysis.lastline.com -https://analyze.intezer.com -https://api-us.logtrust.com -https://api.abuseipdb.com -https://api.alphasoc.net -https://api.amp.cisco.com -https://api.any.run -https://api.botframework.com -https://api.box.com -https://api.c2sec.com -https://api.ciscospark.com -https://api.cloudlock.com -https://api.crowdstrike.com -https://api.cymon.io -https://api.dnsdb.info -https://api.example.luminatesec.com -https://api.github.com -https://api.intelgraph.idefense.com -https://api.intsights.com -https://api.isightpartners.com -https://api.kennasecurity.com -https://api.koodous.com -https://api.meraki.com -https://api.mimecast.com -https://api.monitoredsecurity.com -https://api.mxtoolbox.com -https://api.opsgenie.com -https://api.pagerduty.com -https://api.passivetotal.org -https://api.perch.rocks -https://api.pipl.com -https://api.polyswarm.network -https://api.protectwise.com -https://api.recordedfuture.com -https://api.redlock.io -https://api.secureworks.com -https://api.securitycenter.windows.com -https://api.shodan.io -https://api.sndbox.com -https://api.threatconnect.com -https://api.threatminer.org -https://api.threatstream.com -https://api.trustar.co -https://api.twilio.com -https://api.us.paloaltonetworks.com -https://api.us2.sumologic.com -https://api.xforce.ibmcloud.com -https://api.zerofox.com -https://api.zoom.us -https://apis.google.com -https://apiv2-us.devo.com -https://app.bitdam.com -https://app.kennasecurity.com -https://app.perchsecurity.com -https://app.phish.ai -https://app.recordedfuture.com -https://app.sndbox.com -https://apps.fireeye.com -https://apps.paloaltonetworks.com -https://apt.dockerproject.org -https://auth.docker.io -https://autofocus.paloaltonetworks.com -https://autoriteitpersoonsgegevens.nl -https://aws.amazon.com -https://backstory.googleapis.com -https://belovedcommunityusa.com -https://blogs.msdn.microsoft.com -https://boto3.amazonaws.com -https://bpa.paloaltonetworks.com -https://callback.url -https://caseapi.phishlabs.com -https://cdn-registry-1.docker.io -https://cdn.zerofox.com -https://censys.io -https://cloaken.cypherint.com -https://cloud.google.com -https://cloud.tenable.com -https://cloud.vmray.com -https://codeload.github.com -https://community.mimecast.com -https://confluence.atlassian.com -https://console.aws.amazon.com -https://console.cloud.google.com -https://console.developers.google.com. -https://container.googleapis.com -https://control.akamai.com -https://cve.mitre.org -https://dashboard.signalsciences.net -https://data.alexa.com -https://defense.conferdeploy.net -https://demisto.atlassian.net -https://demisto.com -https://demisto.managed-otrs.com -https://demisto.mock.mybrz.net -https://demisto.my.redcanary.co -https://demisto.secbi.com -https://demisto.zendesk.com -https://demistobot.demisto.com -https://demistohelp.freshdesk.com -https://democloud.countertack.com -https://demodev.backstory.chronicle.security -https://developer.akamai.com -https://developer.atlassian.com -https://developer.carbonblack.com -https://developer.ciscospark.com -https://developer.mozilla.org -https://developer.okta.com -https://developer.salesforce.com -https://developer.zendesk.com -https://developers.facebook.com -https://developers.freshdesk.com -https://developers.google.com -https://developers.redmarlin.ai -https://devo.com -https://discovery.etcd.io -https://dl.bintray.com -https://dns.google -https://dns.google.com -https://docs.aws.amazon.com -https://docs.bmc.com -https://docs.box.com -https://docs.devo.com -https://docs.docker.com -https://docs.docker.combash-4.3 -https://docs.extrahop.com -https://docs.google.com -https://docs.incapsula.com -https://docs.mcafee.com -https://docs.microsoft.com -https://docs.paloaltonetworks.com -https://docs.python.org -https://docs.snowflake.net -https://docs.software.hpe.com -https://docs.splunk.com -https://dodecahedron.freshdesk.com -https://domain.freshdesk.com -https://easylist.github.io -https://ec2.amazonaws.com -https://ec2.eu-central-1.amazonaws.com -https://ec2.region.amazonaws.com -https://ecertificatewala.com -https://en.wikipedia.org -https://etp.eu.fireeye.com -https://etp.us.fireeye.com -https://etp.us.fireeyegov.com -https://eu-api.mimecast.com -https://events.icebrg.io -https://events.pagerduty.com -https://example.awake.cloud -https://example.com -https://example.com. -https://example.looker.com -https://example.net -https://exchange.xforce.ibmcloud.com -https://experimental.docker.com -https://fake.devo.com -https://falcon.crowdstrike.com -https://falconapi.crowdstrike.com -https://fp.tools -https://freebirddemo.dev.ccs.thatcompany.net -https://gcr.io -https://gdpr-info.eu -https://geoip.maxmind.com -https://get.docker.com -https://get.k8s.io -https://github -https://github.com -https://google.com -https://graph.facebook.com -https://graph.microsoft.com -https://haveibeenpwned.com -https://help.canary.tools -https://help.github.com -https://help.rapid7.com -https://help.sumologic.com -https://help.symantec.com -https://helpcenter.threatq.com -https://hmrc.5-notifications.com -https://host -https://hub.docker.com -https://i.ytimg.com -https://icloud.com.uk-maps.info -https://ico.org.uk -https://img.youtube.com -https://index.docker.io -https://integration.cybereason.net -https://intelapi.crowdstrike.com -https://investigate-api.readme.io -https://investigate.api.umbrella.com -https://ioc.phishlabs.com -https://ipinfo.io -https://jbxcloud.joesecurity.org -https://jsonwhois.com -https://kb-healthcare.com -https://kb.tanium.com -https://kc.mcafee.com -https://lattice.s3.amazonaws.com -https://localhost -https://login.botframework.com -https://login.microsoftonline.com -https://login.salesforce.com -https://ltau-portal.com -https://lucene.apache.org -https://luminatepublicapi.docs.apiary.io -https://m2crypto.readthedocs.io -https://mail.google.com -https://malwr.com -https://management.azure.com -https://me.endgame.com -https://media.giphy.com -https://msdn.microsoft.com -https://mxtoolbox.com -https://my.domain.com -https://my.incapsula.com -https://myurl.com -https://nvlpubs.nist.gov -https://oauth2.googleapis.com -https://ogs.google.com -https://opendxl.github.io -https://openphish.com -https://oproxy.demisto.ninja -https://optusupdatemail.com -https://osquery.readthedocs.io -https://oti.slashnext.cloud -https://otx.alienvault.com -https://outlook.office365.com -https://panacea.threatgrid.com -https://partner.analystplatform.com -https://paulvmoreau.github.io -https://paypal.co.uk.6mon.icu -https://platform.risksense.com -https://polyswarm.network -https://portal-digitalshadows.com -https://protect.cylance.com -https://protectapi.cylance.com -https://provision.threatx.io -https://ps.compliance.protection.outlook.com -https://publicsuffix.org -https://pypi.org -https://raw.githubusercontent.com -https://rebrand.ly -https://report.icebrg.io -https://research.domaintools.com -https://risksense.atlassian.net -https://s3.us-west-2.amazonaws.com -https://safebrowsing.googleapis.com -https://sdk.cloud.google.com -https://securitycenter.windows.com -https://services.runescape.com-ey.top -https://smba.trafficmanager.net -https://software8n-chase.com -https://some_url.com -https://somedomain -https://splunkbase.splunk.com -https://stackoverflow.com -https://starlight.companyname.com -https://stixproject.github.io -https://support.demisto.com -https://support.google.com -https://support.paloaltonetworks.com -https://t.co -https://tagnet.app -https://takedown.netcraft.com -https://tap-api-v2.proofpoint.com -https://tc39.github.io -https://td-toolbelt.herokuapp.com -https://te.checkpoint.com -https://technet.microsoft.com -https://tenant.goskope.com -https://test -https://test.com -https://test1 -https://threatinsight.proofpoint.com -https://thumb.pipl.com -https://ticloud-aws1-api.reversinglabs.com -https://ticloud-cdn-api.reversinglabs.com -https://tools.emergingthreats.net -https://tools.ietf.org -https://unshorten.me -https://url -https://url-test.com -https://urldefense.com -https://urldefense.proofpoint.com -https://urlhaus-api.abuse.ch -https://urlscan.io -https://us.devo.com -https://usea1.sentinelone.net -https://v2.developer.pagerduty.com -https://vigilant.alienvault.cloud -https://vigilanteati.infoarmor.com -https://vm.frontline.cloud -https://vulndb.cyberriskanalytics.com -https://wiki.openoffice.org -https://wildfire.paloaltonetworks.com -https://ws.isitphishing.org -https://www.abuseipdb.com -https://www.agpd.es -https://www.akamai.com -https://www.alexa.com -https://www.algosec.com -https://www.alphasoc.com -https://www.americanas.semanasaldao.com -https://www.beyondtrust.com -https://www.blockade.io -https://www.circl.lu -https://www.cisco.com -https://www.cymon.io -https://www.demisto.com -https://www.elastic.co -https://www.example.com -https://www.extrahop.com -https://www.forescout.com -https://www.google.com -https://www.googleapis.com -https://www.hybrid-analysis.com -https://www.ibm.com -https://www.ip-rs.si -https://www.markdownguide.org -https://www.misp-project.org -https://www.monitoredsecurity.com -https://www.nltk.org -https://www.packetmail.net -https://www.packetsled.com -https://www.paloaltonetworks.com -https://www.phishlabs.com -https://www.sans.org -https://www.securityadvisor.io -https://www.test.com -https://www.threatcrowd.org -https://www.threathq.com -https://www.tufin.com -https://www.twilio.com -https://www.us-cert.gov -https://www.utlsapi.com -https://www.virustotal.com -https://www.youtube.com -https://www31.janeirodepromocao.com -https://www35.janeirodepromocao.com -https://x0m0s.weblium.site -https://your_company.easyvista.com -https://yt3.ggpht.com -https://zasobygwp.pl -info.dss@llv.li -info@aki.ee -info@autoriteitpersoonsgegevens.nl -info@cnpd.lu -info@dataprotection.ie -info@dvi.gov.lv -internacional@agpd.es -international.team@ico.org.uk -jane@acme.com -jeff@contoso.onmicrosoft.com -joe@example.com -john.doe@devo.com -john@acme.com -john@doe.com -john@domain.com -john@mypersonalblog.com -johnnydepp@gmail.com -koko@demisto.com -kzld@cpdp.bg -mayb@queen.com -members@odata.bind -mobi777@gmail.com -momo@demisto.com -name@demistodev.onmicrosoft.com -nexpose@placeholder.com -nobody@demistotest.com -nonexistingmmember@demisto.com -noreply@demisto.com -not@domain.com -foo@test.com -owners@odata.bind -peterfalvi.attila@naih.hu -posta@uoou.cz -postkasse@datatilsynet.no -poststelle@bfdi.bund.de -postur@personuvernd.is -recipient@dev.onmicrosoft.com -sentinel@placeholder.com -serviceadmins@contoso.onmicrosoft.com -site_test2@demistodev.onmicrosoft.com -someemail@test.com -somemail@test.com -somerandomemail@nodomain.net -foo@test.com -someuser@example.com -soso@demisto.com -splunk@placeholder.com -spongobob@demisto.com -statny.dozor@pdp.gov.sk -support@crowdstrike.com -support@crowdstrike.com. -support@cybertriage.com. -support@demisto.com -support@securityadvisor.io. -support@slashnext.com -support@threatx.com. -t1.txt@xxx.yyy -t2.txt@xxx.zzz -teamsApp@odata.bind -test@demisto.com -test@email.com -test@example.com -test@test.com -test@www.b -testpublic@demistodev.onmicrosoft.com -testtrainee@test.com -tietosuoja@om.fi -track@securityadvisor.io -ubuntu@130.211.103.14... -ubuntu@54.154.68.31 -user1@domain.com -user1@test.com -user@example.com -userthatdoesnotexist4@demisto.com -userthatdoesnotexist@demisto.com -vikramarsid@gmail.com -william19770319@yahoo.com -woo@demisto.com -wowo@demisto.com -172.22.14.237 -root@u-MacBook-Pro-2.local -user@u-MacBook-Pro-2.local -94.188.164.68 -192.168.1.76 -72.17.8.102 -info@flashpoint-intel.com -qicifomuejijika@o2.pl -92.63.197.153 -https://www.sammyboy.com -http://www.crdpro.su -210.122.7.129 -soc@phishlabs.com -47.75.33.100 -::a1:72:38:36 -23.123.123.65 -http://.1 -23.20.239.12 -file:Scripts/ReadPDFFileV2/test_data/encrypted.pdf -file:Scripts/ReadPDFFileV2/test_data/Docker-Cookbook.pdf -112.126.94.107 -68.232.135.242 -68.232.142.41 -46.98.200.157 -192.168.100.1 -1.125.227.13 -201.93.212.87 -108.177.127.102 -108.177.127.139 -108.177.15.138 -224.0.0.22 -108.177.15.113 -10.0.2.15 -108.177.15.101 -108.177.15.100 -10.0.2.2 -51.141.32.51 -216.58.206.238 -108.177.15.102 -239.255.255.250 -108.177.127.138 -10.0.2.255 -51.140.127.197 -108.177.127.101 -108.177.127.100 -108.177.122.139 -82.112.184.197 -108.177.127.113 -93.174.93.255 -80.82.77.139 -60.191.38.77 -82.211.30.0 -216.75.62.8 -93.174.93.1 -46.148.22.18 -7.77.7.7 -172.31.25.170 -3.2.3.2 -116.202.56.112 -80.227.43.146 -17.252.141.15 -10.100.100.66 -10.10.10.230 -10.10.10.243 -10.100.100.254 -80.80.80.146 -10.10.10.241 -112.56.202.116 -10.100.100.17 -10.10.10.21 -172.31.31.110 -112.175.209.72 -105.102.75.16 -172.18.20.20 -186.185.91.72 -104.236.48.178 -104.236.54.196 -5.5.255.25 -5.5.5.179 -181.61.87.106 -151.101.12.133 -172.31.37.106 -232.12.34.135 -91.140.64.113 -3.1.5.63 -3.2.4.54 -52.49.120.63 -99.80.149.227 -18.202.247.204 -73.92.194.57 -3.1.3.38 -3.122.240.42 -34.100.71.242 -98.234.105.153 -92.119.160.40 -77.247.110.59 -159.203.169.16 -185.176.27.118 -185.254.120.27 -85.93.20.34 -192.168.1.77 -151.101.0.0 -8.8.3.3 -77.8.77.8 -3.5.3.5 -5.7.5.7 -9.7.9.7 -55.7.55.7 -6.1.7.1 -4.7.4.7 -6.8.6.8 -44.2.44.2 -85.13.155.169 -52.86.122.241 -54.165.193.163 -52.15.91.198 -186.29.149.40 -23.7.44.197 -104.67.128.36 -96.16.84.130 -104.98.248.71 -173.222.24.202 -23.197.219.175 -23.212.29.129 -172.233.131.187 -204.12.0.50 -222.163.206.206 -172.231.209.35 -50.23.225.49 -172.228.24.209 -54.235.96.83 -192.168.39.128 -172.16.3.7 -::Dec -93.174.93.63 -1.2.0.1 -192.168.1.44 -192.168.1.8 -192.168.1.31 -192.168.1.52 -10.212.134.200 -172.31.46.243 -77.247.181.163 -11.0.0.2 -213.35.2.109 -192.168.5.172 -192.168.5.189 -192.168.138.158 -5.8.4.61 -150.242.117.189 -5.8.4.64 -172.22.100.85 -172.31.36.134 -172.31.36.196 -5.8.4.17 -8.36.116.16 -3.7.1.4 -108.177.121.101 -108.177.119.102 -108.177.12.101 -108.177.120.100 -108.177.10.102 -108.177.119.138 -108.177.12.139 -108.177.120.113 -108.177.111.113 -108.177.11.100 -108.177.112.139 -108.177.119.113 -108.177.122.113 -108.177.11.139 -108.177.12.100 -108.177.120.138 -108.177.119.100 -108.177.12.113 -108.177.121.100 -108.177.112.101 -108.177.122.138 -108.177.121.139 -108.177.120.139 -108.177.11.101 -108.177.120.101 -108.177.122.100 -108.177.119.101 -108.177.112.100 -108.177.111.102 -108.177.111.138 -108.177.112.102 -108.167.133.29 -108.177.111.100 -108.177.11.113 -108.177.112.138 -108.177.121.113 -108.177.12.138 -108.177.11.138 -108.177.122.101 -108.177.11.102 -108.177.12.102 -108.177.112.113 -108.177.121.138 -108.177.122.102 -108.177.120.102 -108.177.111.101 -108.177.121.102 -108.177.111.139 -108.177.119.139 -108.177.10.100 -95.181.249.58 -182.176.178.74 -192.168.2.81 -140.80.0.101 -3.0.2.8 -192.168.2.22 -67.143.208.113 -3.1.0.100 -11.1.0.0 -192.168.255.255 -172.16.90.1 -172.16.20.1 -10.248.100.74 -122.175.240.173 -113.186.213.226 -37.27.67.92 -184.105.192.2 -117.194.21.62 -9.0.01.001 -172.16.2.20 -162.236.53.68 -172.16.40.55 -10.0.0.6 -4.4.0.6 -185.72.179.152 -5.29.211.60 -6.7.4.1 -2.2.1.1 -172.31.33.227 -194.147.35.172 -39.41.26.166 -121.31.166.99 -182.91.129.207 -182.88.27.168 -184.168.221.52 -192.168.2.4 -54.39.20.14 -182.91.129.165 -50.63.202.51 -2001:db8:1234:1a00:: -::1234 -e1C::c -fe80:0000:0000:0000:91ba:7558:26d3:acde -fe80:0000:0000:0000:2811:397d:53e0:db3b -fe80:0000:0000:0000:04f9:deff:fe36:ddb0 -2001:0000:9d38:6ab8:2811:397d:53e0:db3b -fe80:0008:0000:0000:aede:48ff:fe00:1122 -fe80:0000:0000:0000:0000:5efe:ac1f:24c4 -charles@corp.com -newnsm@corp.com -jason@corp.com -socbncbc433amq6qhrb76000edcdhd3q@corp.com -socbncbc433amq6qhrb76ir3l0000edcdhd3q@corp.com -diana@corp.com -u003csoc@corp.com -SOC@corp.com -rachel@corp.com -int-sights.net -user1@mail.com -moviepropit.com -user@domain.com -malc0de.com -yandex.com -www.malwaredomainlist.com -zeustracker.abuse.ch -junk.name@jonk.com -content.any.run -app.any.run -a.co.il -e71ed0532685.o3n.io -192.168.1.43 -example2@gmail.com -pedmart@gmail.com -example1@gmail.com -jeffrey.collins@gmail.com -example3@gmail.com -sskymedia.com -name@company.com -replymail@company.com -test@company.com -tinyurl.com -someurl.com -badperson.com -tiny.url.com -john@wick.com -msdn.microsoft.com -test@demisto.int -ldap.com -demistoadmin@demisto.int -jack@company.com -paloalto-networks.alienvault.cloud -someemail@domain.com -foaas.com -admin@admin.test -email@gmail.com -group@dgmail.com -test@gmail.com -mcafee.com -jack@company.com -test@demisto.int -msdn.microsoft.com -demistoadmin@demisto.int -ldap.com -vassg142.crl.omniroot.com -http://vassg142.crl.omniroot.com -f5.com -reddit.com -canindia.com -obfuscated.com -news.8btc.com -user-images.githubusercontent.com -access.redhat.com -raw.githubusercontent.com -aws.amazon.com -archive.apache.org -16@gmail.com -foo@test.com -zoom.us -qlql.ru -icann.org -www.arkham-mass.com -kzkoicaalumni.com -kinaneevents.com -amandanovotny49.com -acre-services.com -www.markmonitor.com -abusecomplaints@markmonitor.com -icann.org -escenas.cl -actor@org.com -johndoe@test.org -test@that.com -target@org.com -54.190.157.130 -test@domain.com -jondoe@test.org -vectranetworks.com -autofocus.samples.id -autofocus.sessions.id -updates.cdc.carbonblack.io -wikis.uit.tufts.edu -stackedit.io -admin@company.com -sky-fraud.ru -bcbm4y7yusdxthg3.onion -www.technobuffalo.com -dummy1@hotmail.com -pastebin.com -apt.ripbigboss.com -bitshacking.com -www.lifewire.com -ibb.co -dummy2@sina.com -dummy3@hotmail.com -server -SERVER -216.128.82 -www.logtrust.com -skyformation.zendesk.com -portal.secureworks.com -example@aol.com -dev@demisto.works -www.example2.com%2Chttps -www.example2.com -WIN-CQD6UQJIA7J -sync.bigfix.com -content.demisto.works -https://github.com -www.vaultproject.io -csrgenerator.com -mar.services.name -mar.processes.id -mar.files.name -mar.processes.name -jane@company.com -john@company.com -email@company.com -alice@company.com -panda.tech-tw.com -panda.tech -azmwn.suliparwarda.com -suliparwarda.com -swagger.io -support.safebreach.com -foo@test.com -goo@test.com -194.147.35.172 -https://wiki.easyvista.com -https://support.symantec.com -grosspam@msn.com -njbur1111@yahoo.com -foo4@yahoo.com -nglennzenner@yahoo.com -foo6@yahoo.com -http://www. -foo7@yahoo.com -https://developer.pagerduty.com -user2@demisto.com -user1@demisto.com -test@this.com -https://cylanceephemeralfilestore.s3.amazonaws.com -owner@demisto.com -https://prov.core.ctp.secureworks.net -https://cloud.bitdam.com -192.168.2.125 -noreply@github.com -55035720example-user1@users.noreply.github.com -testuser@demisto.com -dbot@demisto.com -https://malicious1 -http://malicious2 -https://bestiankelly.com -onme@www1079.sakura.ne.jp -10.212.134.210 -http://domain.name -http://eclecticiq.domain.id -http://chstarkeco.com -http://eclecticiq.entity.id -http://eclecticiq.email.id -disco-team@stealthemail.com -http://eclecticiq.ip.id -http://eclecticiq.file.id -http://eclecticiq.entity.source.name -http://gooc.om -http://eclecticiq.url.id -http://eclecticiq.domain.name -http://www.cisco.com -1.2.3.99 -https://docs.umbrella.com -dns@google.com -56.1.1.1 -user@demisto.com -http://sigsciences.corp.site.blacklist.id -arian@demisto.com -goo@test.com -92.168.2.178 -or@example.com -se@example.com -192.168.2.195 -https://developer.microsoft.com -steve@demisto.com -https://nexpose.help.rapid7.com -10.200.104.236 -10.200.103.100 -rajguru2003@yahoo.com -http://aws.ec2.images.name -http://aws.ec2.instances.state.name -http://aws.ec2.instances.iaminstanceprofile.id -https://code.google.com -http://admin.google.com -test2@google.com -test@google.com -https://knowledgebase.paloaltonetworks.com -10.10.10.9 -69.172.200.235 -172.228.24.0 -37.235.50.29 -http://va872g.g90e1h.b8.642b63u.j985a2.v33e.37.pa269cc.e8mfzdgrf7g0.groupprograms.in -10.3.23.103 -192.254.233.44 -http://comarksecurity.com -104.27.188.52 -http://fidelis.alert.id -http://runlove.us -172.22.5.119 -52.52.210.187 -190.105.238.43 -176.121.14.95 -10.12.16.101 -52.9.23.208 -5.5.5.5 -https://www. -http://www.github.com -6.6.6.5 -9.5.9.62 -192.168.1.0 -192.168.1.57 -test@demistodev.onmicrosoft.com -oren@demistodev.onmicrosoft.com -22oren@demistodev.onmicrosoft.com -donaldt@demistodev.onmicrosoft.com -graph@demistodev.onmicrosoft.com -ore@demistdev.onmicrosoft.com -test2@demistodev.onmicrosoft.com -ore@demisodev.onmicrosoft.com -https://s3.amazonaws.com -clboone@freshdesk.com -mark.colbert@freshdesk.com -rachel@freshdesk.com -sam.ozzy@freshdesk.com -finchhoot1@freshdesk.com -james@freshdesk.com -lewis.clarke@freshdesk.com -joe.mathew@freshdesk.com -emily.dean@freshdesk.com -aroundtheworld80@freshdesk.com -sam.kart@freshdesk.com -soundofmusic@freshdesk.com -matt.rogers@freshdesk.com -support@demistohelp.freshdesk.com -bob.tree@freshdesk.com -johnny.appleseed@freshdesk.com -7.7.7.7 -http://www.bing.com -http://www.yahoo.com -https://go.microsoft.com -test@demistodev.onmicrosoft.com -dem@demistodev.onmicrosoft.com -some@dev.microsoft.com -test2@demistodev.onmicrosoft.com -https://eu-central-1.queue.amazonaws.com -https://ctgold.in.net -https://www. -mockmail@demistomock.com -admin@demistodev.com -http://www. -https://www. -https://twitter.com -https://support.recordedfuture.com -support@alphasoc.com -192.168.2.170 -9.9.4.4 -94.147.35.172 -mailonline_16@filposcv.com -176.228.66.70 -5.5.5.5 -http://action.name -https://s3.eu-central-1.amazonaws.com -shriki@demisto.com -http://www.pdf995.com -https://blogs. -::8080 -http://azmwn. -http://-tw.com -https://docs. -https://%2Chttps -55035720example.user1@users.noreply.github.com -https://api..com -https://xsoar.pan.dev -https://boto3. -https://. -https://.awake. -https://.com -https://. -https://s3.us-west-2. -https://.infoarmor.com -3.7.2.200 -https://api. -https://raw.user.com -https://public.org -https://help. -2.7.15.155 -23.223.223.233 -http://www.thisurlwillneverexist4444.co.il -98.222.222.9 -https://api..luminatesec.com -3.7.2.214 -::1760 -https://msdn. -98.222.222.9 -http://www.thisurlwillneverexist4444.co.il -23.223.223.233 -http://s. -https://s -https://os.readthedocs.io -https://.-otrs.com -https://demo.ertack.com -https://panacea.grid.com -https://ti-aws1-api.labs.com -https://ti-cdn-api.labs.com -http://docs.-s.org -https://public.org -http://wiki.now.com -https://oauth2. -https://acs. -https://public.org -http://forums. -https://s -https://ti-aws1-api.labs.com -https://api-us.log.com -https://panacea.grid.com -http://wiki.now.com -http://.nai.com -https://app.snd -https://demo.ertack.com -https://raw.user.com -https://kc. -https://m -http://bugs..org -https://provision.x.io -http://s..com -dev>@demistodev.onmicrosoft.com -"MicrosoftGraph.Draft.Sender" -"|ID|From|Sender|To|Subject|Body|BodyType|Cc|Bcc|Headers|Importance|MessageID|ConversationID|CreatedTime|SentTime|ReceivedTime|ModifiedTime|IsDraft|IsRead|" -"MicrosoftGraph.Email.subject" -"MicrosoftGraph.Draft.ConversationID" -"MSGraphMail.Folders.DisplayName" -"" -"MSGraphMail.Folders.ParentFolderID" -MSGraphMail.BCCRecipients.Name -"MicrosoftGraph.Draft.ReceivedTime" ->com> -MSGraphMail.CCRecipients.Address -MSGraphMail.CCRecipients.Name -MSGraphMailAttachment.UserID -"MSGraphMail.Folders.UnreadItemCount" -"MSGraphMail.Folders.TotalItemCount" -"MicrosoftGraph.Draft.IsRead" -MSGraphMail.MovedEmails.DestinationFolder -!msgraph-mail-update-folder -"|ID|Subject|SendTime|Sender|From|HasAttachments|Body|" -"MicrosoftGraph.Draft.Subject" -"MicrosoftGraph.Draft.SentTime" -MicrosoftGraph.Email.internetMessage -"MSGraphMailAttachment.ID" -dev@demistodev.onmicrosoft.com -"new_folder_name=\"Testing\"```" -"MSGraphMail.MovedEmails.ID" -AM6PR07MB44530DA96C2DF255705F30FD83CA0@AM6PR07MB4453.eurprdx07.prod.outlook.com -"MicrosoftGraph.Draft.BodyType" -"|ChildFolderCount|DisplayName|ID|ParentFolderID|TotalItemCount|UnreadItemCount|" -"MicrosoftGraph.Draft.ModifiedTime" -"MSGraphMail.Folders.ChildFolderCount" -"MSGraphMail.Folders.ID" -"MSGraphMail.ReplyTo.Address" -MSGraphMail.BCCRecipients.Address -"MSGraphMail.LastModifiedTime" -"MicrosoftGraph.Email.body" -"MicrosoftGraph.Email.importance" -MicrosoftGraph.Email.ccRecipients -"MicrosoftGraph.Draft.CreatedTime" -"MicrosoftGraph.Email.bodyPreview" -"MicrosoftGraph.Email.toRecipients" -"|body|flag|importance|subject|toRecipients|" -MSGraphMail.MovedEmails.User -MicrosoftGraph.Email.bccRecipients -"AM6PR07MB44530DA96C2DF255705F30FD83CA0@AM6PR07MB4453.eurprd07.prod.outlook." -MSGraphMail.Folders.talItemCount -MicrosoftGraph.Email.Preview -MSGraphMailAttachment.User -AM6PR07MB44530DA96C2DF255705F30FD83CA0@AM6PR07MB4453.eurprd07.prod.outlook -dev@dev.on -https://.com -https://msdn..com -https://stix..io -headers=MULTIPART_HEADERS, -Required -Argument -#h_9330372011351545913868554 -Required -boolean -#h_8372857491141544959433947 -Path -Attivo.User.IsDeceptive -attacker_ip -#h_923142110971545913776046 -Type -#h_5165200802171544959442597 -#h_5588456511921545913911620 -bpa.paloaltos.com -https://bpa diff --git a/Packs/Legacy/CHANGELOG.md b/Packs/Legacy/CHANGELOG.md deleted file mode 100644 index 4117bdc5e161..000000000000 --- a/Packs/Legacy/CHANGELOG.md +++ /dev/null @@ -1,2 +0,0 @@ -## [Unreleased] -- \ No newline at end of file diff --git a/Packs/Legacy/README.md b/Packs/Legacy/README.md deleted file mode 100644 index f0aed1335aae..000000000000 --- a/Packs/Legacy/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Legacy Content Pack - diff --git a/Packs/Legacy/pack_metadata.json b/Packs/Legacy/pack_metadata.json deleted file mode 100644 index 17637540fe33..000000000000 --- a/Packs/Legacy/pack_metadata.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "Legacy Content", - "description": "Old format content items", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-03-09T16:35:16Z", - "categories": [], - "tags": [], - "useCases": [ - "content" - ], - "keywords": [] -} \ No newline at end of file From 0230fd22ed5952b6343f5f7083b4c5030090f229 Mon Sep 17 00:00:00 2001 From: Lior Blobstein Date: Wed, 10 Jun 2020 11:00:54 +0300 Subject: [PATCH 020/200] Delete Exchange pack (#7433) --- Packs/Exchange/.pack-ignore | 0 Packs/Exchange/.secrets-ignore | 0 Packs/Exchange/CHANGELOG.md | 1 - Packs/Exchange/README.md | 0 Packs/Exchange/pack_metadata.json | 16 ---------------- 5 files changed, 17 deletions(-) delete mode 100644 Packs/Exchange/.pack-ignore delete mode 100644 Packs/Exchange/.secrets-ignore delete mode 100644 Packs/Exchange/CHANGELOG.md delete mode 100644 Packs/Exchange/README.md delete mode 100644 Packs/Exchange/pack_metadata.json diff --git a/Packs/Exchange/.pack-ignore b/Packs/Exchange/.pack-ignore deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/Packs/Exchange/.secrets-ignore b/Packs/Exchange/.secrets-ignore deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/Packs/Exchange/CHANGELOG.md b/Packs/Exchange/CHANGELOG.md deleted file mode 100644 index 723f2f878c2b..000000000000 --- a/Packs/Exchange/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -## [Unreleased] \ No newline at end of file diff --git a/Packs/Exchange/README.md b/Packs/Exchange/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/Packs/Exchange/pack_metadata.json b/Packs/Exchange/pack_metadata.json deleted file mode 100644 index 018ad29db02a..000000000000 --- a/Packs/Exchange/pack_metadata.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "Exchange", - "description": "Query exchange servers with PowerShell queries.", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-06-01T13:40:44Z", - "categories": [ - "Utilities" - ], - "tags": [], - "useCases": [], - "keywords": [] -} \ No newline at end of file From 2ee8e6d9b86e2d8a15bd493bc49d6d9588627e7f Mon Sep 17 00:00:00 2001 From: Agam Date: Wed, 10 Jun 2020 11:45:44 +0300 Subject: [PATCH 021/200] Add the GetShiftsPerUser automation (#7213) * Add the GetShiftsPerUser automation * Add current user to script and fix bad check for GetOnCallHoursPerUser * Style guides * Remove unusedimports * Remove used vars * Add a better output type * Fix imports * Release notes of bug in GetOnCallHoursPerUser * Fix the tests * Fix the eslint lines too long * Fix eslint changelog * release notes * docker tags * Fix the output * Add related tests * Add header for the markdown * Update Packs/ShiftManagement/ReleaseNotes/1_1_0.md Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> * Eslint * Shifts per user * Trailing whitespace * RN * Docker version * Tests + imports * Debug tests * Debug tests 2 * Debug tests 3 * Debug 4 * Debug 5 * Debug 6 * Debug 7 * Debug 8 * Debug 9 * Debug 10 * Debug 12 * Fix mock result * Fix mock result * linting * Flake8 * Updated * Updated. Co-authored-by: Agam More Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> Co-authored-by: Alex Fiedler <38628621+kirbles19@users.noreply.github.com> --- Packs/ShiftManagement/ReleaseNotes/1_1_0.md | 3 + .../GetOnCallHoursPerUser/CHANGELOG.md | 4 +- .../GetOnCallHoursPerUser.py | 2 +- .../GetOnCallHoursPerUser.yml | 2 +- .../Scripts/GetShiftsPerUser/CHANGELOG.md | 2 + .../GetShiftsPerUser/GetShiftsPerUser.py | 110 +++++++ .../GetShiftsPerUser/GetShiftsPerUser.yml | 23 ++ .../GetShiftsPerUser/GetShiftsPerUser_test.py | 82 +++++ .../Scripts/GetShiftsPerUser/Pipfile | 19 ++ .../Scripts/GetShiftsPerUser/Pipfile.lock | 305 ++++++++++++++++++ Packs/ShiftManagement/pack_metadata.json | 24 +- 11 files changed, 560 insertions(+), 16 deletions(-) create mode 100644 Packs/ShiftManagement/ReleaseNotes/1_1_0.md create mode 100644 Packs/ShiftManagement/Scripts/GetShiftsPerUser/CHANGELOG.md create mode 100644 Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.py create mode 100644 Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.yml create mode 100644 Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser_test.py create mode 100644 Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile create mode 100644 Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile.lock diff --git a/Packs/ShiftManagement/ReleaseNotes/1_1_0.md b/Packs/ShiftManagement/ReleaseNotes/1_1_0.md new file mode 100644 index 000000000000..9816d2546675 --- /dev/null +++ b/Packs/ShiftManagement/ReleaseNotes/1_1_0.md @@ -0,0 +1,3 @@ +### Scripts +- __GetOnCallHoursPerUser__ +- __GetShiftsPerUser__ diff --git a/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/CHANGELOG.md b/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/CHANGELOG.md index c1b1725cbee1..2e0e25706492 100644 --- a/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/CHANGELOG.md +++ b/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/CHANGELOG.md @@ -1,6 +1,6 @@ ## [Unreleased] - +Fixed error handling of the getUsers call. ## [20.4.1] - 2020-04-29 #### New Script -Retrieves number of on-call hours per user. \ No newline at end of file +Retrieves number of on-call hours per user. diff --git a/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.py b/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.py index a21213971b02..c596f5c255d7 100644 --- a/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.py +++ b/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.py @@ -33,7 +33,7 @@ def main(): else: hours_per_user: Dict[str, int] = {} get_users_response: List = demisto.executeCommand('getUsers', {}) - if is_error(get_roles_response): + if is_error(get_users_response): demisto.error(f'Failed to get users: {str(get_error(get_users_response))}') else: users = get_users_response[0]['Contents'] diff --git a/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.yml b/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.yml index 44f81c199c79..a498e82f0df1 100644 --- a/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.yml +++ b/Packs/ShiftManagement/Scripts/GetOnCallHoursPerUser/GetOnCallHoursPerUser.yml @@ -12,5 +12,5 @@ subtype: python3 system: false timeout: '0' type: python -dockerimage: demisto/python3:3.8.2.6981 +dockerimage: demisto/python3:3.8.3.8715 fromversion: 5.5.0 diff --git a/Packs/ShiftManagement/Scripts/GetShiftsPerUser/CHANGELOG.md b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/CHANGELOG.md new file mode 100644 index 000000000000..3f6dba076059 --- /dev/null +++ b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/CHANGELOG.md @@ -0,0 +1,2 @@ +## [Unreleased] +Retrieves the shifts per user. \ No newline at end of file diff --git a/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.py b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.py new file mode 100644 index 000000000000..3be3a18a104e --- /dev/null +++ b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.py @@ -0,0 +1,110 @@ +import demistomock as demisto +from CommonServerPython import * +from CommonServerUserPython import * +from typing import List + +HOURS_DAYS_HEADER = 'Hours / Days' +SUNDAY_HEADER = 'Sunday' +MONDAY_HEADER = 'Monday' +TUESDAY_HEADER = 'Tuesday' +WEDNESDAY_HEADER = 'Wednesday' +THURSDAY_HEADER = 'Thursday' +FRIDAY_HEADER = 'Friday' +SATURDAY_HEADER = 'Saturday' + +DAY_NUM_TO_DAY_HEADER = { + 0: SUNDAY_HEADER, + 1: MONDAY_HEADER, + 2: TUESDAY_HEADER, + 3: WEDNESDAY_HEADER, + 4: THURSDAY_HEADER, + 5: FRIDAY_HEADER, + 6: SATURDAY_HEADER +} + + +def time_fix(t): + # If the time is a single number padd it with zeros + if t // 10 < 1: + return '0' + str(t) + return str(t) + + +def main(): + user_id = demisto.args().get('userId', False) + if not user_id: + get_users_res: List = demisto.executeCommand("getUsers", + {"current": True}) + if is_error(get_users_res): + return_error( + f'Failed to get users: {str(get_error(get_users_res))}') + contents = get_users_res[0] + if contents and len(contents.get("Contents")) == 1: + user_id = contents.get("Contents")[0].get("id") + else: + return_error(f'Failed to get users: User object is empty') + + get_roles_response: List = demisto.executeCommand('getRoles', {}) + if is_error(get_roles_response): + return_error( + f'Failed to get roles: {str(get_error(get_roles_response))}') + + get_users_response: List = demisto.executeCommand('getUsers', {}) + if is_error(get_users_response): + return_error( + f'Failed to get users: {str(get_error(get_users_response))}') + + users = get_users_response[0]['Contents'] + user = [u for u in users if u.get("id", False) == user_id] + if len(user) == 0: + return_error(f'Failed to find user: {str(user_id)}') + + user = user[0] + user_roles = user.get("allRoles", []) + if len(user_roles) == 0: + demisto.error(f'Failed to find roles for user: {str(user_id)}') + demisto.results([]) + + roles = get_roles_response[0]['Contents'] + shifts_of_user = [r.get("shifts") for r in roles if + r.get("shifts", False) and r.get("name") in user_roles] + if len(shifts_of_user) == 0: + demisto.error(f'Failed to find shifts for user: {str(user_id)}') + demisto.results([]) + + shifts_of_user = [s for rshifts in shifts_of_user for s in rshifts] + + shifts_of_user_readable = [] + for s in shifts_of_user: + from_day = DAY_NUM_TO_DAY_HEADER[s.get("fromDay")] + from_hour = time_fix(s.get("fromHour")) + from_minute = time_fix(s.get("fromMinute")) + to_day = DAY_NUM_TO_DAY_HEADER[s.get("toDay")] + to_hour = time_fix(s.get("toHour")) + to_minute = time_fix(s.get("toMinute")) + shifts_of_user_readable.append( + [f'{from_day} {from_hour}:{from_minute}', + f'{to_day} {to_hour}:{to_minute}']) + + HEADERS = ["Start", "End"] + + shifts_table = [ + { + HEADERS[0]: shift[0], + HEADERS[1]: shift[1], + } for shift in shifts_of_user_readable + ] + + demisto.results({ + 'Type': entryTypes['note'], + 'ContentsFormat': formats['markdown'], + 'Contents': tableToMarkdown( + name=f'{user.get("name", user_id)}\'s Shifts', + t=shifts_table, + headers=HEADERS + ) + }) + + +if __name__ in ('__builtin__', 'builtins', '__main__'): + main() diff --git a/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.yml b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.yml new file mode 100644 index 000000000000..114aa05ea3c9 --- /dev/null +++ b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser.yml @@ -0,0 +1,23 @@ +args: + - default: false + description: The user ID for which to get the number of on-call hours for the shift (e.g. johndoe). + isArray: false + name: userId + required: false + secret: false +comment: Retrieves the number of on-call hours per user. +commonfields: + id: GetShiftsPerUser + version: -1 +enabled: false +name: GetShiftsPerUser +script: '-' +tags: +- Shift Management +- widget +subtype: python3 +system: false +timeout: '0' +type: python +dockerimage: demisto/python3:3.8.3.8715 +fromversion: 5.5.0 diff --git a/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser_test.py b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser_test.py new file mode 100644 index 000000000000..4786957fbeb9 --- /dev/null +++ b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/GetShiftsPerUser_test.py @@ -0,0 +1,82 @@ +import demistomock as demisto +from GetShiftsPerUser import main + +ROLES = [ + { + 'name': 'Shift1', + 'shifts': [ + {'fromDay': 0, 'fromHour': 8, 'fromMinute': 0, 'toDay': 3, + 'toHour': 12, 'toMinute': 0}, + {'fromDay': 4, 'fromHour': 16, 'fromMinute': 0, 'toDay': 6, + 'toHour': 20, 'toMinute': 0} + ] + }, + { + 'name': 'Administrator', + 'shifts': None + }, + { + 'name': 'Shift2', + 'shifts': [ + {'fromDay': 0, 'fromHour': 8, 'fromMinute': 0, 'toDay': 3, + 'toHour': 12, 'toMinute': 0}, + {'fromDay': 4, 'fromHour': 16, 'fromMinute': 0, 'toDay': 6, + 'toHour': 20, 'toMinute': 0}, + {'fromDay': 1, 'fromHour': 3, 'fromMinute': 0, 'toDay': 4, + 'toHour': 6, 'toMinute': 0} + ] + } +] + +USERS = [ + { + 'Type': 1, + 'Contents': [ + { + 'id': 'user1', + 'name': 'User1', + 'roles': { + 'demisto': ['Shift1'] + }, + "allRoles": ['Shift1', 'Administrator'] + }, + { + 'id': 'admin', + 'name': 'Admin', + 'roles': { + 'demisto': ['Administrator'] + }, + "allRoles": ['Administrator'] + } + ] + } +] + +GET_ROLES_RESPONSE = [{ + 'Type': 1, + 'Contents': ROLES +}] + + +def execute_command(name, args=None): + if name == 'getRoles': + return GET_ROLES_RESPONSE + elif name == 'getUsers': + return USERS + else: + return None + + +def test_get_shifts_per_user(mocker): + mocker.patch.object(demisto, 'executeCommand', side_effect=execute_command) + mocker.patch.object(demisto, 'results') + mocker.patch.object(demisto, 'args', return_value={'userId': 'user1'}) + main() + results = demisto.results.call_args[0] + assert len(results) == 1 + assert """### User1's Shifts +|Start|End| +|---|---| +| Sunday 08:00 | Wednesday 12:00 | +| Thursday 16:00 | Saturday 20:00 | +""" in results[0]['Contents'] diff --git a/Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile new file mode 100644 index 000000000000..aad46817ca2f --- /dev/null +++ b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile @@ -0,0 +1,19 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] +pylint = "*" +pytest = "==5.0.1" +pytest-mock = "*" +requests-mock = "*" +pytest-asyncio = "*" +pytest-xdist = "*" +freezegun = "*" +pytest-datadir-ng = "*" + +[packages] + +[requires] +python_version = "3.8" diff --git a/Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile.lock b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile.lock new file mode 100644 index 000000000000..190fd5a5cfa3 --- /dev/null +++ b/Packs/ShiftManagement/Scripts/GetShiftsPerUser/Pipfile.lock @@ -0,0 +1,305 @@ +{ + "_meta": { + "hash": { + "sha256": "78de325ac8977e10eb7a8c420f45ae4f30ef63f3cc33dd7323061d79eb840415" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": {}, + "develop": { + "apipkg": { + "hashes": [ + "sha256:37228cda29411948b422fae072f57e31d3396d2ee1c9783775980ee9c9990af6", + "sha256:58587dd4dc3daefad0487f6d9ae32b4542b185e1c36db6993290e7c41ca2b47c" + ], + "version": "==1.5" + }, + "astroid": { + "hashes": [ + "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", + "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42" + ], + "version": "==2.3.3" + }, + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", + "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + ], + "version": "==19.3.0" + }, + "certifi": { + "hashes": [ + "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", + "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" + ], + "version": "==2019.11.28" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "execnet": { + "hashes": [ + "sha256:cacb9df31c9680ec5f95553976c4da484d407e85e41c83cb812aa014f0eddc50", + "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547" + ], + "version": "==1.7.1" + }, + "freezegun": { + "hashes": [ + "sha256:2a4d9c8cd3c04a201e20c313caf8b6338f1cfa4cda43f46a94cc4a9fd13ea5e7", + "sha256:edfdf5bc6040969e6ed2e36eafe277963bdc8b7c01daeda96c5c8594576c9390" + ], + "index": "pypi", + "version": "==0.3.12" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "importlib-metadata": { + "hashes": [ + "sha256:073a852570f92da5f744a3472af1b61e28e9f78ccf0c9117658dc32b15de7b45", + "sha256:d95141fbfa7ef2ec65cfd945e2af7e5a6ddbd7c8d9a25e66ff3be8e3daf9f60f" + ], + "markers": "python_version <= '3.8'", + "version": "==1.3.0" + }, + "isort": { + "hashes": [ + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + ], + "version": "==4.3.21" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", + "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", + "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", + "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", + "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", + "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", + "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", + "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", + "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", + "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", + "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", + "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", + "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", + "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", + "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", + "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", + "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", + "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", + "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", + "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", + "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" + ], + "version": "==1.4.3" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "more-itertools": { + "hashes": [ + "sha256:b84b238cce0d9adad5ed87e745778d20a3f8487d0f0cb8b8a586816c7496458d", + "sha256:c833ef592a0324bcc6a60e48440da07645063c453880c9477ceb22490aec1564" + ], + "version": "==8.0.2" + }, + "packaging": { + "hashes": [ + "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47", + "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108" + ], + "version": "==19.2" + }, + "pluggy": { + "hashes": [ + "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", + "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" + ], + "version": "==0.13.1" + }, + "py": { + "hashes": [ + "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa", + "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0" + ], + "version": "==1.8.1" + }, + "pylint": { + "hashes": [ + "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", + "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4" + ], + "index": "pypi", + "version": "==2.4.4" + }, + "pyparsing": { + "hashes": [ + "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f", + "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec" + ], + "version": "==2.4.6" + }, + "pytest": { + "hashes": [ + "sha256:6ef6d06de77ce2961156013e9dff62f1b2688aa04d0dc244299fe7d67e09370d", + "sha256:a736fed91c12681a7b34617c8fcefe39ea04599ca72c608751c31d89579a3f77" + ], + "index": "pypi", + "version": "==5.0.1" + }, + "pytest-asyncio": { + "hashes": [ + "sha256:9fac5100fd716cbecf6ef89233e8590a4ad61d729d1732e0a96b84182df1daaf", + "sha256:d734718e25cfc32d2bf78d346e99d33724deeba774cc4afdf491530c6184b63b" + ], + "index": "pypi", + "version": "==0.10.0" + }, + "pytest-datadir-ng": { + "hashes": [ + "sha256:0d9e0212eaa4d0440a4b7c3d2df4b4b7eeebde1854ab383c5aff590764ad8a52", + "sha256:7fec7a4996a12529a935512c128624fa7289495b520fd31b4645c3a71daa394e" + ], + "index": "pypi", + "version": "==1.1.1" + }, + "pytest-forked": { + "hashes": [ + "sha256:1805699ed9c9e60cb7a8179b8d4fa2b8898098e82d229b0825d8095f0f261100", + "sha256:1ae25dba8ee2e56fb47311c9638f9e58552691da87e82d25b0ce0e4bf52b7d87" + ], + "version": "==1.1.3" + }, + "pytest-mock": { + "hashes": [ + "sha256:67e414b3caef7bff6fc6bd83b22b5bc39147e4493f483c2679bc9d4dc485a94d", + "sha256:e24a911ec96773022ebcc7030059b57cd3480b56d4f5d19b7c370ec635e6aed5" + ], + "index": "pypi", + "version": "==1.13.0" + }, + "pytest-xdist": { + "hashes": [ + "sha256:0f46020d3d9619e6d17a65b5b989c1ebbb58fc7b1da8fb126d70f4bac4dfeed1", + "sha256:7dc0d027d258cd0defc618fb97055fbd1002735ca7a6d17037018cf870e24011" + ], + "index": "pypi", + "version": "==1.31.0" + }, + "python-dateutil": { + "hashes": [ + "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", + "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" + ], + "version": "==2.8.1" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "version": "==2.22.0" + }, + "requests-mock": { + "hashes": [ + "sha256:510df890afe08d36eca5bb16b4aa6308a6f85e3159ad3013bac8b9de7bd5a010", + "sha256:88d3402dd8b3c69a9e4f9d3a73ad11b15920c6efd36bc27bf1f701cf4a8e4646" + ], + "index": "pypi", + "version": "==1.7.0" + }, + "six": { + "hashes": [ + "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", + "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + ], + "version": "==1.13.0" + }, + "typed-ast": { + "hashes": [ + "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", + "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + ], + "markers": "implementation_name == 'cpython' and python_version <= '3.8'", + "version": "==1.4.0" + }, + "urllib3": { + "hashes": [ + "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", + "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745" + ], + "version": "==1.25.7" + }, + "wcwidth": { + "hashes": [ + "sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603", + "sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8" + ], + "version": "==0.1.8" + }, + "wrapt": { + "hashes": [ + "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" + ], + "version": "==1.11.2" + }, + "zipp": { + "hashes": [ + "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", + "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + ], + "version": "==0.6.0" + } + } +} diff --git a/Packs/ShiftManagement/pack_metadata.json b/Packs/ShiftManagement/pack_metadata.json index cde7d655f2d5..9c7004e00334 100644 --- a/Packs/ShiftManagement/pack_metadata.json +++ b/Packs/ShiftManagement/pack_metadata.json @@ -1,14 +1,14 @@ { - "name": "Shift Management", - "description": "Shift management related content", - "support": "xsoar", - "currentVersion": "1.0.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-04-01T08:30:00Z", - "categories": [], - "tags": [], - "useCases": [], - "keywords": [] + "name": "Shift Management", + "description": "Shift management related content", + "support": "xsoar", + "currentVersion": "1.1.0", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-04-01T08:30:00Z", + "categories": [], + "tags": [], + "useCases": [], + "keywords": [] } \ No newline at end of file From 52371f9df3f4229cfc3db20eee14ac740ddf0c26 Mon Sep 17 00:00:00 2001 From: Shai Yaakovi <30797606+yaakovi@users.noreply.github.com> Date: Wed, 10 Jun 2020 13:03:26 +0300 Subject: [PATCH 022/200] ignore missing CHANGELOG failures (#7482) * Update config.yml * Update config.yml --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7521cc95ff43..fff336f8e193 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -171,10 +171,10 @@ jobs: fi if [ -n "${GITHUB_TOKEN}" ] ; then - python3 release_notes.py $CONTENT_VERSION $GIT_SHA1 $CIRCLE_BUILD_NUM $SERVER_VERSION --github-token $GITHUB_TOKEN + python3 release_notes.py $CONTENT_VERSION $GIT_SHA1 $CIRCLE_BUILD_NUM $SERVER_VERSION --github-token $GITHUB_TOKEN || echo "ignore errors" else - python3 release_notes.py $CONTENT_VERSION $GIT_SHA1 $CIRCLE_BUILD_NUM $SERVER_VERSION + python3 release_notes.py $CONTENT_VERSION $GIT_SHA1 $CIRCLE_BUILD_NUM $SERVER_VERSION || echo "ignore errors" fi - run: name: Common Server Documentation From 453d71acbca7df10294642dd889984c821d861c7 Mon Sep 17 00:00:00 2001 From: Bar Hochman <11165655+jochman@users.noreply.github.com> Date: Wed, 10 Jun 2020 13:13:03 +0300 Subject: [PATCH 023/200] demistomock.py formatting (#7483) --- Tests/demistomock/demistomock.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Tests/demistomock/demistomock.py b/Tests/demistomock/demistomock.py index ff068e3ff8b1..40c286b827c2 100644 --- a/Tests/demistomock/demistomock.py +++ b/Tests/demistomock/demistomock.py @@ -381,7 +381,7 @@ "workPlan": "https://test-address:8443/#/WorkPlan/7ab2ac46-4142-4af8-8cbe-538efb4e63d6", } -callingContext = {} +callingContext = {} # type: dict def params(): @@ -542,35 +542,45 @@ def mirrorInvestigation(id, mirrorType, autoClose=False): def updateModuleHealth(error): return "" -def directMessage(message, username = None, email = None, anyoneCanOpenIncidents = None): + +def directMessage(message, username=None, email=None, anyoneCanOpenIncidents=None): return "" -def createIncidents(incidents, lastRun = None, userID = None): + +def createIncidents(incidents, lastRun=None, userID=None): return [] -def findUser(username = None, email = None): + +def findUser(username=None, email=None): return {} + def handleEntitlementForUser(incidentID, guid, email, content, taskID=""): return {} + def demistoVersion(): return { 'version': '5.5.0', 'buildNumber': '12345' } + def integrationInstance(): return "" + def createIndicators(indicators_batch): return "" -def searchIndicators(fromdate = '', query = '', size = 100, page = 0, todate = '', value = ''): + +def searchIndicators(fromdate='', query='', size=100, page=0, todate='', value=''): return {} + def getIndexHash(): return '' + def getLicenseID(): return '' From f6c79ee63327bcb06fe56df9a1f46957c25b8858 Mon Sep 17 00:00:00 2001 From: hod Date: Wed, 10 Jun 2020 13:47:44 +0300 Subject: [PATCH 024/200] Fixed print when GCS_MARKET_KEY is not set (#7486) * Fixed print when GCS_MARKET_KEY is not set * Skipping a step in contribution Co-authored-by: halpert --- .circleci/config.yml | 4 ++++ Tests/scripts/prepare_content_packs_for_testing.sh | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fff336f8e193..9dcd099980a7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -309,6 +309,10 @@ jobs: echo 'Skipping - running only in container number 0.' exit 0; fi + if [[ $CIRCLE_BRANCH =~ pull/[0-9]+ ]]; then + echo "Skipping, Should not run on contributor's branch." + exit 0 + fi ./Tests/scripts/prepare_content_packs_for_testing.sh - run: name: Zip Content Packs From GCS diff --git a/Tests/scripts/prepare_content_packs_for_testing.sh b/Tests/scripts/prepare_content_packs_for_testing.sh index edfe969f2696..ef452ba52852 100644 --- a/Tests/scripts/prepare_content_packs_for_testing.sh +++ b/Tests/scripts/prepare_content_packs_for_testing.sh @@ -11,7 +11,7 @@ ID_SET=$CIRCLE_ARTIFACTS/id_set.json EXTRACT_FOLDER=$(mktemp -d) if [[ -z "$GCS_MARKET_KEY" ]]; then - echo "$GCS_MARKET_KEY not set aborting!" + echo "GCS_MARKET_KEY not set aborting!" exit 1 fi @@ -64,4 +64,4 @@ echo -e "https://console.cloud.google.com/storage/browser/$BUCKET_FULL_TARGET_PA echo "Finished preparing content packs for testing successfully." echo -e "\nIf you want to connect this build bucket to your test machine, add this server config:" -echo "marketplace.bootstrap.bypass.url: https://storage.googleapis.com/$BUCKET_FULL_TARGET_PATH" \ No newline at end of file +echo "marketplace.bootstrap.bypass.url: https://storage.googleapis.com/$BUCKET_FULL_TARGET_PATH" From 900b38add47757c4c9d7f842f9dc2091ffc301cb Mon Sep 17 00:00:00 2001 From: Ika Gabashvili <45535078+IkaDemisto@users.noreply.github.com> Date: Wed, 10 Jun 2020 15:00:33 +0300 Subject: [PATCH 025/200] fixed build images paths (#7450) --- Tests/Marketplace/marketplace_services.py | 30 +++++++++++++++-------- Tests/Marketplace/upload_packs.py | 8 +++--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Tests/Marketplace/marketplace_services.py b/Tests/Marketplace/marketplace_services.py index 9f348e72f71c..0c339b21b427 100644 --- a/Tests/Marketplace/marketplace_services.py +++ b/Tests/Marketplace/marketplace_services.py @@ -28,7 +28,8 @@ class GCPConfig(object): """ Google cloud storage basic configurations """ - STORAGE_BASE_PATH = "content/packs" # base path for packs in gcs + STORAGE_BASE_PATH = "content/packs" # configurable base path for packs in gcs, can be modified + IMAGES_BASE_PATH = "content/packs" # images packs prefix stored in metadata STORAGE_CONTENT_PATH = "content" # base path for content in gcs USE_GCS_RELATIVE_PATH = True # whether to use relative path in uploaded to gcs images GCS_PUBLIC_URL = "https://storage.googleapis.com" # disable-secrets-detection @@ -1099,15 +1100,21 @@ def upload_integration_images(self, storage_bucket): image_name = os.path.basename(image_path) image_storage_path = os.path.join(pack_storage_root_path, image_name) pack_image_blob = storage_bucket.blob(image_storage_path) - print(f"Uploading {self._pack_name} pack integration image: {image_name}") + print(f"Uploading {self._pack_name} pack integration image: {image_name}") with open(image_path, "rb") as image_file: pack_image_blob.upload_from_file(image_file) - uploaded_integration_images.append({ - 'name': image_data.get('display_name', ''), - 'imagePath': urllib.parse.quote(pack_image_blob.name) if GCPConfig.USE_GCS_RELATIVE_PATH - else pack_image_blob.public_url - }) + + if GCPConfig.USE_GCS_RELATIVE_PATH: + image_gcs_path = urllib.parse.quote( + os.path.join(GCPConfig.IMAGES_BASE_PATH, self._pack_name, image_name)) + else: + image_gcs_path = pack_image_blob.public_url + + uploaded_integration_images.append({ + 'name': image_data.get('display_name', ''), + 'imagePath': image_gcs_path + }) print(f"Uploaded {len(pack_local_images)} images for {self._pack_name} pack.") except Exception as e: @@ -1144,12 +1151,15 @@ def upload_author_image(self, storage_bucket): with open(author_image_path, "rb") as author_image_file: pack_author_image_blob.upload_from_file(author_image_file) - author_image_storage_path = pack_author_image_blob.name if GCPConfig.USE_GCS_RELATIVE_PATH \ - else pack_author_image_blob.public_url + if GCPConfig.USE_GCS_RELATIVE_PATH: + author_image_storage_path = urllib.parse.quote( + os.path.join(GCPConfig.IMAGES_BASE_PATH, self._pack_name, Pack.AUTHOR_IMAGE_NAME)) + else: + author_image_storage_path = pack_author_image_blob.public_url print_color(f"Uploaded successfully {self._pack_name} pack author image", LOG_COLORS.GREEN) elif self.support_type == Metadata.XSOAR_SUPPORT: # use default Base pack image for xsoar supported packs - author_image_storage_path = os.path.join(GCPConfig.STORAGE_BASE_PATH, GCPConfig.BASE_PACK, + author_image_storage_path = os.path.join(GCPConfig.IMAGES_BASE_PATH, GCPConfig.BASE_PACK, Pack.AUTHOR_IMAGE_NAME) # disable-secrets-detection if not GCPConfig.USE_GCS_RELATIVE_PATH: diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 8ad5ec37f036..45f26a6e1933 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -496,7 +496,7 @@ def option_handler(): parser.add_argument('-k', '--key_string', help="Base64 encoded signature key used for signing packs.", required=False) parser.add_argument('-pb', '--private_bucket_name', help="Private storage bucket name", required=False) - parser.add_argument('-sb', '--storage_bash_path', help="Storage base path of the directory to upload to.", + parser.add_argument('-sb', '--storage_base_path', help="Storage base path of the directory to upload to.", required=False) parser.add_argument('-rt', '--remove_test_playbooks', type=str2bool, help='Should remove test playbooks from content packs or not.', default=True) @@ -517,15 +517,15 @@ def main(): signature_key = option.key_string id_set_path = option.id_set_path packs_dependencies_mapping = load_json(option.pack_dependencies) if option.pack_dependencies else {} - storage_bash_path = option.storage_bash_path + storage_base_path = option.storage_base_path remove_test_playbooks = option.remove_test_playbooks # google cloud storage client initialized storage_client = init_storage_client(service_account) storage_bucket = storage_client.bucket(storage_bucket_name) - if storage_bash_path: - GCPConfig.STORAGE_BASE_PATH = storage_bash_path + if storage_base_path: + GCPConfig.STORAGE_BASE_PATH = storage_base_path # detect packs to upload modified_packs = get_modified_packs(target_packs) From f6599b09206a0755be6c20560ac8b765f87f4aed Mon Sep 17 00:00:00 2001 From: Ika Gabashvili <45535078+IkaDemisto@users.noreply.github.com> Date: Wed, 10 Jun 2020 15:20:01 +0300 Subject: [PATCH 026/200] Packs changelog - added build number to display name (#7279) * added build number to pack changelog * switched brackets to dash in changelog version * added versionInfo field * fixed doc strings * added versionInfo to unit test --- .../Tests/marketplace_services_test.py | 23 ++++++--- Tests/Marketplace/marketplace_services.py | 48 ++++++++++++++----- Tests/Marketplace/upload_packs.py | 5 +- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/Tests/Marketplace/Tests/marketplace_services_test.py b/Tests/Marketplace/Tests/marketplace_services_test.py index 36f62c6fd69b..8a7b122421d2 100644 --- a/Tests/Marketplace/Tests/marketplace_services_test.py +++ b/Tests/Marketplace/Tests/marketplace_services_test.py @@ -1,6 +1,7 @@ import pytest import json import os +import random from unittest.mock import mock_open from Tests.Marketplace.marketplace_services import Pack, Metadata, input_to_list, get_valid_bool, convert_price, \ get_higher_server_version, GCPConfig @@ -28,7 +29,8 @@ def test_validate_all_fields_of_parsed_metadata(self, dummy_pack_metadata): """ parsed_metadata = Pack._parse_pack_metadata(user_metadata=dummy_pack_metadata, pack_content_items={}, pack_id='test_pack_id', integration_images=[], author_image="", - dependencies_data={}, server_min_version="5.5.0") + dependencies_data={}, server_min_version="5.5.0", + build_number="dummy_build_number") assert parsed_metadata['name'] == 'Test Pack Name' assert parsed_metadata['id'] == 'test_pack_id' assert parsed_metadata['description'] == 'Description of test pack' @@ -44,6 +46,7 @@ def test_validate_all_fields_of_parsed_metadata(self, dummy_pack_metadata): assert parsed_metadata['price'] == 0 assert parsed_metadata['serverMinVersion'] == '5.5.0' assert parsed_metadata['currentVersion'] == '2.3.0' + assert parsed_metadata['versionInfo'] == "dummy_build_number" assert parsed_metadata['tags'] == ["tag number one", "Tag number two"] assert parsed_metadata['categories'] == ["Messaging"] assert parsed_metadata['contentItems'] == {} @@ -58,7 +61,8 @@ def test_parsed_metadata_empty_input(self): """ parsed_metadata = Pack._parse_pack_metadata(user_metadata={}, pack_content_items={}, pack_id='test_pack_id', integration_images=[], author_image="", - dependencies_data={}, server_min_version="dummy_server_version") + dependencies_data={}, server_min_version="dummy_server_version", + build_number="dummy_build_number") assert parsed_metadata['name'] == "test_pack_id" assert parsed_metadata['id'] == "test_pack_id" @@ -80,7 +84,8 @@ def test_parsed_metadata_with_price(self, pack_metadata_input, expected, mocker) mocker.patch("Tests.Marketplace.marketplace_services.print_warning") parsed_metadata = Pack._parse_pack_metadata(user_metadata=pack_metadata_input, pack_content_items={}, pack_id="test_pack_id", integration_images=[], author_image="", - dependencies_data={}, server_min_version="dummy_server_version") + dependencies_data={}, server_min_version="dummy_server_version", + build_number="dummy_build_number") assert parsed_metadata['price'] == expected @@ -243,7 +248,8 @@ def test_prepare_release_notes_first_run(self, mocker, dummy_pack): """ mocker.patch("os.path.exists", return_value=False) dummy_path = 'Irrelevant/Test/Path' - result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path) + build_number = random.randint(0, 100000) + result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path, build_number=build_number) assert result is True def test_prepare_release_notes_upgrade_version(self, mocker, dummy_pack): @@ -274,7 +280,8 @@ def test_prepare_release_notes_upgrade_version(self, mocker, dummy_pack): }''' mocker.patch('builtins.open', mock_open(read_data=original_changelog)) dummy_path = 'Irrelevant/Test/Path' - result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path) + build_number = random.randint(0, 100000) + result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path, build_number=build_number) assert result is True def test_prepare_release_notes_upgrade_version_mismatch(self, mocker, dummy_pack): @@ -306,7 +313,8 @@ def test_prepare_release_notes_upgrade_version_mismatch(self, mocker, dummy_pack }''' mocker.patch('builtins.open', mock_open(read_data=original_changelog)) dummy_path = 'Irrelevant/Test/Path' - result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path) + build_number = random.randint(0, 100000) + result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path, build_number=build_number) assert result is False def test_prepare_release_notes_upgrade_version_dup(self, mocker, dummy_pack): @@ -339,7 +347,8 @@ def test_prepare_release_notes_upgrade_version_dup(self, mocker, dummy_pack): }''' mocker.patch('builtins.open', mock_open(read_data=original_changelog)) dummy_path = 'Irrelevant/Test/Path' - result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path) + build_number = random.randint(0, 100000) + result = Pack.prepare_release_notes(self=dummy_pack, index_folder_path=dummy_path, build_number=build_number) assert result is True def test_clean_release_notes_lines(self): diff --git a/Tests/Marketplace/marketplace_services.py b/Tests/Marketplace/marketplace_services.py index 0c339b21b427..2f52efe3b30a 100644 --- a/Tests/Marketplace/marketplace_services.py +++ b/Tests/Marketplace/marketplace_services.py @@ -404,7 +404,7 @@ def _get_author(support_type, author=None): @staticmethod def _parse_pack_metadata(user_metadata, pack_content_items, pack_id, integration_images, author_image, - dependencies_data, server_min_version): + dependencies_data, server_min_version, build_number): """ Parses pack metadata according to issue #19786 and #20091. Part of field may change over the time. Args: @@ -415,6 +415,7 @@ def _parse_pack_metadata(user_metadata, pack_content_items, pack_id, integration author_image (str): gcs uploaded author image dependencies_data (dict): mapping of pack dependencies data, of all levels. server_min_version (str): server minimum version found during the iteration over content items. + build_number (str): circleCI build number. Returns: dict: parsed pack metadata. @@ -440,6 +441,7 @@ def _parse_pack_metadata(user_metadata, pack_content_items, pack_id, integration pack_metadata['price'] = convert_price(pack_id=pack_id, price_value_input=user_metadata.get('price')) pack_metadata['serverMinVersion'] = user_metadata.get('serverMinVersion') or server_min_version pack_metadata['currentVersion'] = user_metadata.get('currentVersion', '') + pack_metadata['versionInfo'] = build_number pack_metadata['tags'] = input_to_list(input_data=user_metadata.get('tags')) pack_metadata['categories'] = input_to_list(input_data=user_metadata.get('categories'), capitalize_input=True) pack_metadata['contentItems'] = pack_content_items @@ -621,12 +623,13 @@ def upload_to_storage(self, zip_pack_path, latest_version, storage_bucket, overr print_error(f"Failed in uploading {self._pack_name} pack to gcs. Additional info:\n {e}") return task_status, True - def prepare_release_notes(self, index_folder_path): + def prepare_release_notes(self, index_folder_path, build_number): """ Handles the creation and update of the changelog.json files. Args: index_folder_path (str): Path to the unzipped index json. + build_number (str): circleCI build number. Returns: bool: whether the operation succeeded. """ @@ -658,10 +661,14 @@ def prepare_release_notes(self, index_folder_path): changelog = json.load(changelog_file) if latest_release_notes in changelog: - shutil.copyfile(changelog_index_path, - os.path.join(self._pack_path, Pack.CHANGELOG_JSON)) - print_warning(f"Found existing release notes for version: {latest_release_notes} " - f"in the {self._pack_name} pack.") + changelog[latest_release_notes][ # update latest release notes build numbers + 'displayName'] = f'{latest_release_notes} - {build_number}' + # write back the updated build number to the changelog in pack the folder + with open(os.path.join(self._pack_path, Pack.CHANGELOG_JSON), 'w') as pack_changelog: + json.dump(changelog, pack_changelog, indent=4) + + print(f"Found existing release notes for version: {latest_release_notes} " + f"in the {self._pack_name} pack.") task_status = True return task_status @@ -672,7 +679,7 @@ def prepare_release_notes(self, index_folder_path): changelog_lines = changelog_md.read() changelog_lines = self._clean_release_notes(changelog_lines) version_changelog = {'releaseNotes': changelog_lines, - 'displayName': latest_release_notes, + 'displayName': f'{latest_release_notes} - {build_number}', 'released': datetime.utcnow().strftime(Metadata.DATE_FORMAT)} changelog[latest_release_notes] = version_changelog @@ -680,13 +687,28 @@ def prepare_release_notes(self, index_folder_path): json.dump(changelog, f, indent=4) else: # will enter only on initial version and release notes folder still was not created - shutil.copyfile(changelog_index_path, os.path.join(self._pack_path, Pack.CHANGELOG_JSON)) - print(f"Keeping existing {Pack.CHANGELOG_JSON} of {self._pack_name} pack.") + with open(changelog_index_path, "r") as changelog_file: + changelog = json.load(changelog_file) + + if len(changelog.keys()) > 1 or Pack.PACK_INITIAL_VERSION not in changelog: + print_error( + f"{self._pack_name} pack mismatch between {Pack.CHANGELOG_JSON} and {Pack.RELEASE_NOTES}") + task_status = False + return task_status + + changelog[Pack.PACK_INITIAL_VERSION][ # update latest release notes build numbers + 'displayName'] = f'{Pack.PACK_INITIAL_VERSION} - {build_number}' + # write back the updated build number to the changelog in pack the folder + with open(os.path.join(self._pack_path, Pack.CHANGELOG_JSON), 'w') as pack_changelog: + json.dump(changelog, pack_changelog, indent=4) + + print(f"Found existing release notes for version: {Pack.PACK_INITIAL_VERSION} " + f"in the {self._pack_name} pack.") elif self._current_version == Pack.PACK_INITIAL_VERSION: changelog = {} version_changelog = {'releaseNotes': self._description, - 'displayName': Pack.PACK_INITIAL_VERSION, + 'displayName': f'{Pack.PACK_INITIAL_VERSION} - {build_number}', 'released': datetime.utcnow().strftime(Metadata.DATE_FORMAT)} changelog[Pack.PACK_INITIAL_VERSION] = version_changelog @@ -900,7 +922,7 @@ def load_user_metadata(self): return task_status, user_metadata def format_metadata(self, user_metadata, pack_content_items, integration_images, author_image, index_folder_path, - packs_dependencies_mapping): + packs_dependencies_mapping, build_number): """ Re-formats metadata according to marketplace metadata format defined in issue #19786 and writes back the result. @@ -912,6 +934,7 @@ def format_metadata(self, user_metadata, pack_content_items, integration_images, author_image (str): uploaded public gcs path to author image. index_folder_path (str): downloaded index folder directory path. packs_dependencies_mapping (dict): all packs dependencies lookup mapping. + build_number (str): circleCI build number. Returns: bool: True is returned in case metadata file was parsed successfully, otherwise False. @@ -941,7 +964,8 @@ def format_metadata(self, user_metadata, pack_content_items, integration_images, integration_images=integration_images, author_image=author_image, dependencies_data=dependencies_data, - server_min_version=self.server_min_version) + server_min_version=self.server_min_version, + build_number=build_number) with open(metadata_path, "w") as metadata_file: json.dump(formatted_metadata, metadata_file, indent=4) # writing back parsed metadata diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 45f26a6e1933..25f66c461e5a 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -576,13 +576,14 @@ def main(): task_status = pack.format_metadata(user_metadata=user_metadata, pack_content_items=pack_content_items, integration_images=integration_images, author_image=author_image, index_folder_path=index_folder_path, - packs_dependencies_mapping=packs_dependencies_mapping) + packs_dependencies_mapping=packs_dependencies_mapping, + build_number=build_number) if not task_status: pack.status = PackStatus.FAILED_METADATA_PARSING.name pack.cleanup() continue - task_status = pack.prepare_release_notes(index_folder_path) + task_status = pack.prepare_release_notes(index_folder_path, build_number) if not task_status: pack.status = PackStatus.FAILED_RELEASE_NOTES.name pack.cleanup() From 97698ab06546c3565e269d2a7f7a544862f232da Mon Sep 17 00:00:00 2001 From: Shahaf Ben Yakir <44666568+ShahafBenYakir@users.noreply.github.com> Date: Wed, 10 Jun 2020 15:21:50 +0300 Subject: [PATCH 027/200] Nightly failures (#7317) * Skipped nightly failures * Un-skipped infoblox * Skipped tonight's failing tests * Skipping failing tests * Skipping failing tests * Skipped traps * Skipped traps * Added timeout to "Digital Defense FrontlineVM - Scan Asset Not Recently Scanned Test * Skipped Digital Defense FrontlineVM - Scan Asset Not Recently Scanned Test * Skipped Digital Defense FrontlineVM - Scan Asset Not Recently Scanned Test * Skipped Test - Cofense Intelligence * Skipped Test - Cofense Intelligence --- Tests/conf.json | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Tests/conf.json b/Tests/conf.json index 5d31bdafcb1a..9f18602de20c 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -2836,12 +2836,15 @@ ], "skipped_tests": { + "RedLockTest": "Issue 24600", + "Test - Cofense Intelligence": "Issue 25498", + "Digital Defense FrontlineVM - Scan Asset Not Recently Scanned Test": "Issue 25477", + "Test-IsMaliciousIndicatorFound": "Issue 24398", "SentinelOne V2 - test": "Issue 24933", "DuoAdmin API test playbook": "Issue 24937", "Wildfire Test": "Issue 24936", "SignalSciences-Test": "Issue 24934", "Maltiverse Test": "Issue 24335", - "Cisco Umbrella Test": "Issue 24338", "TestDedupIncidentsPlaybook": "Issue 24344", "Prisma_Access_Egress_IP_Feed-Test": "unskip after we will get PrismaAccess instance", "Prisma_Access-Test": "unskip after we will get PrismaAccess instance", @@ -2854,7 +2857,6 @@ "Bluecat Address Manager test": "Issue 22616", "test-Expanse": "Expanse should provide domain that they have in their system", "TestProofpointFeed": "Issue 22229", - "Digital Defense FrontlineVM - Scan Asset Not Recently Scanned Test": "Issue 22227", "Test-Detonate URL - Crowdstrike": "Issue 19439", "Git_Integration-Test": "Issue 20029", "Symantec Data Loss Prevention - Test": "Issue 20134", @@ -2894,12 +2896,14 @@ }, "skipped_integrations": { "_comment1": "~~~ NO INSTANCE ~~~", + "Traps": "Issue 24122", + "McAfee Advanced Threat Defense": "Issue 16909", + "Cisco Umbrella Investigate": "Issue 24338", "Deep Instinct": "The partner didn't provide an instance", "Cofense Triage v2": "No instance - partner integration", "ArcSight Logger": "Issue 24303", "AttackIQFireDrill": "Issue 24281", "MxToolBox": "No instance", - "Traps": "Issue 24122", "Skyformation": "No instance, old partner", "PrismaAccess": "Instance will be provided soon by Lior and Prasen", "AlphaSOC Network Behavior Analytics": "No instance", @@ -2915,7 +2919,6 @@ "Cisco CloudLock": "No instance", "SentinelOne": "No instance", "Vectra v2": "No instance", - "Infoblox": "Issue 23770", "Trend Micro Apex": "Issue 23632", "Awake Security": "Issue 23376", "ExtraHop": "No license, issue 23731", @@ -3028,7 +3031,6 @@ ], "unmockable_integrations": { "SNDBOX": "Submits a file - tests that send files shouldn't be mocked", - "Test-IsMaliciousIndicatorFound": "Issue 24398", "Maltiverse": "issue 24335", "MITRE ATT&CK": "Using taxii2client package", "MongoDB": "Our instance not using SSL", From 8c85884a101b35f14589d1d12080118bca09ad60 Mon Sep 17 00:00:00 2001 From: Shai Yaakovi <30797606+yaakovi@users.noreply.github.com> Date: Wed, 10 Jun 2020 15:56:46 +0300 Subject: [PATCH 028/200] Update XDR_iocs.yml (#7494) --- Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml index dc271068a153..babb32aad8ab 100644 --- a/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml +++ b/Packs/XDR_iocs/Integrations/XDR_iocs/XDR_iocs.yml @@ -90,7 +90,6 @@ configuration: required: false type: 1 - defaultvalue: 'true' - hidden: true name: feedIncremental required: false type: 8 From af2259cdc0bf142acfedf8e96b433b86734a0219 Mon Sep 17 00:00:00 2001 From: Ika Gabashvili <45535078+IkaDemisto@users.noreply.github.com> Date: Wed, 10 Jun 2020 16:13:28 +0300 Subject: [PATCH 029/200] Uploader - changed upload corepacks.json logic (#7487) * changed upload corepacks.json logic * added sys.exit(1) in case of failure --- Tests/Marketplace/upload_packs.py | 54 +++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/Tests/Marketplace/upload_packs.py b/Tests/Marketplace/upload_packs.py index 25f66c461e5a..8d63ccaa01bc 100644 --- a/Tests/Marketplace/upload_packs.py +++ b/Tests/Marketplace/upload_packs.py @@ -264,34 +264,54 @@ def upload_index_to_storage(index_folder_path, extract_destination_path, index_b print_color(f"Finished uploading {GCPConfig.INDEX_NAME}.zip to storage.", LOG_COLORS.GREEN) -def upload_core_packs_config(storage_bucket, packs_list, build_number): - """Uploads corepacks.json file configuration to bucket. corepacks file includes core packs for server installation. +def upload_core_packs_config(storage_bucket, build_number, index_folder_path): + """Uploads corepacks.json file configuration to bucket. Corepacks file includes core packs for server installation. Args: storage_bucket (google.cloud.storage.bucket.Bucket): gcs bucket where core packs config is uploaded. - packs_list (list): list of initialized packs. build_number (str): circleCI build number. + index_folder_path (str): The index folder path. """ - # todo later check if it is not pre release and only then upload corepacks.json - core_packs_public_urls = [c.public_storage_path for c in packs_list if - c.name in GCPConfig.CORE_PACKS_LIST and c.public_storage_path] + core_packs_public_urls = [] + found_core_packs = set() + + for pack in os.scandir(index_folder_path): + if pack.is_dir() and pack.name in GCPConfig.CORE_PACKS_LIST: + pack_metadata_path = os.path.join(index_folder_path, pack.name, Pack.METADATA) - if not core_packs_public_urls: - print(f"No core packs detected, skipping {GCPConfig.CORE_PACK_FILE_NAME} upload") - return + if not os.path.exists(pack_metadata_path): + print_error(f"{pack.name} pack {Pack.METADATA} is missing in {GCPConfig.INDEX_NAME}") + sys.exit(1) + + with open(pack_metadata_path, 'r') as metadata_file: + metadata = json.load(metadata_file) - if len(core_packs_public_urls) != len(GCPConfig.CORE_PACKS_LIST): - print_warning(f"Found core packs does not match configured core packs. " - f"Found {len(core_packs_public_urls)} and configured {len(GCPConfig.CORE_PACKS_LIST)}, " - f"skipping {GCPConfig.CORE_PACK_FILE_NAME} upload") + pack_current_version = metadata.get('currentVersion', Pack.PACK_INITIAL_VERSION) + core_pack_relative_path = os.path.join(GCPConfig.STORAGE_BASE_PATH, pack.name, + pack_current_version, f"{pack.name}.zip") + core_pack_public_url = os.path.join(GCPConfig.GCS_PUBLIC_URL, storage_bucket.name, core_pack_relative_path) + + if not storage_bucket.blob(core_pack_relative_path).exists(): + print_error(f"{pack.name} pack does not exist under {core_pack_relative_path} path") + sys.exit(1) + + core_packs_public_urls.append(core_pack_public_url) + found_core_packs.add(pack.name) + + if len(found_core_packs) != len(GCPConfig.CORE_PACKS_LIST): + missing_core_packs = set(GCPConfig.CORE_PACKS_LIST) ^ found_core_packs + print_error(f"Number of defined core packs are: {len(GCPConfig.CORE_PACKS_LIST)}") + print_error(f"Actual number of found core packs are: {len(found_core_packs)}") + print_error(f"Missing core packs are: {missing_core_packs}") + sys.exit(1) # construct core pack data with public gcs urls core_packs_data = { 'corePacks': core_packs_public_urls, 'buildNumber': build_number } - + # upload core pack json file to gcs core_packs_config_path = os.path.join(GCPConfig.STORAGE_BASE_PATH, GCPConfig.CORE_PACK_FILE_NAME) blob = storage_bucket.blob(core_packs_config_path) blob.upload_from_string(json.dumps(core_packs_data, indent=4)) @@ -635,12 +655,12 @@ def main(): pack.status = PackStatus.SUCCESS.name + # upload core packs json to bucket + upload_core_packs_config(storage_bucket, build_number, index_folder_path) + # finished iteration over content packs upload_index_to_storage(index_folder_path, extract_destination_path, index_blob, build_number, private_packs) - # upload core packs json to bucket - upload_core_packs_config(storage_bucket, packs_list, build_number) - # upload id_set.json to bucket upload_id_set(storage_bucket, id_set_path) From 246f7d26051895c59e99d0e122525015208240a9 Mon Sep 17 00:00:00 2001 From: Ido van Dijk <43602124+idovandijk@users.noreply.github.com> Date: Wed, 10 Jun 2020 18:17:55 +0300 Subject: [PATCH 030/200] Updated video link for Crisus Management (#7496) * Updated video link * moved video to pack readme * http = https * fix RNs Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> --- .../Employee_Status_Survey_README.md | 5 +- .../Playbooks/Process_Survey_Response.yml | 2 +- Packs/CrisisManagement/README.md | 1 + Packs/CrisisManagement/ReleaseNotes/1_1_0.md | 4 +- Packs/CrisisManagement/ReleaseNotes/1_1_1.md | 5 ++ Packs/CrisisManagement/pack_metadata.json | 48 +++++++++---------- 6 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 Packs/CrisisManagement/ReleaseNotes/1_1_1.md diff --git a/Packs/CrisisManagement/Playbooks/Employee_Status_Survey_README.md b/Packs/CrisisManagement/Playbooks/Employee_Status_Survey_README.md index a7d073f0f20a..e45b258aec00 100644 --- a/Packs/CrisisManagement/Playbooks/Employee_Status_Survey_README.md +++ b/Packs/CrisisManagement/Playbooks/Employee_Status_Survey_README.md @@ -32,7 +32,4 @@ There are no outputs for this playbook. ## Playbook Image --- -![Employee_Status_Survey](https://raw.githubusercontent.com/demisto/content/ec6cda315c0d1e15cf36a3c93cc936dd90dfbc48/Packs/CrisisManagement/doc_files/Employee_Status_Survey.png) - -## Playbook Demo Video -[Crisis Management in Cortex XSOAR](https://www.youtube.com/watch?v=J6DcD5y5B_U "Crisis Management in Cortex XSOAR") +![Employee_Status_Survey](https://raw.githubusercontent.com/demisto/content/ec6cda315c0d1e15cf36a3c93cc936dd90dfbc48/Packs/CrisisManagement/doc_files/Employee_Status_Survey.png) \ No newline at end of file diff --git a/Packs/CrisisManagement/Playbooks/Process_Survey_Response.yml b/Packs/CrisisManagement/Playbooks/Process_Survey_Response.yml index 2d8ec83434d2..a883be1f9b0b 100644 --- a/Packs/CrisisManagement/Playbooks/Process_Survey_Response.yml +++ b/Packs/CrisisManagement/Playbooks/Process_Survey_Response.yml @@ -1317,7 +1317,7 @@ fromversion: 5.5.0 tests: - No tests (auto formatted) description: "Note: This is a beta playbook, which lets you implement and test pre-release - software. Since the playbook is beta, it might contain bugs. Updates to the playbook + software. Since the playbook is in beta, it might contain bugs. Updates to the playbook during the beta phase might include non-backward compatible features. We appreciate your feedback on the quality and usability of the playbook to help us identify issues, fix them, and continually improve. This playbook processes the survery responses. It updates that the employee responded to the survey and what their health status is. If necessary, it opens IT or HR incidents, and updates the process survey tracker." diff --git a/Packs/CrisisManagement/README.md b/Packs/CrisisManagement/README.md index e69de29bb2d1..133daa252856 100644 --- a/Packs/CrisisManagement/README.md +++ b/Packs/CrisisManagement/README.md @@ -0,0 +1 @@ +[![Crisis Management in Cortex XSOAR](https://img.youtube.com/vi/J6DcD5y5B_U/0.jpg)](https://www.youtube.com/watch?v=J6DcD5y5B_U "Crisis Management in Cortex XSOAR") \ No newline at end of file diff --git a/Packs/CrisisManagement/ReleaseNotes/1_1_0.md b/Packs/CrisisManagement/ReleaseNotes/1_1_0.md index 93a9477ab5b4..1ee969dd62ef 100644 --- a/Packs/CrisisManagement/ReleaseNotes/1_1_0.md +++ b/Packs/CrisisManagement/ReleaseNotes/1_1_0.md @@ -1,3 +1,3 @@ - \ No newline at end of file diff --git a/Packs/CrisisManagement/ReleaseNotes/1_1_1.md b/Packs/CrisisManagement/ReleaseNotes/1_1_1.md new file mode 100644 index 000000000000..58dfda4719cf --- /dev/null +++ b/Packs/CrisisManagement/ReleaseNotes/1_1_1.md @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/Packs/CrisisManagement/pack_metadata.json b/Packs/CrisisManagement/pack_metadata.json index 5e2814a9ab42..bd31a79e3578 100644 --- a/Packs/CrisisManagement/pack_metadata.json +++ b/Packs/CrisisManagement/pack_metadata.json @@ -1,25 +1,25 @@ -{ - "name": "Crisis Management", - "description": "Manage crises such as pandemics or other events that would change the conditions under which employees would normally work. Note: This is a beta pack, which lets you implement and test pre-release software. Since the pack is beta, it might contain bugs. Updates to the pack during the beta phase might include non-backward compatible features. We appreciate your feedback on the quality and usability of the pack to help us identify issues, fix them, and continually improve.", - "support": "xsoar", - "certification": "", - "currentVersion": "1.1.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "categories": [ - "Case Management" - ], - "tags": [ - "Crisis", - "Pandemic", - "Remote Work", - "COVID-19" - ], - "created": "2020-05-06T08:54:47Z", - "updated": "2020-05-06T08:54:47Z", - "useCases": [ - "Crisis Management" - ], - "keywords": [] +{ + "name": "Crisis Management", + "description": "Manage crises such as pandemics or other events that would change the conditions under which employees would normally work. Note: This is a beta pack, which lets you implement and test pre-release software. Since the pack is beta, it might contain bugs. Updates to the pack during the beta phase might include non-backward compatible features. We appreciate your feedback on the quality and usability of the pack to help us identify issues, fix them, and continually improve.", + "support": "xsoar", + "certification": "", + "currentVersion": "1.1.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "categories": [ + "Case Management" + ], + "tags": [ + "Crisis", + "Pandemic", + "Remote Work", + "COVID-19" + ], + "created": "2020-05-06T08:54:47Z", + "updated": "2020-05-06T08:54:47Z", + "useCases": [ + "Crisis Management" + ], + "keywords": [] } \ No newline at end of file From 4f0782f315671c691beaabad318ffb6222f57771 Mon Sep 17 00:00:00 2001 From: Dean Arbel Date: Wed, 10 Jun 2020 18:25:59 +0300 Subject: [PATCH 031/200] [New Integration] EWS O365 (OAuth 2) (#7145) * created new branch with files from original branch * changed name to EWS O365 * changed app name * fixed service based and item based commands * fixed recover_soft_delete_item * added external files (test playbook, picture detailed description) * created readme and removed impersonation and mark_as_read fields * added test infrastructure * removed dev code * updated fetch logic to use last_modified_time * moved files to EWS pack * added rn and test * reformatted redame * removed ews-search-mailboxes * build fix * changed insecure logic * fixed test playbook * added proxy support * added constants and max incidents per fetch validation * style changes + added support for target_mailbox in get_folder and create_folder * Updated * moved ews v1 to deprecated * added docstrings * added back ews v1 to ews pack - will be moved to deprecated in a future PR * reverted changes to ewsv2 * removed ErrorInvalidPropertyRequest * added descriptions for test playbook-EWS_O365_test.yml * moved description a level deeper * added test for public folders * added descriptions to test playbook tasks * added descriptions to test playbook tasks * updated docker image * added fromversion to test playbook Co-authored-by: Alex Fiedler <38628621+kirbles19@users.noreply.github.com> --- Packs/EWS/.secrets-ignore | 16 + Packs/EWS/Integrations/EWSO365/CHANGELOG.md | 2 + Packs/EWS/Integrations/EWSO365/EWSO365.py | 2081 ++++++++++++++ Packs/EWS/Integrations/EWSO365/EWSO365.yml | 1051 +++++++ .../EWSO365/EWSO365_description.md | 6 + .../Integrations/EWSO365/EWSO365_image.png | Bin 0 -> 3275 bytes .../EWS/Integrations/EWSO365/EWSO365_test.py | 148 + Packs/EWS/Integrations/EWSO365/Pipfile | 18 + Packs/EWS/Integrations/EWSO365/Pipfile.lock | 369 +++ Packs/EWS/Integrations/EWSO365/README.md | 1354 +++++++++ .../EWSO365/test_data/commands_outputs.json | 2441 +++++++++++++++++ .../EWSO365/test_data/raw_responses.json | 2426 ++++++++++++++++ Packs/EWS/Integrations/EWSv2/README.md | 4 +- Packs/EWS/ReleaseNotes/1_1_0.md | 4 + .../TestPlaybooks/playbook-EWS_O365_test.yml | 859 ++++++ Packs/EWS/pack_metadata.json | 2 +- Tests/conf.json | 5 + 17 files changed, 10783 insertions(+), 3 deletions(-) create mode 100644 Packs/EWS/Integrations/EWSO365/CHANGELOG.md create mode 100644 Packs/EWS/Integrations/EWSO365/EWSO365.py create mode 100644 Packs/EWS/Integrations/EWSO365/EWSO365.yml create mode 100644 Packs/EWS/Integrations/EWSO365/EWSO365_description.md create mode 100644 Packs/EWS/Integrations/EWSO365/EWSO365_image.png create mode 100644 Packs/EWS/Integrations/EWSO365/EWSO365_test.py create mode 100644 Packs/EWS/Integrations/EWSO365/Pipfile create mode 100644 Packs/EWS/Integrations/EWSO365/Pipfile.lock create mode 100644 Packs/EWS/Integrations/EWSO365/README.md create mode 100644 Packs/EWS/Integrations/EWSO365/test_data/commands_outputs.json create mode 100644 Packs/EWS/Integrations/EWSO365/test_data/raw_responses.json create mode 100644 Packs/EWS/ReleaseNotes/1_1_0.md create mode 100644 Packs/EWS/TestPlaybooks/playbook-EWS_O365_test.yml diff --git a/Packs/EWS/.secrets-ignore b/Packs/EWS/.secrets-ignore index ed3dd016074c..5dcba5d33605 100644 --- a/Packs/EWS/.secrets-ignore +++ b/Packs/EWS/.secrets-ignore @@ -26,3 +26,19 @@ https://docs..com test@dev.on.com https:// https://docs +2603:10a6:20b:6e:cafe::20 +10.152.3.80 +2603:10a6:10:72::46 +CALOVw6vw2eOojGdALXwyz_McutDOuDfs_qecQSkph0yxwY_5tg@mail.gmail.com +2603:10a6:20b:6e::48 +209.85.161.69 +2002:a05:6808:106:: +67.231.156.123 +2603:10a6:20b:f0::25 +2603:10a6:20b:2e::32 +2603:10a6:803:d4::19 +2603:10a6:10:72:cafe::cb +8.16.0.42 +CALOVw6uFpJ2pBoehvve4TwavOUe0BY-KRXnDkwbBh2hKEyQeYg@mail.gmail.com +2603:10a6:20b:6c::19 +10.152.4.255 diff --git a/Packs/EWS/Integrations/EWSO365/CHANGELOG.md b/Packs/EWS/Integrations/EWSO365/CHANGELOG.md new file mode 100644 index 000000000000..1ed0ad7fa4f3 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/CHANGELOG.md @@ -0,0 +1,2 @@ +## [Unreleased] +- New Integration EWS O365 diff --git a/Packs/EWS/Integrations/EWSO365/EWSO365.py b/Packs/EWS/Integrations/EWSO365/EWSO365.py new file mode 100644 index 000000000000..671502a070e5 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/EWSO365.py @@ -0,0 +1,2081 @@ +from typing import Dict + +import demistomock as demisto +from CommonServerPython import * +from CommonServerUserPython import * + +import sys +import traceback +import json +import os +import hashlib +from datetime import timedelta +from io import StringIO +import logging +import warnings +import email +from requests.exceptions import ConnectionError +from collections import deque + +from multiprocessing import Process +import exchangelib +from exchangelib.errors import ( + ErrorItemNotFound, + ResponseMessageError, + RateLimitError, + ErrorInvalidIdMalformed, + ErrorFolderNotFound, + ErrorMailboxStoreUnavailable, + ErrorMailboxMoveInProgress, + ErrorNameResolutionNoResults, + MalformedResponseError, +) +from exchangelib.items import Item, Message, Contact +from exchangelib.services.common import EWSService, EWSAccountService +from exchangelib.util import create_element, add_xml_child, MNS, TNS +from exchangelib import ( + IMPERSONATION, + Account, + EWSDateTime, + EWSTimeZone, + Configuration, + FileAttachment, + Version, + Folder, + HTMLBody, + Body, + ItemAttachment, + OAUTH2, + OAuth2AuthorizationCodeCredentials, + Identity, +) +from oauthlib.oauth2 import OAuth2Token +from exchangelib.version import EXCHANGE_O365 +from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter + +# Ignore warnings print to stdout +warnings.filterwarnings("ignore") + +""" Constants """ + +APP_NAME = "ms-ews-o365" +FOLDER_ID_LEN = 120 +MAX_INCIDENTS_PER_FETCH = 50 + +# move results +MOVED_TO_MAILBOX = "movedToMailbox" +MOVED_TO_FOLDER = "movedToFolder" + +# item types +FILE_ATTACHMENT_TYPE = "FileAttachment" +ITEM_ATTACHMENT_TYPE = "ItemAttachment" +ATTACHMENT_TYPE = "attachmentType" + +TOIS_PATH = "/root/Top of Information Store/" + +# context keys +ATTACHMENT_ID = "attachmentId" +ATTACHMENT_ORIGINAL_ITEM_ID = "originalItemId" +NEW_ITEM_ID = "newItemId" +MESSAGE_ID = "messageId" +ITEM_ID = "itemId" +ACTION = "action" +MAILBOX = "mailbox" +MAILBOX_ID = "mailboxId" +FOLDER_ID = "id" + +# context paths +CONTEXT_UPDATE_EWS_ITEM = "EWS.Items(val.{0} === obj.{0} || (val.{1} && obj.{1} && val.{1} === obj.{1}))".format( + ITEM_ID, MESSAGE_ID +) +CONTEXT_UPDATE_EWS_ITEM_FOR_ATTACHMENT = "EWS.Items(val.{0} == obj.{1})".format( + ITEM_ID, ATTACHMENT_ORIGINAL_ITEM_ID +) +CONTEXT_UPDATE_ITEM_ATTACHMENT = ".ItemAttachments(val.{0} == obj.{0})".format( + ATTACHMENT_ID +) +CONTEXT_UPDATE_FILE_ATTACHMENT = ".FileAttachments(val.{0} == obj.{0})".format( + ATTACHMENT_ID +) +CONTEXT_UPDATE_FOLDER = "EWS.Folders(val.{0} == obj.{0})".format(FOLDER_ID) + +# fetch params +LAST_RUN_TIME = "lastRunTime" +LAST_RUN_IDS = "ids" +LAST_RUN_FOLDER = "folderName" +ERROR_COUNTER = "errorCounter" + +# headers +ITEMS_RESULTS_HEADERS = [ + "sender", + "subject", + "hasAttachments", + "datetimeReceived", + "receivedBy", + "author", + "toRecipients", + "textBody", +] + +""" Classes """ + + +class ProxyAdapter(requests.adapters.HTTPAdapter): + """ + Proxy Adapter used to add PROXY to requests + """ + def send(self, *args, **kwargs): + kwargs['proxies'] = handle_proxy() + return super().send(*args, **kwargs) + + +class InsecureProxyAdapter(NoVerifyHTTPAdapter): + """ + Insecure Proxy Adapter used to add PROXY and INSECURE to requests + NoVerifyHTTPAdapter is a built-in insecure HTTPAdapter class + """ + def send(self, *args, **kwargs): + kwargs['proxies'] = handle_proxy() + return super().send(*args, **kwargs) + + +class EWSClient: + def __init__( + self, + default_target_mailbox, + client_id, + client_secret, + tenant_id, + folder="Inbox", + is_public_folder=False, + request_timeout="120", + max_fetch=MAX_INCIDENTS_PER_FETCH, + self_deployed=True, + insecure=True, + proxy=False, + **kwargs, + ): + """ + Client used to communicate with EWS + :param default_target_mailbox: Email address from which to fetch incidents + :param client_id: Application client ID + :param client_secret: Application client secret + :param folder: Name of the folder from which to fetch incidents + :param is_public_folder: Public Folder flag + :param request_timeout: Timeout (in seconds) for HTTP requests to Exchange Server + :param max_fetch: Max incidents per fetch + :param insecure: Trust any certificate (not secure) + """ + BaseProtocol.TIMEOUT = int(request_timeout) + self.ews_server = "https://outlook.office365.com/EWS/Exchange.asmx/" + self.ms_client = MicrosoftClient( + tenant_id=tenant_id, + auth_id=client_id, + enc_key=client_secret, + app_name=APP_NAME, + base_url=self.ews_server, + verify=not insecure, + proxy=proxy, + self_deployed=self_deployed, + scope="https://outlook.office.com/.default", + ) + self.folder_name = folder + self.is_public_folder = is_public_folder + self.access_type = kwargs.get('access_type') or IMPERSONATION + self.max_fetch = min(MAX_INCIDENTS_PER_FETCH, int(max_fetch)) + self.last_run_ids_queue_size = 500 + self.client_id = client_id + self.client_secret = client_secret + self.account_email = default_target_mailbox + self.config = self.__prepare(insecure) + self.protocol = BaseProtocol(self.config) + + def __prepare(self, insecure): + """ + Prepares the client PROTOCOL, CREDENTIALS and CONFIGURATION + :param insecure: Trust any certificate (not secure) + :return: OAuth 2 Configuration + """ + BaseProtocol.HTTP_ADAPTER_CLS = InsecureProxyAdapter if insecure else ProxyAdapter + access_token = self.ms_client.get_access_token() + oauth2_token = OAuth2Token({"access_token": access_token}) + self.credentials = credentials = OAuth2AuthorizationCodeCredentials( + client_id=self.client_id, + client_secret=self.client_secret, + access_token=oauth2_token, + ) + # need to add identity for protocol OAuth header + self.credentials.identity = Identity(upn=self.account_email) + config_args = { + "credentials": credentials, + "auth_type": OAUTH2, + "version": Version(EXCHANGE_O365), + "service_endpoint": "https://outlook.office365.com/EWS/Exchange.asmx", + } + + return Configuration(**config_args) + + def get_account(self, target_mailbox=None): + """ + Request an account from EWS + :param (Optional) target_mailbox: Mailbox associated with the requested account + :return: exchangelib Account + """ + if not target_mailbox: + target_mailbox = self.account_email + return Account( + primary_smtp_address=target_mailbox, + autodiscover=False, + config=self.config, + access_type=self.access_type, + ) + + def get_items_from_mailbox(self, account, item_ids): + """ + Request specific items from a mailbox associated with an account + :param account: EWS account or target_mailbox associated with that account + :param item_ids: item_ids of the requested items + :return: list of exchangelib Items + """ + # allow user to pass target_mailbox as account + if isinstance(account, str): + account = self.get_account(account) + else: + account = self.get_account(self.account_email) + if type(item_ids) is not list: + item_ids = [item_ids] + items = [Item(id=x) for x in item_ids] + result = list(account.fetch(ids=items)) + result = [x for x in result if not isinstance(x, ErrorItemNotFound)] + if len(result) != len(item_ids): + raise Exception( + "One or more items were not found. Check the input item ids" + ) + return result + + def get_item_from_mailbox(self, account, item_id): + """ + Request a single item from a mailbox associated with an account + :param account: EWS account or target_mailbox associated with that account + :param item_id: item_id of the requested item + :return: exchangelib Item + """ + result = self.get_items_from_mailbox(account, [item_id]) + if len(result) == 0: + raise Exception(f"ItemId {str(item_id)} not found") + return result[0] + + def get_attachments_for_item(self, item_id, account, attachment_ids=None): + """ + Request attachments for an item + :param item_id: item_id of the item to retrieve attachments from + :param account: EWS account or target_mailbox associated with that account + :param (Optional) attachment_ids: attachment_ids: attachment_ids to retrieve + :return: list of exchangelib Item.attachments + """ + item = self.get_item_from_mailbox(account, item_id) + attachments = [] + attachment_ids = argToList(attachment_ids) + if item: + if item.attachments: + for attachment in item.attachments: + if ( + attachment_ids + and attachment.attachment_id.id not in attachment_ids + ): + continue + attachments.append(attachment) + + else: + raise Exception("Message item not found: " + item_id) + + if attachment_ids and len(attachments) < len(attachment_ids): + raise Exception( + "Some attachment id did not found for message:" + str(attachment_ids) + ) + + return attachments + + def is_default_folder(self, folder_path, is_public=None): + """ + Is the given folder_path public + :param folder_path: folder path to check if is public + :param is_public: (Optional) if provided, will return this value + :return: Boolean + """ + if is_public is not None: + return is_public + + if folder_path == self.folder_name: + return self.is_public_folder + + return False + + def get_folder_by_path(self, path, account=None, is_public=False): + """ + Retrieve folder by path + :param path: path of the folder + :param account: account associated with the requested path + :param is_public: is the requested folder public + :return: exchangelib Folder + """ + if account is None: + account = self.get_account() + # handle exchange folder id + if len(path) == FOLDER_ID_LEN: + folders_map = account.root._folders_map + if path in folders_map: + return account.root._folders_map[path] + if is_public: + folder_result = account.public_folders_root + elif path == "AllItems": + folder_result = account.root + else: + folder_result = account.inbox.parent # Top of Information Store + path = path.replace("/", "\\") + path = path.split("\\") + for sub_folder_name in path: + folder_filter_by_name = [ + x + for x in folder_result.children + if x.name.lower() == sub_folder_name.lower() + ] + if len(folder_filter_by_name) == 0: + raise Exception(f"No such folder {path}") + folder_result = folder_filter_by_name[0] + + return folder_result + + +class MarkAsJunk(EWSAccountService): + """ + EWSAccountService class used for marking items as junk + """ + SERVICE_NAME = "MarkAsJunk" + + def call(self, item_id, move_item): + elements = list( + self._get_elements( + payload=self.get_payload(item_id=item_id, move_item=move_item) + ) + ) + for element in elements: + if isinstance(element, ResponseMessageError): + return str(element) + return "Success" + + def get_payload(self, item_id, move_item): + junk = create_element( + f"m:{self.SERVICE_NAME}", + {"IsJunk": "true", "MoveItem": "true" if move_item else "false"}, + ) + + items_list = create_element("m:ItemIds") + item_element = create_element("t:ItemId", {"Id": item_id}) + items_list.append(item_element) + junk.append(items_list) + + return junk + + +class GetSearchableMailboxes(EWSService): + """ + EWSAccountService class used for getting Searchable Mailboxes + """ + SERVICE_NAME = "GetSearchableMailboxes" + element_container_name = f"{{{MNS}}}SearchableMailboxes" + + @staticmethod + def parse_element(element): + return { + MAILBOX: element.find(f"{{{TNS}}}PrimarySmtpAddress").text + if element.find(f"{{{TNS}}}PrimarySmtpAddress") is not None + else None, + MAILBOX_ID: element.find(f"{{{TNS}}}ReferenceId").text + if element.find(f"{{{TNS}}}ReferenceId") is not None + else None, + "displayName": element.find(f"{{{TNS}}}DisplayName").text + if element.find(f"{{{TNS}}}DisplayName") is not None + else None, + "isExternal": element.find(f"{{{TNS}}}IsExternalMailbox").text + if element.find(f"{{{TNS}}}IsExternalMailbox") is not None + else None, + "externalEmailAddress": element.find(f"{{{TNS}}}ExternalEmailAddress").text + if element.find(f"{{{TNS}}}ExternalEmailAddress") is not None + else None, + } + + def call(self): + elements = self._get_elements(payload=self.get_payload()) + return [ + self.parse_element(x) + for x in elements + if x.find(f"{{{TNS}}}ReferenceId").text + ] + + def get_payload(self): + element = create_element(f"m:{self.SERVICE_NAME}") + return element + + +class ExpandGroup(EWSService): + """ + EWSAccountService class used for expanding groups + """ + SERVICE_NAME = "ExpandDL" + element_container_name = f"{{{MNS}}}DLExpansion" + + @staticmethod + def parse_element(element): + return { + MAILBOX: element.find(f"{{{TNS}}}EmailAddress").text + if element.find(f"{{{TNS}}}EmailAddress") is not None + else None, + "displayName": element.find(f"{{{TNS}}}Name").text + if element.find(f"{{{TNS}}}Name") is not None + else None, + "mailboxType": element.find(f"{{{TNS}}}MailboxType").text + if element.find(f"{{{TNS}}}MailboxType") is not None + else None, + } + + def call(self, email_address, recursive_expansion=False): + try: + if recursive_expansion == "True": + group_members: Dict = {} + self.expand_group_recursive(email_address, group_members) + return list(group_members.values()) + else: + return self.expand_group(email_address) + except ErrorNameResolutionNoResults: + demisto.results("No results were found.") + sys.exit() + + def get_payload(self, email_address): + element = create_element(f"m:{self.SERVICE_NAME}") + mailbox_element = create_element("m:Mailbox") + add_xml_child(mailbox_element, "t:EmailAddress", email_address) + element.append(mailbox_element) + return element + + def expand_group(self, email_address): + """ + Expand given group + :param email_address: email address of the group to expand + :return: list dict with parsed expanded group data + """ + elements = self._get_elements(payload=self.get_payload(email_address)) + return [self.parse_element(x) for x in elements] + + def expand_group_recursive(self, email_address, non_dl_emails, dl_emails=None): + """ + Expand group recursively + :param email_address: email address of the group to expand + :param non_dl_emails: non distribution only emails + :param dl_emails: (Optional) distribution only emails + :return: Set of dl emails and non dl emails (returned via reference) + """ + if dl_emails is None: + dl_emails = set() + if email_address in non_dl_emails or email_address in dl_emails: + return None + dl_emails.add(email_address) + + for member in self.expand_group(email_address): + if ( + member["mailboxType"] == "PublicDL" + or member["mailboxType"] == "PrivateDL" + ): + self.expand_group_recursive(member.get("mailbox"), non_dl_emails, dl_emails) + else: + if member["mailbox"] not in non_dl_emails: + non_dl_emails[member["mailbox"]] = member + + +# If you are modifying this probably also need to modify in other files +def exchangelib_cleanup(): + key_protocols = list(exchangelib.protocol.CachingProtocol._protocol_cache.items()) + try: + exchangelib.close_connections() + except Exception as ex: + demisto.error("Error was found in exchangelib cleanup, ignoring: {}".format(ex)) + for key, protocol in key_protocols: + try: + if "thread_pool" in protocol.__dict__: + demisto.debug( + "terminating thread pool key{} id: {}".format( + key, id(protocol.thread_pool) + ) + ) + protocol.thread_pool.terminate() + del protocol.__dict__["thread_pool"] + else: + demisto.info( + "Thread pool not found (ignoring terminate) in protcol dict: {}".format( + dir(protocol.__dict__) + ) + ) + except Exception as ex: + demisto.error("Error with thread_pool.terminate, ignoring: {}".format(ex)) + + +""" LOGGING """ + +log_stream = None +log_handler = None + + +def start_logging(): + global log_stream + global log_handler + logging.raiseExceptions = False + if log_stream is None: + log_stream = StringIO() + log_handler = logging.StreamHandler(stream=log_stream) + log_handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) + logger = logging.getLogger() + logger.addHandler(log_handler) + logger.setLevel(logging.DEBUG) + + +""" Helper Functions """ + + +def get_attachment_name(attachment_name): + """ + Retrieve attachment name or error string if none is provided + :param attachment_name: attachment name to retrieve + :return: string + """ + if attachment_name is None or attachment_name == "": + return "demisto_untitled_attachment" + return attachment_name + + +def get_entry_for_object(title, context_key, obj, headers=None): + """ + Create an entry for a given object + :param title: Title of the human readable + :param context_key: Context key used for entry context + :param obj: Object to create entry for + :param headers: (Optional) headers used in the tableToMarkDown + :return: Entry object to be used with demisto.results() + """ + if len(obj) == 0: + return "There is no output results" + if headers and isinstance(obj, dict): + headers = list(set(headers).intersection(set(obj.keys()))) + + return { + "Type": entryTypes["note"], + "Contents": obj, + "ContentsFormat": formats["json"], + "ReadableContentsFormat": formats["markdown"], + "HumanReadable": tableToMarkdown(title, obj, headers), + "EntryContext": {context_key: obj}, + } + + +def prepare_args(args): + """ + Prepare arguments to be used as the API expects it + :param args: demisto args + :return: transformed args + """ + args = dict((k.replace("-", "_"), v) for k, v in list(args.items())) + if "is_public" in args: + args["is_public"] = args["is_public"] == "True" + return args + + +def get_limited_number_of_messages_from_qs(qs, limit): + """ + Retrieve a limited number of messages from query search + :param qs: query search to execute + :param limit: limit on number of items to retrieve from search + :return: list of exchangelib.Message + """ + count = 0 + results = [] + for item in qs: + if count == limit: + break + if isinstance(item, Message): + count += 1 + results.append(item) + return results + + +def keys_to_camel_case(value): + """ + Transform keys from snake to camel case (does nothing if no snakes are found) + :param value: value to transform + :return: transformed value + """ + def str_to_camel_case(snake_str): + components = snake_str.split("_") + return components[0] + "".join(x.title() for x in components[1:]) + + if value is None: + return None + if isinstance(value, (list, set)): + return list(map(keys_to_camel_case, value)) + if isinstance(value, dict): + return dict( + ( + keys_to_camel_case(k), + keys_to_camel_case(v) if isinstance(v, (list, dict)) else v, + ) + for (k, v) in list(value.items()) + ) + + return str_to_camel_case(value) + + +def get_last_run(client: EWSClient, last_run=None): + """ + Retrieve the last run time + :param client: EWS Client + :param last_run: (Optional) last run object + :return: last run dict + """ + if not last_run or last_run.get(LAST_RUN_FOLDER) != client.folder_name: + last_run = { + LAST_RUN_TIME: None, + LAST_RUN_FOLDER: client.folder_name, + LAST_RUN_IDS: [], + } + if LAST_RUN_TIME in last_run and last_run[LAST_RUN_TIME] is not None: + last_run[LAST_RUN_TIME] = EWSDateTime.from_string(last_run[LAST_RUN_TIME]) + + # In case we have existing last_run data + if last_run.get(LAST_RUN_IDS) is None: + last_run[LAST_RUN_IDS] = [] + + return last_run + + +def email_ec(item): + """ + Create entry context for an email + :param item: exchangelib.Item + :return: entry context dict + """ + return { + "CC": None + if not item.cc_recipients + else [mailbox.email_address for mailbox in item.cc_recipients], + "BCC": None + if not item.bcc_recipients + else [mailbox.email_address for mailbox in item.bcc_recipients], + "To": None + if not item.to_recipients + else [mailbox.email_address for mailbox in item.to_recipients], + "From": item.author.email_address, + "Subject": item.subject, + "Text": item.text_body, + "HTML": item.body, + "HeadersMap": {header.name: header.value for header in item.headers}, + } + + +def parse_item_as_dict(item, email_address=None, camel_case=False, compact_fields=False): + """ + Parses an exchangelib item as a dict + :param item: exchangelib.Item to parse + :param (Optional) email_address: string mailbox + :param (Optional) camel_case: Is camel case + :param (Optional) compact_fields: Is compact fields + :return: Item as a dict + """ + def parse_object_as_dict(obj): + raw_dict = {} + if obj is not None: + for field in obj.FIELDS: + raw_dict[field.name] = getattr(obj, field.name, None) + return raw_dict + + def parse_folder_as_json(folder): + raw_dict = parse_object_as_dict(folder) + if "parent_folder_id" in raw_dict: + raw_dict["parent_folder_id"] = parse_folder_as_json( + raw_dict["parent_folder_id"] + ) + if "effective_rights" in raw_dict: + raw_dict["effective_rights"] = parse_object_as_dict( + raw_dict["effective_rights"] + ) + return raw_dict + + raw_dict = {} + for field, value in item._field_vals(): + if type(value) in [str, str, int, float, bool, Body, HTMLBody, None]: + raw_dict[field] = value + raw_dict["id"] = item.id + if getattr(item, "attachments", None): + raw_dict["attachments"] = [ + parse_attachment_as_dict(item.id, x) for x in item.attachments + ] + + for time_field in [ + "datetime_sent", + "datetime_created", + "datetime_received", + "last_modified_time", + "reminder_due_by", + ]: + value = getattr(item, time_field, None) + if value: + raw_dict[time_field] = value.ewsformat() + + for dict_field in [ + "effective_rights", + "parent_folder_id", + "conversation_id", + "author", + "extern_id", + "received_by", + "received_representing", + "reply_to", + "sender", + "folder", + ]: + value = getattr(item, dict_field, None) + if value: + raw_dict[dict_field] = parse_object_as_dict(value) + + for list_dict_field in ["headers", "cc_recipients", "to_recipients"]: + value = getattr(item, list_dict_field, None) + if value: + raw_dict[list_dict_field] = [parse_object_as_dict(x) for x in value] + + if getattr(item, "folder", None): + raw_dict["folder"] = parse_folder_as_json(item.folder) + folder_path = ( + item.folder.absolute[len(TOIS_PATH):] + if item.folder.absolute.startswith(TOIS_PATH) + else item.folder.absolute + ) + raw_dict["folder_path"] = folder_path + + if compact_fields: + new_dict = {} + # noinspection PyListCreation + fields_list = [ + "datetime_created", + "datetime_received", + "datetime_sent", + "sender", + "has_attachments", + "importance", + "message_id", + "last_modified_time", + "size", + "subject", + "text_body", + "headers", + "body", + "folder_path", + "is_read", + ] + + if "id" in raw_dict: + new_dict["itemId"] = raw_dict["id"] + fields_list.append("itemId") + + for field in fields_list: + if field in raw_dict: + new_dict[field] = raw_dict.get(field) + for field in ["received_by", "author", "sender"]: + if field in raw_dict: + new_dict[field] = raw_dict.get(field, {}).get("email_address") + for field in ["to_recipients"]: + if field in raw_dict: + new_dict[field] = [x.get("email_address") for x in raw_dict[field]] + attachments = raw_dict.get("attachments") + if attachments and len(attachments) > 0: + file_attachments = [ + x for x in attachments if x[ATTACHMENT_TYPE] == FILE_ATTACHMENT_TYPE + ] + if len(file_attachments) > 0: + new_dict["FileAttachments"] = file_attachments + item_attachments = [ + x for x in attachments if x[ATTACHMENT_TYPE] == ITEM_ATTACHMENT_TYPE + ] + if len(item_attachments) > 0: + new_dict["ItemAttachments"] = item_attachments + + raw_dict = new_dict + + if camel_case: + raw_dict = keys_to_camel_case(raw_dict) + + if email_address: + raw_dict[MAILBOX] = email_address + return raw_dict + + +def get_entry_for_file_attachment(item_id, attachment): + """ + Creates a file entry for an attachment + :param item_id: item_id of the attachment + :param attachment: attachment dict + :return: file entry dict for attachment + """ + entry = fileResult(get_attachment_name(attachment.name), attachment.content) + entry["EntryContext"] = { + CONTEXT_UPDATE_EWS_ITEM_FOR_ATTACHMENT + + CONTEXT_UPDATE_FILE_ATTACHMENT: parse_attachment_as_dict(item_id, attachment) + } + return entry + + +def parse_attachment_as_dict(item_id, attachment): + """ + Creates a note entry for an attachment + :param item_id: item_id of the attachment + :param attachment: attachment dict + :return: note entry dict for attachment + """ + try: + attachment_content = ( + attachment.content + if isinstance(attachment, FileAttachment) + else attachment.item.mime_content + ) + return { + ATTACHMENT_ORIGINAL_ITEM_ID: item_id, + ATTACHMENT_ID: attachment.attachment_id.id, + "attachmentName": get_attachment_name(attachment.name), + "attachmentSHA256": hashlib.sha256(attachment_content).hexdigest() + if attachment_content + else None, + "attachmentContentType": attachment.content_type, + "attachmentContentId": attachment.content_id, + "attachmentContentLocation": attachment.content_location, + "attachmentSize": attachment.size, + "attachmentLastModifiedTime": attachment.last_modified_time.ewsformat(), + "attachmentIsInline": attachment.is_inline, + ATTACHMENT_TYPE: FILE_ATTACHMENT_TYPE + if isinstance(attachment, FileAttachment) + else ITEM_ATTACHMENT_TYPE, + } + except TypeError as e: + if str(e) != "must be string or buffer, not None": + raise + return { + ATTACHMENT_ORIGINAL_ITEM_ID: item_id, + ATTACHMENT_ID: attachment.attachment_id.id, + "attachmentName": get_attachment_name(attachment.name), + "attachmentSHA256": None, + "attachmentContentType": attachment.content_type, + "attachmentContentId": attachment.content_id, + "attachmentContentLocation": attachment.content_location, + "attachmentSize": attachment.size, + "attachmentLastModifiedTime": attachment.last_modified_time.ewsformat(), + "attachmentIsInline": attachment.is_inline, + ATTACHMENT_TYPE: FILE_ATTACHMENT_TYPE + if isinstance(attachment, FileAttachment) + else ITEM_ATTACHMENT_TYPE, + } + + +def get_entry_for_item_attachment(item_id, attachment, target_email): + """ + Creates a note entry for an item attachment + :param item_id: Item id + :param attachment: exchangelib attachment + :param target_email: target email + :return: note entry dict for item attachment + """ + item = attachment.item + dict_result = parse_attachment_as_dict(item_id, attachment) + dict_result.update( + parse_item_as_dict(item, target_email, camel_case=True, compact_fields=True) + ) + title = f'EWS get attachment got item for "{target_email}", "{get_attachment_name(attachment.name)}"' + + return get_entry_for_object( + title, + CONTEXT_UPDATE_EWS_ITEM_FOR_ATTACHMENT + CONTEXT_UPDATE_ITEM_ATTACHMENT, + dict_result, + ) + + +""" Command Functions """ + + +def get_expanded_group(client: EWSClient, email_address, recursive_expansion=False): + """ + Retrieve expanded group command + :param client: EWS Client + :param email_address: Email address of the group to expand + :param (Optional) recursive_expansion: Whether to enable recursive expansion. Default is "False". + :return: Expanded groups output tuple + """ + group_members = ExpandGroup(protocol=client.protocol).call( + email_address, recursive_expansion + ) + group_details = {"name": email_address, "members": group_members} + output = {"EWS.ExpandGroup": group_details} + readable_output = tableToMarkdown("Group Members", group_members) + return readable_output, output, group_details + + +def get_searchable_mailboxes(client: EWSClient): + """ + Retrieve searchable mailboxes command + :param client: EWS Client + :return: Searchable mailboxes output tuple + """ + searchable_mailboxes = GetSearchableMailboxes(protocol=client.protocol).call() + readable_output = tableToMarkdown( + "Searchable mailboxes", searchable_mailboxes, headers=["displayName", "mailbox"] + ) + output = {"EWS.Mailboxes": searchable_mailboxes} + return readable_output, output, searchable_mailboxes + + +def delete_attachments_for_message( + client: EWSClient, item_id, target_mailbox=None, attachment_ids=None +): + """ + Deletes attachments for a given message + :param client: EWS Client + :param item_id: item id + :param (Optional) target_mailbox: target mailbox + :param (Optional) attachment_ids: attachment ids to delete + :return: entries that were delted + """ + attachments = client.get_attachments_for_item( + item_id, target_mailbox, attachment_ids + ) + deleted_file_attachments = [] + deleted_item_attachments = [] # type: ignore + for attachment in attachments: + attachment_deleted_action = { + ATTACHMENT_ID: attachment.attachment_id.id, + ACTION: "deleted", + } + if isinstance(attachment, FileAttachment): + deleted_file_attachments.append(attachment_deleted_action) + else: + deleted_item_attachments.append(attachment_deleted_action) + attachment.detach() + + entries = [] + if len(deleted_file_attachments) > 0: + entry = get_entry_for_object( + "Deleted file attachments", + "EWS.Items" + CONTEXT_UPDATE_FILE_ATTACHMENT, + deleted_file_attachments, + ) + entries.append(entry) + if len(deleted_item_attachments) > 0: + entry = get_entry_for_object( + "Deleted item attachments", + "EWS.Items" + CONTEXT_UPDATE_ITEM_ATTACHMENT, + deleted_item_attachments, + ) + entries.append(entry) + + return entries + + +def fetch_attachments_for_message( + client: EWSClient, item_id, target_mailbox=None, attachment_ids=None +): + """ + Fetches attachments for a message + :param client: EWS Client + :param item_id: item id + :param (Optional) target_mailbox: target mailbox + :param (Optional) attachment_ids: attachment ids + :return: list of parsed entries + """ + account = client.get_account(target_mailbox) + attachments = client.get_attachments_for_item(item_id, account, attachment_ids) + entries = [] + for attachment in attachments: + if isinstance(attachment, FileAttachment): + try: + if attachment.content: + entries.append(get_entry_for_file_attachment(item_id, attachment)) + except TypeError as e: + if str(e) != "must be string or buffer, not None": + raise + else: + entries.append( + get_entry_for_item_attachment( + item_id, attachment, account.primary_smtp_address + ) + ) + if attachment.item.mime_content: + entries.append( + fileResult( + get_attachment_name(attachment.name) + ".eml", + attachment.item.mime_content, + ) + ) + + return entries + + +def move_item_between_mailboxes( + client: EWSClient, + item_id, + destination_mailbox, + destination_folder_path, + source_mailbox=None, + is_public=None, +): + """ + Moves item between mailboxes + :param client: EWS Client + :param item_id: item id + :param destination_mailbox: destination mailbox + :param destination_folder_path: destination folder path + :param (Optional) source_mailbox: source mailbox + :param (Optional) is_public: is the destination folder public + :return: Output tuple + """ + source_account = client.get_account(source_mailbox) + destination_account = client.get_account(destination_mailbox) + is_public = client.is_default_folder(destination_folder_path, is_public) + destination_folder = client.get_folder_by_path( + destination_folder_path, destination_account, is_public + ) + item = client.get_item_from_mailbox(source_account, item_id) + + exported_items = source_account.export([item]) + destination_account.upload([(destination_folder, exported_items[0])]) + source_account.bulk_delete([item]) + + move_result = { + MOVED_TO_MAILBOX: destination_mailbox, + MOVED_TO_FOLDER: destination_folder_path, + } + readable_output = "Item was moved successfully." + output = {f"EWS.Items(val.itemId === '{item_id}')": move_result} + return readable_output, output, move_result + + +def move_item( + client: EWSClient, item_id, target_folder_path, target_mailbox=None, is_public=None +): + """ + Moves an item within the same mailbox + :param client: EWS Client + :param item_id: item id + :param target_folder_path: target folder path + :param (Optional) target_mailbox: mailbox containing the item + :param (Optional) is_public: is the destination folder public + :return: Output tuple + """ + account = client.get_account(target_mailbox) + is_public = client.is_default_folder(target_folder_path, is_public) + target_folder = client.get_folder_by_path(target_folder_path, is_public=is_public) + item = client.get_item_from_mailbox(account, item_id) + if isinstance(item, ErrorInvalidIdMalformed): + raise Exception("Item not found") + item.move(target_folder) + move_result = { + NEW_ITEM_ID: item.id, + ITEM_ID: item_id, + MESSAGE_ID: item.message_id, + ACTION: "moved", + } + readable_output = tableToMarkdown("Moved items", move_result) + output = {CONTEXT_UPDATE_EWS_ITEM: move_result} + return readable_output, output, move_result + + +def delete_items(client: EWSClient, item_ids, delete_type, target_mailbox=None): + """ + Delete items in a mailbox + :param client: EWS Client + :param item_ids: items ids to delete + :param delete_type: delte type soft/hard + :param (Optional) target_mailbox: mailbox containinf the items + :return: Output tuple + """ + deleted_items = [] + item_ids = argToList(item_ids) + items = client.get_items_from_mailbox(target_mailbox, item_ids) + delete_type = delete_type.lower() + + for item in items: + item_id = item.id + if delete_type == "trash": + item.move_to_trash() + elif delete_type == "soft": + item.soft_delete() + elif delete_type == "hard": + item.delete() + else: + raise Exception( + f'invalid delete type: {delete_type}. Use "trash" \\ "soft" \\ "hard"' + ) + deleted_items.append( + { + ITEM_ID: item_id, + MESSAGE_ID: item.message_id, + ACTION: f"{delete_type}-deleted", + } + ) + + readable_output = tableToMarkdown( + f"Deleted items ({delete_type} delete type)", deleted_items + ) + output = {CONTEXT_UPDATE_EWS_ITEM: deleted_items} + return readable_output, output, deleted_items + + +def search_items_in_mailbox( + client: EWSClient, + query=None, + message_id=None, + folder_path="", + limit=100, + target_mailbox=None, + is_public=None, + selected_fields="all", +): + """ + Search items in mailbox + :param client: EWS Client + :param (Optional) query: query to execute + :param (Optional) message_id: message ids to search + :param (Optional) folder_path: folder path to search + :param (Optional) limit: max amount of items to fetch + :param (Optional) target_mailbox: mailbox containing the items + :param (Optional) is_public: is the targeted folder public + :param (Optional) selected_fields: Selected fields + :return: Output tuple + """ + if not query and not message_id: + return_error("Missing required argument. Provide query or message-id") + + if message_id and message_id[0] != "<" and message_id[-1] != ">": + message_id = "<{}>".format(message_id) + + account = client.get_account(target_mailbox) + limit = int(limit) + if folder_path.lower() == "inbox": + folders = [account.inbox] + elif folder_path: + is_public = client.is_default_folder(folder_path, is_public) + folders = [client.get_folder_by_path(folder_path, account, is_public)] + else: + folders = account.inbox.parent.walk() # pylint: disable=E1101 + + items = [] # type: ignore + selected_all_fields = selected_fields == "all" + + if selected_all_fields: + restricted_fields = list([x.name for x in Message.FIELDS]) # type: ignore + else: + restricted_fields = set(argToList(selected_fields)) # type: ignore + restricted_fields.update(["id", "message_id"]) # type: ignore + + for folder in folders: + if Message not in folder.supported_item_models: + continue + if query: + items_qs = folder.filter(query).only(*restricted_fields) + else: + items_qs = folder.filter(message_id=message_id).only(*restricted_fields) + items += get_limited_number_of_messages_from_qs(items_qs, limit) + if len(items) >= limit: + break + + items = items[:limit] + searched_items_result = [ + parse_item_as_dict( + item, + account.primary_smtp_address, + camel_case=True, + compact_fields=selected_all_fields, + ) + for item in items + ] + + if not selected_all_fields: + searched_items_result = [ + {k: v for (k, v) in i.items() if k in keys_to_camel_case(restricted_fields)} + for i in searched_items_result + ] + + for item in searched_items_result: + item["itemId"] = item.pop("id", "") + + readable_output = tableToMarkdown( + "Searched items", + searched_items_result, + headers=ITEMS_RESULTS_HEADERS if selected_all_fields else None, + ) + output = {CONTEXT_UPDATE_EWS_ITEM: searched_items_result} + return readable_output, output, searched_items_result + + +def get_out_of_office_state(client: EWSClient, target_mailbox=None): + """ + Retrieve get out of office state of the targeted mailbox + :param client: EWS Client + :param (Optional) target_mailbox: target mailbox + :return: Output tuple + """ + account = client.get_account(target_mailbox) + oof = account.oof_settings + oof_dict = { + "state": oof.state, # pylint: disable=E1101 + "externalAudience": getattr(oof, "external_audience", None), + "start": oof.start.ewsformat() if oof.start else None, # pylint: disable=E1101 + "end": oof.end.ewsformat() if oof.end else None, # pylint: disable=E1101 + "internalReply": getattr(oof, "internal_replay", None), + "externalReply": getattr(oof, "external_replay", None), + MAILBOX: account.primary_smtp_address, + } + readable_output = tableToMarkdown( + f"Out of office state for {account.primary_smtp_address}", oof_dict + ) + output = {f"Account.Email(val.Address == obj.{MAILBOX}).OutOfOffice": oof_dict} + return readable_output, output, oof_dict + + +def recover_soft_delete_item( + client: EWSClient, + message_ids, + target_folder_path="Inbox", + target_mailbox=None, + is_public=None, +): + """ + Recovers soft deleted items + :param client: EWS Client + :param message_ids: Message ids to recover + :param (Optional) target_folder_path: target folder path + :param (Optional) target_mailbox: target mailbox + :param (Optional) is_public: is the target folder public + :return: + """ + account = client.get_account(target_mailbox) + is_public = client.is_default_folder(target_folder_path, is_public) + target_folder = client.get_folder_by_path(target_folder_path, account, is_public) + recovered_messages = [] + message_ids = argToList(message_ids) + + items_to_recover = account.recoverable_items_deletions.filter( # pylint: disable=E1101 + message_id__in=message_ids + ).all() # pylint: disable=E1101 + + recovered_items = set() + for item in items_to_recover: + recovered_items.add(item) + if len(recovered_items) != len(message_ids): + missing_items = set(message_ids).difference(recovered_items) + raise Exception( + f"Some message ids are missing in recoverable items directory: {missing_items}" + ) + + for item in recovered_items: + item.move(target_folder) + recovered_messages.append( + {ITEM_ID: item.id, MESSAGE_ID: item.message_id, ACTION: "recovered"} + ) + + readable_output = tableToMarkdown("Recovered messages", recovered_messages) + output = {CONTEXT_UPDATE_EWS_ITEM: recovered_messages} + return readable_output, output, recovered_messages + + +def get_contacts(client: EWSClient, limit, target_mailbox=None): + """ + Retrieve contacts of the target mailbox or client mailbox + :param client: EWS Client + :param limit: max amount of contacts to retrieve + :param (Optional) target_mailbox: Target mailbox + :return: + """ + def parse_physical_address(address): + result = {} + for attr in ["city", "country", "label", "state", "street", "zipcode"]: + result[attr] = getattr(address, attr, None) + return result + + def parse_phone_number(phone_number): + result = {} + for attr in ["label", "phone_number"]: + result[attr] = getattr(phone_number, attr, None) + return result + + def parse_contact(contact): + contact_dict = dict( + (k, v if not isinstance(v, EWSDateTime) else v.ewsformat()) + for k, v in list(contact._field_vals()) + if isinstance(v, str) or isinstance(v, EWSDateTime) + ) + if isinstance(contact, Contact) and contact.physical_addresses: + contact_dict["physical_addresses"] = list( + map(parse_physical_address, contact.physical_addresses) + ) + if isinstance(contact, Contact) and contact.phone_numbers: + contact_dict["phone_numbers"] = list( + map(parse_phone_number, contact.phone_numbers) + ) + if ( + isinstance(contact, Contact) + and contact.email_addresses + and len(contact.email_addresses) > 0 + ): + contact_dict["emailAddresses"] = [x.email for x in contact.email_addresses] + contact_dict = keys_to_camel_case(contact_dict) + contact_dict = dict((k, v) for k, v in list(contact_dict.items()) if v) + contact_dict.pop("mimeContent", None) + contact_dict["originMailbox"] = target_mailbox + return contact_dict + + account = client.get_account(target_mailbox) + contacts = [] + + for contact in account.contacts.all()[: int(limit)]: # pylint: disable=E1101 + contacts.append(parse_contact(contact)) + readable_output = tableToMarkdown(f"Email contacts for {target_mailbox}", contacts) + output = {"Account.Email(val.Address == obj.originMailbox).EwsContacts": contacts} + return readable_output, output, contacts + + +def create_folder(client: EWSClient, new_folder_name, folder_path, target_mailbox=None): + """ + Creates a folder in the target mailbox or the client mailbox + :param client: EWS Client + :param new_folder_name: new folder name + :param folder_path: path of the new folder + :param (Optional) target_mailbox: target mailbox + :return: Output tuple + """ + account = client.get_account(target_mailbox) + full_path = os.path.join(folder_path, new_folder_name) + try: + if client.get_folder_by_path(full_path, account): + return f"Folder {full_path} already exists", + except Exception: + pass + parent_folder = client.get_folder_by_path(folder_path, account) + f = Folder(parent=parent_folder, name=new_folder_name) + f.save() + client.get_folder_by_path(full_path, account) + return f"Folder {full_path} created successfully", + + +def find_folders(client: EWSClient, target_mailbox=None): + """ + Finds folders in the mailbox + :param client: EWS Client + :param (Optional) target_mailbox: target mailbox + :return: Output tuple + """ + account = client.get_account(target_mailbox) + root = account.root + if client.is_public_folder: + root = account.public_folders_root + folders = [] + for f in root.walk(): # pylint: disable=E1101 + folder = folder_to_context_entry(f) + folders.append(folder) + folders_tree = root.tree() # pylint: disable=E1101 + readable_output = folders_tree + output = {"EWS.Folders(val.id == obj.id)": folders} + return readable_output, output, folders + + +def mark_item_as_junk(client: EWSClient, item_id, move_items, target_mailbox=None): + """ + Marks item as junk in the target mailbox or client mailbox + :param client: EWS Client + :param item_id: item ids to mark as junk + :param move_items: "yes" or "no" - to move or not to move to trash + :param (Optional) target_mailbox: target mailbox + :return: + """ + account = client.get_account(target_mailbox) + move_items = move_items.lower() == "yes" + ews_result = MarkAsJunk(account=account).call(item_id=item_id, move_item=move_items) + mark_as_junk_result = { + ITEM_ID: item_id, + } + if ews_result == "Success": + mark_as_junk_result[ACTION] = "marked-as-junk" + else: + raise Exception("Failed mark-item-as-junk with error: " + ews_result) + + readable_output = tableToMarkdown("Mark item as junk", mark_as_junk_result) + output = {CONTEXT_UPDATE_EWS_ITEM: mark_as_junk_result} + return readable_output, output, mark_as_junk_result + + +def get_items_from_folder( + client: EWSClient, + folder_path, + limit=100, + target_mailbox=None, + is_public=None, + get_internal_item="no", +): + """ + Retrieve items from folder path + :param client: EWS Client + :param folder_path: folder path + :param (Optional) limit: max amount of items to retrieve + :param (Optional) target_mailbox: target mailbox + :param (Optional) is_public: is the folder public + :param (Optional) get_internal_item: should also retrieve internal items ("no" by default) + :return: Output tuple + """ + account = client.get_account(target_mailbox) + limit = int(limit) + get_internal_item = get_internal_item == "yes" + is_public = client.is_default_folder(folder_path, is_public) + folder = client.get_folder_by_path(folder_path, account, is_public) + qs = folder.filter().order_by("-datetime_created")[:limit] + items = get_limited_number_of_messages_from_qs(qs, limit) + items_result = [] + + for item in items: + item_attachment = parse_item_as_dict( + item, account.primary_smtp_address, camel_case=True, compact_fields=True + ) + for attachment in item.attachments: + if ( + get_internal_item + and isinstance(attachment, ItemAttachment) + and isinstance(attachment.item, Message) + ): + # if found item attachment - switch item to the attchment + item_attachment = parse_item_as_dict( + attachment.item, + account.primary_smtp_address, + camel_case=True, + compact_fields=True, + ) + break + items_result.append(item_attachment) + + hm_headers = [ + "sender", + "subject", + "hasAttachments", + "datetimeReceived", + "receivedBy", + "author", + "toRecipients", + "id", + ] + readable_output = tableToMarkdown( + "Items in folder " + folder_path, items_result, headers=hm_headers + ) + output = {CONTEXT_UPDATE_EWS_ITEM: items_result} + return readable_output, output, items_result + + +def get_items(client: EWSClient, item_ids, target_mailbox=None): + """ + Get items from target mailbox or client mailbox + :param client: EWS Client + :param item_ids: item ids to retrieve + :param (Optional) target_mailbox: target mailbox to retrieve items from + :return: + """ + item_ids = argToList(item_ids) + account = client.get_account(target_mailbox) + items = client.get_items_from_mailbox(account, item_ids) + items = [x for x in items if isinstance(x, Message)] + items_as_incidents = [parse_incident_from_item(x) for x in items] + items_to_context = [ + parse_item_as_dict(x, account.primary_smtp_address, True, True) for x in items + ] + readable_output = tableToMarkdown( + "Get items", items_to_context, ITEMS_RESULTS_HEADERS + ) + output = { + CONTEXT_UPDATE_EWS_ITEM: items_to_context, + "Email": [email_ec(item) for item in items], + } + return readable_output, output, items_as_incidents + + +def get_folder(client: EWSClient, folder_path, target_mailbox=None, is_public=None): + """ + Retrieve a folder from the target mailbox or client mailbox + :param client: EWS Client + :param folder_path: folder path to retrieve + :param (Optional) target_mailbox: target mailbox + :param (Optional) is_public: is the folder public + :return: + """ + account = client.get_account(target_mailbox) + is_public = client.is_default_folder(folder_path, is_public) + folder = folder_to_context_entry( + client.get_folder_by_path(folder_path, account=account, is_public=is_public) + ) + readable_output = tableToMarkdown(f"Folder {folder_path}", folder) + output = {CONTEXT_UPDATE_FOLDER: folder} + return readable_output, output, folder + + +def folder_to_context_entry(f): + """ + Create a context entry from a folder response + :param f: folder response + :return: dict context entry + """ + try: + f_entry = { + "name": f.name, + "totalCount": f.total_count, + "id": f.id, + "childrenFolderCount": f.child_folder_count, + "changeKey": f.changekey, + } + + if "unread_count" in [x.name for x in Folder.FIELDS]: + f_entry["unreadCount"] = f.unread_count + return f_entry + except AttributeError: + if isinstance(f, dict): + return { + "name": f.get("name"), + "totalCount": f.get("total_count"), + "id": f.get("id"), + "childrenFolderCount": f.get("child_folder_count"), + "changeKey": f.get("changekey"), + "unreadCount": f.get("unread_count"), + } + + +def mark_item_as_read( + client: EWSClient, item_ids, operation="read", target_mailbox=None +): + """ + Marks item as read + :param client: EWS Client + :param item_ids: items ids to mark as read + :param (Optional) operation: operation to execute + :param (Optional) target_mailbox: target mailbox + :return: Output tuple + """ + marked_items = [] + item_ids = argToList(item_ids) + items = client.get_items_from_mailbox(target_mailbox, item_ids) + items = [x for x in items if isinstance(x, Message)] + + for item in items: + item.is_read = operation == "read" + item.save() + + marked_items.append( + { + ITEM_ID: item.id, + MESSAGE_ID: item.message_id, + ACTION: "marked-as-{}".format(operation), + } + ) + + readable_output = tableToMarkdown( + f"Marked items ({operation} marked operation)", marked_items + ) + output = {CONTEXT_UPDATE_EWS_ITEM: marked_items} + return readable_output, output, marked_items + + +def get_item_as_eml(client: EWSClient, item_id, target_mailbox=None): + """ + Retrieve item as an eml + :param client: EWS Client + :param item_id: Item id to retrieve + :param (Optional) target_mailbox: target mailbox + :return: Output tuple + """ + account = client.get_account(target_mailbox) + item = client.get_item_from_mailbox(account, item_id) + + if item.mime_content: + mime_content = item.mime_content + if isinstance(mime_content, bytes): + email_content = email.message_from_bytes(mime_content) + else: + email_content = email.message_from_string(mime_content) + if item.headers: + attached_email_headers = [ + (h, " ".join(map(str.strip, v.split("\r\n")))) + for (h, v) in list(email_content.items()) + ] + for header in item.headers: + if ( + header.name, + header.value, + ) not in attached_email_headers and header.name != "Content-Type": + email_content.add_header(header.name, header.value) + + eml_name = item.subject if item.subject else "demisto_untitled_eml" + file_result = fileResult(eml_name + ".eml", email_content.as_string()) + file_result = ( + file_result if file_result else "Failed uploading eml file to war room" + ) + + return file_result + + +def parse_incident_from_item(item): + """ + Parses an incident from an item + :param item: item to parse + :return: Parsed item + """ + incident = {} + labels = [] + + try: + incident["details"] = item.text_body or item.body + except AttributeError: + incident["details"] = item.body + incident["name"] = item.subject + labels.append({"type": "Email/subject", "value": item.subject}) + incident["occurred"] = item.datetime_created.ewsformat() + + # handle recipients + if item.to_recipients: + for recipient in item.to_recipients: + labels.append({"type": "Email", "value": recipient.email_address}) + + # handle cc + if item.cc_recipients: + for recipient in item.cc_recipients: + labels.append({"type": "Email/cc", "value": recipient.email_address}) + # handle email from + if item.sender: + labels.append({"type": "Email/from", "value": item.sender.email_address}) + + # email format + email_format = "" + try: + if item.text_body: + labels.append({"type": "Email/text", "value": item.text_body}) + email_format = "text" + except AttributeError: + pass + if item.body: + labels.append({"type": "Email/html", "value": item.body}) + email_format = "HTML" + labels.append({"type": "Email/format", "value": email_format}) + + # handle attachments + if item.attachments: + incident["attachment"] = [] + for attachment in item.attachments: + file_result = None + label_attachment_type = None + label_attachment_id_type = None + if isinstance(attachment, FileAttachment): + try: + if attachment.content: + # file attachment + label_attachment_type = "attachments" + label_attachment_id_type = "attachmentId" + + # save the attachment + file_name = get_attachment_name(attachment.name) + file_result = fileResult(file_name, attachment.content) + + # check for error + if file_result["Type"] == entryTypes["error"]: + demisto.error(file_result["Contents"]) + raise Exception(file_result["Contents"]) + + # save attachment to incident + incident["attachment"].append( + { + "path": file_result["FileID"], + "name": get_attachment_name(attachment.name), + } + ) + except TypeError as e: + if str(e) != "must be string or buffer, not None": + raise + continue + else: + # other item attachment + label_attachment_type = "attachmentItems" + label_attachment_id_type = "attachmentItemsId" + + # save the attachment + if attachment.item.mime_content: + attached_email = email.message_from_string( + attachment.item.mime_content + ) + if attachment.item.headers: + attached_email_headers = [ + (h, " ".join(map(str.strip, v.split("\r\n")))) + for (h, v) in list(attached_email.items()) + ] + for header in attachment.item.headers: + if ( + (header.name, header.value) + not in attached_email_headers + and header.name != "Content-Type" + ): + attached_email.add_header(header.name, header.value) + + file_result = fileResult( + get_attachment_name(attachment.name) + ".eml", + attached_email.as_string(), + ) + + if file_result: + # check for error + if file_result["Type"] == entryTypes["error"]: + demisto.error(file_result["Contents"]) + raise Exception(file_result["Contents"]) + + # save attachment to incident + incident["attachment"].append( + { + "path": file_result["FileID"], + "name": get_attachment_name(attachment.name) + ".eml", + } + ) + + labels.append( + { + "type": label_attachment_type, + "value": get_attachment_name(attachment.name), + } + ) + labels.append( + {"type": label_attachment_id_type, "value": attachment.attachment_id.id} + ) + + # handle headers + if item.headers: + headers = [] + for header in item.headers: + labels.append( + { + "type": "Email/Header/{}".format(header.name), + "value": str(header.value), + } + ) + headers.append("{}: {}".format(header.name, header.value)) + labels.append({"type": "Email/headers", "value": "\r\n".join(headers)}) + + # handle item id + if item.message_id: + labels.append({"type": "Email/MessageId", "value": str(item.message_id)}) + + if item.id: + labels.append({"type": "Email/ID", "value": item.id}) + labels.append({"type": "Email/itemId", "value": item.id}) + + # handle conversion id + if item.conversation_id: + labels.append({"type": "Email/ConversionID", "value": item.conversation_id.id}) + + incident["labels"] = labels + incident["rawJSON"] = json.dumps(parse_item_as_dict(item, None), ensure_ascii=False) + + return incident + + +def fetch_emails_as_incidents(client: EWSClient, last_run): + """ + Fetch incidents + :param client: EWS Client + :param last_run: last run dict + :return: + """ + last_run = get_last_run(client, last_run) + + try: + last_emails = fetch_last_emails( + client, + client.folder_name, + last_run.get(LAST_RUN_TIME), + last_run.get(LAST_RUN_IDS), + ) + + ids = deque( + last_run.get(LAST_RUN_IDS, []), maxlen=client.last_run_ids_queue_size + ) + incidents = [] + incident: Dict[str, str] = {} + for item in last_emails: + if item.message_id: + ids.append(item.message_id) + incident = parse_incident_from_item(item) + incidents.append(incident) + + if len(incidents) >= client.max_fetch: + break + + last_run_time = incident.get("occurred", last_run.get(LAST_RUN_TIME)) + if isinstance(last_run_time, EWSDateTime): + last_run_time = last_run_time.ewsformat() + + new_last_run = { + LAST_RUN_TIME: last_run_time, + LAST_RUN_FOLDER: client.folder_name, + LAST_RUN_IDS: list(ids), + ERROR_COUNTER: 0, + } + + demisto.setLastRun(new_last_run) + return incidents + + except RateLimitError: + if LAST_RUN_TIME in last_run: + last_run[LAST_RUN_TIME] = last_run[LAST_RUN_TIME].ewsformat() + if ERROR_COUNTER not in last_run: + last_run[ERROR_COUNTER] = 0 + last_run[ERROR_COUNTER] += 1 + demisto.setLastRun(last_run) + if last_run[ERROR_COUNTER] > 2: + raise + return [] + + +def fetch_last_emails( + client: EWSClient, folder_name="Inbox", since_datetime=None, exclude_ids=None +): + """ + Fetches last emails + :param client: EWS client + :param (Optional) folder_name: folder name to pull from + :param (Optional) since_datetime: items will be searched after this datetime + :param (Optional) exclude_ids: exclude ids from fetch + :return: list of exchangelib.Items + """ + qs = client.get_folder_by_path(folder_name, is_public=client.is_public_folder) + if since_datetime: + qs = qs.filter(datetime_received__gte=since_datetime) + else: + last_10_min = EWSDateTime.now(tz=EWSTimeZone.timezone("UTC")) - timedelta( + minutes=10 + ) + qs = qs.filter(last_modified_time__gte=last_10_min) + qs = qs.filter().only(*[x.name for x in Message.FIELDS]) + qs = qs.filter().order_by("datetime_received") + + result = qs.all() + result = [x for x in result if isinstance(x, Message)] + if exclude_ids and len(exclude_ids) > 0: + exclude_ids = set(exclude_ids) + result = [x for x in result if x.message_id not in exclude_ids] + return result + + +def test_module(client: EWSClient, max_fetch): + """ + test-module + * Max incidents per fetch <= MAX_INCIDENTS_PER_FETCH + * Account can be retrieved + * Account has read rights + * Test access to fetch folder + :param client: EWS Client + :param max_fetch: Max fetches per incident + :return: "ok" + """ + try: + if int(max_fetch) > MAX_INCIDENTS_PER_FETCH: + return_error(f'Error - Max incidents per fetch cannot be greater than {MAX_INCIDENTS_PER_FETCH}. ' + f'You provided: {max_fetch}') + account = client.get_account() + if not account.root.effective_rights.read: # pylint: disable=E1101 + raise Exception( + "Success to authenticate, but user has no permissions to read from the mailbox. " + "Need to delegate the user permissions to the mailbox - " + "please read integration documentation and follow the instructions" + ) + client.get_folder_by_path( + client.folder_name, account, client.is_public_folder + ).test_access() + except ErrorFolderNotFound as e: + if "Top of Information Store" in str(e): + raise Exception( + "Success to authenticate, but user probably has no permissions to read from the specific folder." + "Check user permissions. You can try !ews-find-folders command to " + "get all the folders structure that the user has permissions to" + ) + + return "ok" + + +def sub_main(): + is_test_module = False + params = demisto.params() + client = EWSClient(**params) + args = prepare_args(demisto.args()) + start_logging() + try: + command = demisto.command() + # commands that return a single note result + normal_commands = { + "ews-get-searchable-mailboxes": get_searchable_mailboxes, + "ews-move-item-between-mailboxes": move_item_between_mailboxes, + "ews-move-item": move_item, + "ews-delete-items": delete_items, + "ews-search-mailbox": search_items_in_mailbox, + "ews-get-contacts": get_contacts, + "ews-get-out-of-office": get_out_of_office_state, + "ews-recover-messages": recover_soft_delete_item, + "ews-create-folder": create_folder, + "ews-mark-item-as-junk": mark_item_as_junk, + "ews-find-folders": find_folders, + "ews-get-items-from-folder": get_items_from_folder, + "ews-get-items": get_items, + "ews-get-folder": get_folder, + "ews-expand-group": get_expanded_group, + "ews-mark-items-as-read": mark_item_as_read, + } + + # commands that may return multiple results or non-note result + special_output_commands = { + "ews-get-attachment": fetch_attachments_for_message, + "ews-delete-attachment": delete_attachments_for_message, + "ews-get-items-as-eml": get_item_as_eml, + } + # system commands: + if command == "test-module": + is_test_module = True + demisto.results(test_module(client, params.get('max_fetch'))) + elif command == "fetch-incidents": + last_run = demisto.getLastRun() + incidents = fetch_emails_as_incidents(client, last_run) + demisto.incidents(incidents) + + # special outputs commands + elif command in special_output_commands: + demisto.results(special_output_commands[command](client, **args)) # type: ignore[operator] + + # normal commands + else: + output = normal_commands[command](client, **args) # type: ignore[operator] + return_outputs(*output) + + except Exception as e: + start_logging() + debug_log = log_stream.getvalue() # type: ignore[union-attr] + error_message_simple = "" + + # Office365 regular maintenance case + if isinstance(e, ErrorMailboxStoreUnavailable) or isinstance( + e, ErrorMailboxMoveInProgress + ): + log_message = ( + "Office365 is undergoing load balancing operations. " + "As a result, the service is temporarily unavailable." + ) + if demisto.command() == "fetch-incidents": + demisto.info(log_message) + demisto.incidents([]) + sys.exit(0) + if is_test_module: + demisto.results( + log_message + " Please retry the instance configuration test." + ) + sys.exit(0) + error_message_simple = log_message + " Please retry your request." + + if isinstance(e, ConnectionError): + error_message_simple = ( + "Could not connect to the server.\n" + f"Additional information: {str(e)}" + ) + else: + if is_test_module and isinstance(e, MalformedResponseError): + error_message_simple = ( + "Got invalid response from the server.\n" + ) + + # Legacy error handling + if "Status code: 401" in debug_log: + error_message_simple = ( + "Got unauthorized from the server. " + ) + + if "Status code: 503" in debug_log: + error_message_simple = ( + "Got timeout from the server. " + "Probably the server is not reachable with the current settings. " + ) + + if not error_message_simple: + error_message = error_message_simple = str(e) + else: + error_message = error_message_simple + "\n" + str(e) + + stacktrace = traceback.format_exc() + if stacktrace: + error_message += "\nFull stacktrace:\n" + stacktrace + + if debug_log: + error_message += "\nFull debug log:\n" + debug_log + + if demisto.command() == "fetch-incidents": + raise + if demisto.command() == "ews-search-mailbox" and isinstance(e, ValueError): + return_error( + message="Selected invalid field, please specify valid field name.", + error=e, + ) + if is_test_module: + demisto.results(error_message_simple) + else: + demisto.results( + { + "Type": entryTypes["error"], + "ContentsFormat": formats["text"], + "Contents": error_message_simple, + } + ) + demisto.error(f"{e.__class__.__name__}: {error_message}") + finally: + exchangelib_cleanup() + if log_stream: + try: + logging.getLogger().removeHandler(log_handler) # type: ignore + log_stream.close() + except Exception as ex: + demisto.error( + "EWS: unexpected exception when trying to remove log handler: {}".format( + ex + ) + ) + + +def process_main(): + """setup stdin to fd=0 so we can read from the server""" + sys.stdin = os.fdopen(0, "r") + sub_main() + + +def main(): + # When running big queries, like 'ews-search-mailbox' the memory might not freed by the garbage + # collector. `separate_process` flag will run the integration on a separate process that will prevent + # memory leakage. + separate_process = demisto.params().get("separate_process", False) + demisto.debug("Running as separate_process: {}".format(separate_process)) + if separate_process: + try: + p = Process(target=process_main) + p.start() + p.join() + except Exception as ex: + demisto.error("Failed starting Process: {}".format(ex)) + else: + sub_main() + + +from MicrosoftApiModule import * # noqa: E402 + +if __name__ in ("__main__", "__builtin__", "builtins"): + main() diff --git a/Packs/EWS/Integrations/EWSO365/EWSO365.yml b/Packs/EWS/Integrations/EWSO365/EWSO365.yml new file mode 100644 index 000000000000..dc99373365a7 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/EWSO365.yml @@ -0,0 +1,1051 @@ +category: Messaging +commonfields: + id: EWSO365 + version: -1 +configuration: +- additionalinfo: ID can be received from the admin consent procedure - see Detailed Instructions. + display: ID / Application ID + name: client_id + required: true + type: 4 +- additionalinfo: Token can be received from the admin consent procedure - see Detailed Instructions. + display: Token / Tenant ID + name: tenant_id + required: true + type: 4 +- additionalinfo: Key can be received from the admin consent procedure - see Detailed Instructions. + display: Key / Application Secret + name: client_secret + required: true + type: 4 +- additionalinfo: Mailbox to run commands on and to fetch incidents from. + display: Email Address + name: default_target_mailbox + required: true + type: 0 +- additionalinfo: Supports Exchange Folder ID and sub-folders e.g. Inbox/Phishing. + defaultvalue: Inbox + display: Name of the folder from which to fetch incidents + name: folder + required: true + type: 0 +- defaultvalue: 'false' + display: Public Folder + name: is_public_folder + required: false + type: 8 +- display: Fetch incidents + name: isFetch + required: false + type: 8 +- display: Incident type + name: incidentType + required: false + type: 13 +- defaultvalue: '50' + display: Max incidents per fetch (up to 50) + name: max_fetch + required: false + type: 0 +- defaultvalue: '120' + display: Timeout (in seconds) for HTTP requests to Exchange Server + name: request_timeout + required: false + type: 0 +- display: Trust any certificate (not secure) + name: insecure + required: false + type: 8 +- defaultvalue: 'false' + display: Use system proxy settings + name: proxy + required: false + type: 8 +- defaultvalue: 'false' + display: Run as a separate process (protects against memory depletion) + name: separate_process + required: false + type: 8 +- display: Use a self deployed Azure Application + hidden: false + name: self_deployed + required: false + type: 8 +description: Exchange Web Services and Office 365 (mail) +display: EWS O365 +name: EWSO365 +script: + commands: + - arguments: + - default: false + description: The ID of the email message for which to get the attachments. + isArray: false + name: item-id + required: true + secret: false + - default: false + description: The mailbox in which this attachment was found. If empty, the default + mailbox is used. Otherwise the user might require impersonation rights to + this mailbox. + isArray: false + name: target-mailbox + required: false + secret: false + - default: false + description: The attachments ids to get. If none - all attachments will be retrieve + from the message. Support multiple attachments with comma-separated value + or array. + isArray: true + name: attachment-ids + required: false + secret: false + deprecated: false + description: Retrieves the actual attachments from an item (email message). To + get all attachments for a message, only specify the item-id argument. + execution: false + name: ews-get-attachment + outputs: + - contextPath: EWS.Items.FileAttachments.attachmentId + description: The attachment ID. Used for file attachments only. + type: string + - contextPath: EWS.Items.FileAttachments.attachmentName + description: The attachment name. Used for file attachments only. + type: string + - contextPath: EWS.Items.FileAttachments.attachmentSHA256 + description: The SHA256 hash of the attached file. + type: string + - contextPath: EWS.Items.FileAttachments.attachmentLastModifiedTime + description: The attachment last modified time. Used for file attachments only. + type: date + - contextPath: EWS.Items.ItemAttachments.datetimeCreated + description: The created time of the attached email. + type: date + - contextPath: EWS.Items.ItemAttachments.datetimeReceived + description: The received time of the attached email. + type: date + - contextPath: EWS.Items.ItemAttachments.datetimeSent + description: The sent time of the attached email. + type: date + - contextPath: EWS.Items.ItemAttachments.receivedBy + description: The received by address of the attached email. + type: string + - contextPath: EWS.Items.ItemAttachments.subject + description: The subject of the attached email. + type: string + - contextPath: EWS.Items.ItemAttachments.textBody + description: The body of the attached email (as text). + type: string + - contextPath: EWS.Items.ItemAttachments.headers + description: The headers of the attached email. + type: Unknown + - contextPath: EWS.Items.ItemAttachments.hasAttachments + description: Whether the attached email has attachments. + type: boolean + - contextPath: EWS.Items.ItemAttachments.itemId + description: The attached email item ID. + type: string + - contextPath: EWS.Items.ItemAttachments.toRecipients + description: A list of recipient email addresses for the attached email. + type: Unknown + - contextPath: EWS.Items.ItemAttachments.body + description: The body of the attached email (as HTML). + type: string + - contextPath: EWS.Items.ItemAttachments.attachmentSHA256 + description: The SHA256 hash of the attached email (as EML file). + type: string + - contextPath: EWS.Items.ItemAttachments.FileAttachments.attachmentSHA256 + description: SHA256 hash of the attached files inside of the attached email. + type: string + - contextPath: EWS.Items.ItemAttachments.ItemAttachments.attachmentSHA256 + description: SHA256 hash of the attached emails inside of the attached email. + type: string + - contextPath: EWS.Items.ItemAttachments.isRead + description: The read status of the attachment. + type: String + - arguments: + - default: false + description: The ID of the email message for which to delete attachments. + isArray: false + name: item-id + required: true + secret: false + - default: false + description: The mailbox in which this attachment was found. If empty, the default + mailbox is used. Otherwise the user might require impersonation rights to + this mailbox. + isArray: false + name: target-mailbox + required: false + secret: false + - default: false + description: A comma-separated list (or array) of attachment IDs to delete. If empty, all + attachments will be deleted from the message. + isArray: true + name: attachment-ids + required: false + secret: false + deprecated: false + description: Deletes the attachments of an item (email message). + execution: false + name: ews-delete-attachment + outputs: + - contextPath: EWS.Items.FileAttachments.attachmentId + description: The ID of the deleted attachment, in case of file attachment. + type: string + - contextPath: EWS.Items.ItemAttachments.attachmentId + description: The ID of the deleted attachment, in case of other attachment (for + example, "email"). + type: string + - contextPath: EWS.Items.FileAttachments.action + description: 'The deletion action in case of file attachment. This is a constant + value: ''deleted''.' + type: string + - contextPath: EWS.Items.ItemAttachments.action + description: 'The deletion action in case of other attachment (for example, + "email"). This is a constant value: ''deleted''.' + type: string + - deprecated: false + description: Returns a list of searchable mailboxes. This command requires eDiscovery + permissions to the Exchange Server. For more information, see the EWSv2 integration + documentation. + execution: false + name: ews-get-searchable-mailboxes + outputs: + - contextPath: EWS.Mailboxes.mailbox + description: Addresses of the searchable mailboxes. + type: string + - contextPath: EWS.Mailboxes.mailboxId + description: IDs of the searchable mailboxes. + type: string + - contextPath: EWS.Mailboxes.displayName + description: The email display name. + type: string + - contextPath: EWS.Mailboxes.isExternal + description: Whether the mailbox is external. + type: boolean + - contextPath: EWS.Mailboxes.externalEmailAddress + description: The external email address. + type: string + - arguments: + - default: false + description: The ID of the item to move. + isArray: false + name: item-id + required: true + secret: false + - default: false + description: The path to the folder to which to move the item. Complex paths + are supported, for example, "Inbox\Phishing". + isArray: false + name: target-folder-path + required: true + secret: false + - default: false + description: The mailbox on which to run the command. + isArray: false + name: target-mailbox + required: false + secret: false + - auto: PREDEFINED + default: false + description: Whether the target folder is a public folder. Can be "True" or "False". + isArray: false + name: is-public + predefined: + - 'True' + - 'False' + required: false + secret: false + deprecated: false + description: Move an item to different folder in the mailbox. + execution: false + name: ews-move-item + outputs: + - contextPath: EWS.Items.newItemID + description: The item ID after move. + type: string + - contextPath: EWS.Items.messageID + description: The item message ID. + type: string + - contextPath: EWS.Items.itemId + description: The original item ID. + type: string + - contextPath: EWS.Items.action + description: The action taken. The value will be "moved". + type: string + - arguments: + - default: false + description: The item IDs to delete. + isArray: false + name: item-ids + required: true + secret: false + - default: false + defaultValue: soft + description: Deletion type. Can be "trash", "soft", or "hard". + isArray: false + name: delete-type + required: true + secret: false + - default: false + description: The mailbox on which to run the command. + isArray: false + name: target-mailbox + required: false + secret: false + deprecated: false + description: Delete items from mailbox. + execution: false + name: ews-delete-items + outputs: + - contextPath: EWS.Items.itemId + description: The deleted item ID. + type: string + - contextPath: EWS.Items.messageId + description: The deleted message ID. + type: string + - contextPath: EWS.Items.action + description: The deletion action. Can be 'trash-deleted', 'soft-deleted', or + 'hard-deleted'. + type: string + - arguments: + - default: false + description: 'The search query string. For more information about the query + syntax, see the Microsoft documentation: https://msdn.microsoft.com/en-us/library/ee693615.aspx' + isArray: false + name: query + required: false + secret: false + - default: false + description: The folder path in which to search. If empty, searches all + folders in the mailbox. + isArray: false + name: folder-path + required: false + secret: false + - default: false + defaultValue: '50' + description: Maximum number of results to return. The default is 50. + isArray: false + name: limit + required: false + secret: false + - default: false + description: The mailbox on which to apply the search. + isArray: false + name: target-mailbox + required: false + secret: false + - auto: PREDEFINED + default: false + description: Whether the folder is a public folder. Can be "True" or "False". + isArray: false + name: is-public + predefined: + - 'True' + - 'False' + required: false + secret: false + - default: false + description: The message ID of the email. This will be ignored if a query argument + is provided. + isArray: false + name: message-id + required: false + secret: false + - default: false + defaultValue: all + description: A comma-separated list of fields to retrieve. + isArray: true + name: selected-fields + predefined: + - '' + required: false + secret: false + deprecated: false + description: Searches for items in the specified mailbox. Specific permissions + are needed for this operation to search in a target mailbox other than the default. + execution: false + name: ews-search-mailbox + outputs: + - contextPath: EWS.Items.itemId + description: The email item ID. + type: string + - contextPath: EWS.Items.hasAttachments + description: Whether the email has attachments. + type: boolean + - contextPath: EWS.Items.datetimeReceived + description: Received time of the email. + type: date + - contextPath: EWS.Items.datetimeSent + description: Sent time of the email. + type: date + - contextPath: EWS.Items.headers + description: Email headers (list). + type: Unknown + - contextPath: EWS.Items.sender + description: Sender email address of the email. + type: string + - contextPath: EWS.Items.subject + description: Subject of the email. + type: string + - contextPath: EWS.Items.textBody + description: Body of the email (as text). + type: string + - contextPath: EWS.Items.size + description: Email size. + type: number + - contextPath: EWS.Items.toRecipients + description: List of email recipients addresses. + type: Unknown + - contextPath: EWS.Items.receivedBy + description: Received by address of the email. + type: Unknown + - contextPath: EWS.Items.messageId + description: Email message ID. + type: string + - contextPath: EWS.Items.body + description: Body of the email (as HTML). + type: string + - contextPath: EWS.Items.FileAttachments.attachmentId + description: Attachment ID of the file attachment. + type: unknown + - contextPath: EWS.Items.ItemAttachments.attachmentId + description: Attachment ID of the item attachment. + type: unknown + - contextPath: EWS.Items.FileAttachments.attachmentName + description: Attachment name of the file attachment. + type: unknown + - contextPath: EWS.Items.ItemAttachments.attachmentName + description: Attachment name of the item attachment. + type: unknown + - contextPath: EWS.Items.isRead + description: The read status of the email. + type: String + - arguments: + - default: false + description: The mailbox for which to retrieve the contacts. + isArray: false + name: target-mailbox + required: false + secret: false + - default: false + defaultValue: '50' + description: Maximum number of results to return. The default is 50. + isArray: false + name: limit + required: false + secret: false + deprecated: false + description: Retrieves contacts for a specified mailbox. + execution: false + name: ews-get-contacts + outputs: + - contextPath: Account.Email.EwsContacts.displayName + description: The contact name. + type: Unknown + - contextPath: Account.Email.EwsContacts.lastModifiedTime + description: The time that the contact was last modified. + type: Unknown + - contextPath: Account.Email.EwsContacts.emailAddresses + description: Phone numbers of the contact. + type: Unknown + - contextPath: Account.Email.EwsContacts.physicalAddresses + description: Physical addresses of the contact. + type: Unknown + - contextPath: Account.Email.EwsContacts.phoneNumbers.phoneNumber + description: Email addresses of the contact. + type: Unknown + - arguments: + - default: false + description: The mailbox for which to get the out-of-office status. + isArray: false + name: target-mailbox + required: true + secret: false + deprecated: false + description: Retrieves the out-of-office status for a specified mailbox. + execution: false + name: ews-get-out-of-office + outputs: + - contextPath: Account.Email.OutOfOffice.state + description: 'Out-of-office state. Result can be: Enabled, Scheduled, Disabled.' + type: Unknown + - contextPath: Account.Email.OutOfOffice.externalAudience + description: Out-of-office external audience. Can be "None", "Known", or "All". + type: Unknown + - contextPath: Account.Email.OutOfOffice.start + description: Out-of-office start date. + type: Unknown + - contextPath: Account.Email.OutOfOffice.end + description: Out-of-office end date. + type: Unknown + - contextPath: Account.Email.OutOfOffice.internalReply + description: Out-of-office internal reply. + type: Unknown + - contextPath: Account.Email.OutOfOffice.externalReply + description: Out-of-office external reply. + type: Unknown + - contextPath: Account.Email.OutOfOffice.mailbox + description: Out-of-office mailbox. + type: Unknown + - arguments: + - default: false + description: A comma-separated list of message IDs. Run the py-ews-delete-items command + to retrieve the message IDs + isArray: false + name: message-ids + required: true + secret: false + - default: false + defaultValue: Inbox + description: The folder path to recover the messages to. + isArray: false + name: target-folder-path + required: true + secret: false + - default: false + description: The mailbox in which the messages found. If empty, will use the + default mailbox. If you specify a different mailbox, you might need impersonation + rights to the mailbox. + isArray: false + name: target-mailbox + required: false + secret: false + - auto: PREDEFINED + default: false + description: Whether the target folder is a Public Folder. Can be "True" or "False". + isArray: false + name: is-public + predefined: + - 'True' + - 'False' + required: false + secret: false + deprecated: false + description: Recovers messages that were soft-deleted. + execution: false + name: ews-recover-messages + outputs: + - contextPath: EWS.Items.itemId + description: The item ID of the recovered item. + type: Unknown + - contextPath: EWS.Items.messageId + description: The message ID of the recovered item. + type: Unknown + - contextPath: EWS.Items.action + description: The action taken on the item. The value will be 'recovered'. + type: Unknown + - arguments: + - default: false + description: The name of the new folder. + isArray: false + name: new-folder-name + required: true + secret: false + - default: false + defaultValue: Inbox + description: Path to locate the new folder. Exchange folder ID is also supported. + isArray: false + name: folder-path + required: true + secret: false + - default: false + description: The mailbox in which to create the folder. + isArray: false + name: target-mailbox + required: false + secret: false + deprecated: false + description: Creates a new folder in a specified mailbox. + execution: false + name: ews-create-folder + - arguments: + - default: false + description: The item ID to mark as junk. + isArray: false + name: item-id + required: true + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'yes' + description: Whether to move the item from the original folder to the junk folder. Can be "yes" or "no". The default is "yes". + isArray: false + name: move-items + predefined: + - 'yes' + - 'no' + required: false + secret: false + - default: false + description: If empty, will use the default mailbox. If you specify a different + mailbox, you might need impersonation rights to the mailbox. + isArray: false + name: target-mailbox + required: false + secret: false + deprecated: false + description: 'Marks an item as junk. This is commonly used to block an email address. + For more information, see the Microsoft documentation: https://msdn.microsoft.com/en-us/library/office/dn481311(v=exchg.150).aspx' + execution: false + name: ews-mark-item-as-junk + - arguments: + - default: false + description: The mailbox on which to apply the command. + isArray: false + name: target-mailbox + required: false + secret: false + deprecated: false + description: Retrieves information for folders for a specified mailbox. Only folders + with read permissions will be returned. Your visual folders on the mailbox, + such as "Inbox", are under the folder "Top of Information Store". + execution: false + name: ews-find-folders + outputs: + - contextPath: EWS.Folders.name + description: Folder name. + type: string + - contextPath: EWS.Folders.id + description: Folder ID. + type: string + - contextPath: EWS.Folders.totalCount + description: Number of items in the folder. + type: Unknown + - contextPath: EWS.Folders.unreadCount + description: Number of unread items in the folder. + type: number + - contextPath: EWS.Folders.changeKey + description: Folder change key. + type: number + - contextPath: EWS.Folders.childrenFolderCount + description: Number of sub-folders. + type: number + - arguments: + - default: false + description: The folder path from which to get the items. + isArray: false + name: folder-path + required: true + secret: false + - default: false + defaultValue: '50' + description: Maximum number of items to return. The default is 50. + isArray: false + name: limit + required: false + secret: false + - default: false + description: The mailbox to on which to apply the command. + isArray: false + name: target-mailbox + required: false + secret: false + - auto: PREDEFINED + default: false + description: Whether the folder is a public folder. Can be "True" or "False". The default is "False". + isArray: false + name: is-public + predefined: + - 'True' + - 'False' + required: false + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'no' + description: If the email item contains another email as an attachment (EML + or MSG file), whether to retrieve the EML/MSG file attachment. Can be "yes" + or "no". The default is "no". + isArray: false + name: get-internal-item + predefined: + - 'yes' + - 'no' + required: false + secret: false + deprecated: false + description: Retrieves items from a specified folder in a mailbox. The items are + order by the item created time, most recent is first. + execution: false + name: ews-get-items-from-folder + outputs: + - contextPath: EWS.Items.itemId + description: The item ID of the email. + type: string + - contextPath: EWS.Items.hasAttachments + description: Whether the email has attachments. + type: boolean + - contextPath: EWS.Items.datetimeReceived + description: Received time of the email. + type: date + - contextPath: EWS.Items.datetimeSent + description: Sent time of the email. + type: date + - contextPath: EWS.Items.headers + description: Email headers (list). + type: Unknown + - contextPath: EWS.Items.sender + description: Sender mail address of the email. + type: string + - contextPath: EWS.Items.subject + description: Subject of the email. + type: string + - contextPath: EWS.Items.textBody + description: Body of the email (as text). + type: string + - contextPath: EWS.Items.size + description: Email size. + type: number + - contextPath: EWS.Items.toRecipients + description: Email recipients addresses (list). + type: Unknown + - contextPath: EWS.Items.receivedBy + description: Received by address of the email. + type: Unknown + - contextPath: EWS.Items.messageId + description: Email message ID. + type: string + - contextPath: EWS.Items.body + description: Body of the email (as HTML). + type: string + - contextPath: EWS.Items.FileAttachments.attachmentId + description: Attachment ID of file attachment. + type: unknown + - contextPath: EWS.Items.ItemAttachments.attachmentId + description: Attachment ID of the item attachment. + type: unknown + - contextPath: EWS.Items.FileAttachments.attachmentName + description: Attachment name of the file attachment. + type: unknown + - contextPath: EWS.Items.ItemAttachments.attachmentName + description: Attachment name of the item attachment. + type: unknown + - contextPath: EWS.Items.isRead + description: The read status of the email. + type: String + - arguments: + - default: false + description: A comma-separated list if item IDs. + isArray: true + name: item-ids + required: true + secret: false + - default: false + description: The mailbox on which to run the command. + isArray: false + name: target-mailbox + required: false + secret: false + deprecated: false + description: Retrieves items by item ID. + execution: false + name: ews-get-items + outputs: + - contextPath: EWS.Items.itemId + description: The email item ID. + type: string + - contextPath: EWS.Items.hasAttachments + description: Whether the email has attachments. + type: boolean + - contextPath: EWS.Items.datetimeReceived + description: Received time of the email. + type: date + - contextPath: EWS.Items.datetimeSent + description: Sent time of the email. + type: date + - contextPath: EWS.Items.headers + description: Email headers (list). + type: Unknown + - contextPath: EWS.Items.sender + description: Sender mail address of the email. + type: string + - contextPath: EWS.Items.subject + description: Subject of the email. + type: string + - contextPath: EWS.Items.textBody + description: Body of the email (as text). + type: string + - contextPath: EWS.Items.size + description: Email size. + type: number + - contextPath: EWS.Items.toRecipients + description: Email recipients addresses (list). + type: Unknown + - contextPath: EWS.Items.receivedBy + description: Received by address of the email. + type: Unknown + - contextPath: EWS.Items.messageId + description: Email message ID. + type: string + - contextPath: EWS.Items.body + description: Body of the email (as HTML). + type: string + - contextPath: EWS.Items.FileAttachments.attachmentId + description: Attachment ID of the file attachment. + type: unknown + - contextPath: EWS.Items.ItemAttachments.attachmentId + description: Attachment ID of the item attachment. + type: unknown + - contextPath: EWS.Items.FileAttachments.attachmentName + description: Attachment name of the file attachment. + type: unknown + - contextPath: EWS.Items.ItemAttachments.attachmentName + description: Attachment name of the item attachment. + type: unknown + - contextPath: EWS.Items.isRead + description: The read status of the email. + type: String + - contextPath: Email.CC + description: Email addresses CC'ed to the email. + type: String + - contextPath: Email.BCC + description: Email addresses BCC'ed to the email. + type: String + - contextPath: Email.To + description: The recipient of the email. + type: String + - contextPath: Email.From + description: The sender of the email. + type: String + - contextPath: Email.Subject + description: The subject of the email. + type: String + - contextPath: Email.Text + description: The plain-text version of the email. + type: String + - contextPath: Email.HTML + description: The HTML version of the email. + type: String + - contextPath: Email.HeadersMap + description: The headers of the email. + type: String + - arguments: + - default: false + description: The item ID to move. + isArray: false + name: item-id + required: true + secret: false + - default: false + description: The folder in the destination mailbox to which to move the item. + You can specify a complex path, for example, "Inbox\Phishing". + isArray: false + name: destination-folder-path + required: true + secret: false + - default: false + description: The mailbox to which to move the item. + isArray: false + name: destination-mailbox + required: true + secret: false + - default: false + description: The mailbox from which to move the item (conventionally called + the "target-mailbox", the target mailbox on which to run the command). + isArray: false + name: source-mailbox + required: false + secret: false + - auto: PREDEFINED + default: false + description: Whether the destination folder is a Public Folder. Can be "True" or "False". Default is "False". + isArray: false + name: is-public + predefined: + - 'True' + - 'False' + required: false + secret: false + deprecated: false + description: Moves an item from one mailbox to different mailbox. + execution: false + name: ews-move-item-between-mailboxes + outputs: + - contextPath: EWS.Items.movedToMailbox + description: The mailbox wo which the item was moved. + type: string + - contextPath: EWS.Items.movedToFolder + description: The folder to which the item was moved. + type: string + - contextPath: EWS.Items.action + description: The action taken on the item. The value will be "moved". + type: string + - arguments: + - default: false + description: The mailbox on which to run the search. + isArray: false + name: target-mailbox + required: false + secret: false + - default: true + defaultValue: AllItems + description: The path of the folder to retrieve. If empty, will retrieve the + folder "AllItems". + isArray: false + name: folder-path + required: false + secret: false + - auto: PREDEFINED + default: false + description: Whether the folder is a Public Folder. Default is "False". + isArray: false + name: is-public + predefined: + - 'True' + - 'False' + required: false + secret: false + deprecated: false + description: Retrieves a single folder. + execution: false + name: ews-get-folder + outputs: + - contextPath: EWS.Folders.id + description: Folder ID. + type: string + - contextPath: EWS.Folders.name + description: Folder name. + type: string + - contextPath: EWS.Folders.changeKey + description: Folder change key. + type: string + - contextPath: EWS.Folders.totalCount + description: Total number of emails in the folder. + type: number + - contextPath: EWS.Folders.childrenFolderCount + description: Number of sub-folders. + type: number + - contextPath: EWS.Folders.unreadCount + description: Number of unread emails in the folder. + type: number + - arguments: + - default: false + description: Email address of the group to expand. + isArray: false + name: email-address + required: true + secret: false + - auto: PREDEFINED + default: false + defaultValue: 'False' + description: Whether to enable recursive expansion. Can be "True" or "False". Default is "False". + isArray: false + name: recursive-expansion + predefined: + - 'True' + - 'False' + required: false + secret: false + deprecated: false + description: Expands a distribution list to display all members. By default, expands + only first layer of the distribution list. If recursive-expansion is "True", + the command expands nested distribution lists and returns all members. + execution: false + name: ews-expand-group + - arguments: + - default: false + description: A comma-separated list of item IDs. + isArray: true + name: item-ids + required: true + secret: false + - auto: PREDEFINED + default: false + defaultValue: read + description: How to mark the item. Can be "read" or "unread". Default is "read". + isArray: false + name: operation + predefined: + - read + - unread + required: false + secret: false + - default: false + description: The mailbox on which to run the command. If empty, the command + will be applied on the default mailbox. + isArray: false + name: target-mailbox + required: false + secret: false + deprecated: false + description: Marks items as read or unread. + execution: false + name: ews-mark-items-as-read + outputs: + - contextPath: EWS.Items.action + description: The action that was performed on item. + type: String + - contextPath: EWS.Items.itemId + description: The ID of the item. + type: String + - contextPath: EWS.Items.messageId + description: The message ID of the item. + type: String + - arguments: + - default: false + description: The item ID of item to upload as and EML file. + isArray: false + name: item-id + required: true + secret: false + - default: false + description: The mailbox in which this email was found. If empty, the default + mailbox is used. Otherwise the user might require impersonation rights to + this mailbox. + isArray: false + name: target-mailbox + required: false + secret: false + deprecated: false + description: Retrieves items by item ID and uploads its content as an EML file. + execution: false + name: ews-get-items-as-eml + outputs: + - contextPath: File.Size + description: The size of the file. + type: String + - contextPath: File.SHA1 + description: The SHA1 hash of the file. + type: String + - contextPath: File.SHA256 + description: The SHA256 hash of the file. + type: String + - contextPath: File.SHA512 + description: The SHA512 hash of the file. + type: String + - contextPath: File.Name + description: The name of the file. + type: String + - contextPath: File.SSDeep + description: The SSDeep hash of the file. + type: String + - contextPath: File.EntryID + description: EntryID of the file + type: String + - contextPath: File.Info + description: Information about the file. + type: String + - contextPath: File.Type + description: The file type. + type: String + - contextPath: File.MD5 + description: The MD5 hash of the file. + type: String + - contextPath: File.Extension + description: The extension of the file. + type: String + dockerimage: demisto/py3ews:1.0.0.8854 + feed: false + isfetch: true + longRunning: false + longRunningPort: false + runonce: false + script: '-' + subtype: python3 + type: python +tests: +- pyEWS_Test +- EWS search-mailbox test +fromversion: 5.0.0 diff --git a/Packs/EWS/Integrations/EWSO365/EWSO365_description.md b/Packs/EWS/Integrations/EWSO365/EWSO365_description.md new file mode 100644 index 000000000000..1b3079c5a6a1 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/EWSO365_description.md @@ -0,0 +1,6 @@ +To allow access to EWS O365, an administrator has to approve the Demisto app using an admin consent flow, by clicking on the following [link](https://oproxy.demisto.ninja/ms-ews-o365). +After authorizing the Demisto app, you will get an ID, Token, and Key, which needs to be added to the integration instance configuration's corresponding fields. + +### Required Permissions for self deployed Azure Application: +#### Exchange +* **full_access_as_app** - Application diff --git a/Packs/EWS/Integrations/EWSO365/EWSO365_image.png b/Packs/EWS/Integrations/EWSO365/EWSO365_image.png new file mode 100644 index 0000000000000000000000000000000000000000..97612d231c0fe1e91b379a640cf190d24e646957 GIT binary patch literal 3275 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 JPDHLkV1ghMDbWA` literal 0 HcmV?d00001 diff --git a/Packs/EWS/Integrations/EWSO365/EWSO365_test.py b/Packs/EWS/Integrations/EWSO365/EWSO365_test.py new file mode 100644 index 000000000000..2d1c4688ac47 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/EWSO365_test.py @@ -0,0 +1,148 @@ +import json + +from EWSO365 import ( + find_folders, + get_searchable_mailboxes, + GetSearchableMailboxes, + ExpandGroup, + get_expanded_group, +) + +with open("test_data/commands_outputs.json", "r") as f: + COMMAND_OUTPUTS = json.load(f) +with open("test_data/raw_responses.json", "r") as f: + RAW_RESPONSES = json.load(f) + + +class TestNormalCommands: + """ + The test class checks the following normal_commands: + * ews-find-folders + """ + + class MockClient: + class MockAccount: + def __init__(self): + self.root = self + self.walk_res = [] + self.all_res = "" + self.contacts = self + + def walk(self): + return self.walk_res + + def tree(self): + return "" + + def all(self): + return self.all_res + + def __init__(self): + self.default_target_mailbox = "" + self.client_id = "" + self.client_secret = "" + self.tenant_id = "" + self.folder = "" + self.is_public_folder = "" + self.request_timeout = "" + self.max_fetch = "" + self.self_deployed = "" + self.insecure = "" + self.proxy = "" + self.account = self.MockAccount() + self.protocol = "" + + def get_account(self, target_mailbox=None, access_type=None): + return self.account + + def get_items_from_mailbox(self, account, item_ids): + return "" + + def get_item_from_mailbox(self, account, item_id): + return "" + + def get_attachments_for_item(self, item_id, account, attachment_ids=None): + return "" + + def is_default_folder(self, folder_path, is_public): + return "" + + def get_folder_by_path(self, path, account=None, is_public=False): + return "" + + def test_ews_find_folders(self): + """ + This test checks the following normal_command: + * ews-find-folders + Using this method: + Given: + - command name is ews-find-folders + - client function name to mock + - expected raw result + - expected command result + When: + - we want to execute the command function + Then: + - the expected result will be the same as the entry context + """ + command_name = "ews-find-folders" + + raw_response = RAW_RESPONSES[command_name] + expected = COMMAND_OUTPUTS[command_name] + client = self.MockClient() + client.account.walk_res = raw_response + res = find_folders(client) + actual_ec = res[1] + assert expected == actual_ec + + def test_get_searchable_mailboxes(self, mocker): + """ + This test checks the following normal_command: + * ews-get-searchable-mailboxes + Using this method: + Given: + - command name is ews-get-searchable-mailboxes + - client function name to mock + - expected raw result + - expected command result + When: + - we want to execute the command function + Then: + - the expected result will be the same as the entry context + """ + command_name = "ews-get-searchable-mailboxes" + expected = COMMAND_OUTPUTS[command_name] + raw_response = RAW_RESPONSES["ews-get-searchable-mailboxes"] + mocker.patch.object(GetSearchableMailboxes, "__init__", return_value=None) + mocker.patch.object(GetSearchableMailboxes, "call", return_value=raw_response) + client = self.MockClient() + res = get_searchable_mailboxes(client) + actual_ec = res[1] + assert expected == actual_ec + + def test_expand_group(self, mocker): + """ + This test checks the following normal_command: + * ews-expand-group + Using this method: + Given: + - command name is ews-expand-group + - client function name to mock + - expected raw result + - expected command result + When: + - we want to execute the command function + Then: + - the expected result will be the same as the entry context + """ + command_name = "ews-expand-group" + expected = COMMAND_OUTPUTS[command_name] + raw_response = RAW_RESPONSES[command_name] + mocker.patch.object(ExpandGroup, "__init__", return_value=None) + mocker.patch.object(ExpandGroup, "call", return_value=raw_response) + client = self.MockClient() + res = get_expanded_group( + client, email_address="testgroup-1@demistodev.onmicrosoft.com" + ) + actual_ec = res[1] + assert expected == actual_ec diff --git a/Packs/EWS/Integrations/EWSO365/Pipfile b/Packs/EWS/Integrations/EWSO365/Pipfile new file mode 100644 index 000000000000..3523d3b6b93b --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/Pipfile @@ -0,0 +1,18 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] +pylint = "*" +pytest = "==5.0.1" +pytest-mock = "*" +requests-mock = "*" +pytest-asyncio = "*" + +[packages] +pytest = "*" +requests = "*" + +[requires] +python_version = "3.7" diff --git a/Packs/EWS/Integrations/EWSO365/Pipfile.lock b/Packs/EWS/Integrations/EWSO365/Pipfile.lock new file mode 100644 index 000000000000..6bdb9313414e --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/Pipfile.lock @@ -0,0 +1,369 @@ +{ + "_meta": { + "hash": { + "sha256": "278db815bec49c11262633d34305f9b33f09432a223bedd5329a04f758f78b55" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + ], + "version": "==19.1.0" + }, + "certifi": { + "hashes": [ + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" + ], + "version": "==2019.9.11" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "importlib-metadata": { + "hashes": [ + "sha256:652234b6ab8f2506ae58e528b6fbcc668831d3cc758e1bc01ef438d328b68cdb", + "sha256:6f264986fb88042bc1f0535fa9a557e6a376cfe5679dc77caac7fe8b5d43d05f" + ], + "markers": "python_version < '3.8'", + "version": "==0.22" + }, + "more-itertools": { + "hashes": [ + "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", + "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4" + ], + "version": "==7.2.0" + }, + "packaging": { + "hashes": [ + "sha256:a7ac867b97fdc07ee80a8058fe4435ccd274ecc3b0ed61d852d7d53055528cf9", + "sha256:c491ca87294da7cc01902edbe30a5bc6c4c28172b5138ab4e4aa1b9d7bfaeafe" + ], + "version": "==19.1" + }, + "pluggy": { + "hashes": [ + "sha256:0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", + "sha256:fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34" + ], + "version": "==0.13.0" + }, + "py": { + "hashes": [ + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" + ], + "version": "==1.8.0" + }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "version": "==2.4.2" + }, + "pytest": { + "hashes": [ + "sha256:95d13143cc14174ca1a01ec68e84d76ba5d9d493ac02716fd9706c949a505210", + "sha256:b78fe2881323bd44fd9bd76e5317173d4316577e7b1cddebae9136a4495ec865" + ], + "index": "pypi", + "version": "==5.1.2" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "index": "pypi", + "version": "==2.22.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "urllib3": { + "hashes": [ + "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", + "sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232" + ], + "version": "==1.25.3" + }, + "wcwidth": { + "hashes": [ + "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", + "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" + ], + "version": "==0.1.7" + }, + "zipp": { + "hashes": [ + "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", + "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + ], + "version": "==0.6.0" + } + }, + "develop": { + "astroid": { + "hashes": [ + "sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4", + "sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4" + ], + "version": "==2.2.5" + }, + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + ], + "version": "==19.1.0" + }, + "certifi": { + "hashes": [ + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" + ], + "version": "==2019.9.11" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "importlib-metadata": { + "hashes": [ + "sha256:652234b6ab8f2506ae58e528b6fbcc668831d3cc758e1bc01ef438d328b68cdb", + "sha256:6f264986fb88042bc1f0535fa9a557e6a376cfe5679dc77caac7fe8b5d43d05f" + ], + "markers": "python_version < '3.8'", + "version": "==0.22" + }, + "isort": { + "hashes": [ + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + ], + "version": "==4.3.21" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:02b260c8deb80db09325b99edf62ae344ce9bc64d68b7a634410b8e9a568edbf", + "sha256:18f9c401083a4ba6e162355873f906315332ea7035803d0fd8166051e3d402e3", + "sha256:1f2c6209a8917c525c1e2b55a716135ca4658a3042b5122d4e3413a4030c26ce", + "sha256:2f06d97f0ca0f414f6b707c974aaf8829c2292c1c497642f63824119d770226f", + "sha256:616c94f8176808f4018b39f9638080ed86f96b55370b5a9463b2ee5c926f6c5f", + "sha256:63b91e30ef47ef68a30f0c3c278fbfe9822319c15f34b7538a829515b84ca2a0", + "sha256:77b454f03860b844f758c5d5c6e5f18d27de899a3db367f4af06bec2e6013a8e", + "sha256:83fe27ba321e4cfac466178606147d3c0aa18e8087507caec78ed5a966a64905", + "sha256:84742532d39f72df959d237912344d8a1764c2d03fe58beba96a87bfa11a76d8", + "sha256:874ebf3caaf55a020aeb08acead813baf5a305927a71ce88c9377970fe7ad3c2", + "sha256:9f5caf2c7436d44f3cec97c2fa7791f8a675170badbfa86e1992ca1b84c37009", + "sha256:a0c8758d01fcdfe7ae8e4b4017b13552efa7f1197dd7358dc9da0576f9d0328a", + "sha256:a4def978d9d28cda2d960c279318d46b327632686d82b4917516c36d4c274512", + "sha256:ad4f4be843dace866af5fc142509e9b9817ca0c59342fdb176ab6ad552c927f5", + "sha256:ae33dd198f772f714420c5ab698ff05ff900150486c648d29951e9c70694338e", + "sha256:b4a2b782b8a8c5522ad35c93e04d60e2ba7f7dcb9271ec8e8c3e08239be6c7b4", + "sha256:c462eb33f6abca3b34cdedbe84d761f31a60b814e173b98ede3c81bb48967c4f", + "sha256:fd135b8d35dfdcdb984828c84d695937e58cc5f49e1c854eb311c4d6aa03f4f1" + ], + "version": "==1.4.2" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "more-itertools": { + "hashes": [ + "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", + "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4" + ], + "version": "==7.2.0" + }, + "packaging": { + "hashes": [ + "sha256:a7ac867b97fdc07ee80a8058fe4435ccd274ecc3b0ed61d852d7d53055528cf9", + "sha256:c491ca87294da7cc01902edbe30a5bc6c4c28172b5138ab4e4aa1b9d7bfaeafe" + ], + "version": "==19.1" + }, + "pluggy": { + "hashes": [ + "sha256:0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", + "sha256:fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34" + ], + "version": "==0.13.0" + }, + "py": { + "hashes": [ + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" + ], + "version": "==1.8.0" + }, + "pylint": { + "hashes": [ + "sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09", + "sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1" + ], + "index": "pypi", + "version": "==2.3.1" + }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "version": "==2.4.2" + }, + "pytest": { + "hashes": [ + "sha256:95d13143cc14174ca1a01ec68e84d76ba5d9d493ac02716fd9706c949a505210", + "sha256:b78fe2881323bd44fd9bd76e5317173d4316577e7b1cddebae9136a4495ec865" + ], + "index": "pypi", + "version": "==5.1.2" + }, + "pytest-asyncio": { + "hashes": [ + "sha256:9fac5100fd716cbecf6ef89233e8590a4ad61d729d1732e0a96b84182df1daaf", + "sha256:d734718e25cfc32d2bf78d346e99d33724deeba774cc4afdf491530c6184b63b" + ], + "index": "pypi", + "version": "==0.10.0" + }, + "pytest-mock": { + "hashes": [ + "sha256:43ce4e9dd5074993e7c021bb1c22cbb5363e612a2b5a76bc6d956775b10758b7", + "sha256:5bf5771b1db93beac965a7347dc81c675ec4090cb841e49d9d34637a25c30568" + ], + "index": "pypi", + "version": "==1.10.4" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "index": "pypi", + "version": "==2.22.0" + }, + "requests-mock": { + "hashes": [ + "sha256:510df890afe08d36eca5bb16b4aa6308a6f85e3159ad3013bac8b9de7bd5a010", + "sha256:88d3402dd8b3c69a9e4f9d3a73ad11b15920c6efd36bc27bf1f701cf4a8e4646" + ], + "index": "pypi", + "version": "==1.7.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, + "typed-ast": { + "hashes": [ + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + ], + "markers": "implementation_name == 'cpython'", + "version": "==1.4.0" + }, + "urllib3": { + "hashes": [ + "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", + "sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232" + ], + "version": "==1.25.3" + }, + "wcwidth": { + "hashes": [ + "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", + "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" + ], + "version": "==0.1.7" + }, + "wrapt": { + "hashes": [ + "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" + ], + "version": "==1.11.2" + }, + "zipp": { + "hashes": [ + "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", + "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + ], + "version": "==0.6.0" + } + } +} diff --git a/Packs/EWS/Integrations/EWSO365/README.md b/Packs/EWS/Integrations/EWSO365/README.md new file mode 100644 index 000000000000..d9a5c5f446d1 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/README.md @@ -0,0 +1,1354 @@ +Exchange Web Services (EWS) provides the functionality to enable client applications to communicate with the Exchange server. EWS provides access to much of the same data that is made available through Microsoft OfficeOutlook. + +The EWS O365 integration implants EWS leading services. The integration allows getting information on emails and activities in a target mailbox, and some active operations on the mailbox such as deleting emails and attachments or moving emails from folder to folder. + +## EWS O365 Playbook + +* Office 365 Search and Delete +* Search And Delete Emails - EWS +* Get Original Email - EWS +* Process Email - EWS + +## Use Cases + +The EWS integration can be used for the following use cases. + +* Monitor a specific email account and create incidents from incoming emails to the defined folder. + Follow the instructions in the Fetched Incidents Data section. + +* Search for an email message across mailboxes and folders. + This can be achieved in the following ways: + + 1. Use the `ews-search-mailboxes` command to search for all emails in a specific scope of mailboxes. + Use the filter argument to narrow the search for emails sent from a specific account and more. + 2. Use the `ews-search-mailbox` command to search for all emails in a specific folder within the target mailbox. + Use the query argument to narrow the search for emails sent from a specific account and more. + * Both of these commands retrieve the _ItemID_ field for each email item listed in the results. The `ItemID` can be used in the `ews-get-items` command in order to get more information about the email item itself. + * For instance, use the `ews-search-mailboxes` command to hunt for emails that were marked as malicious in prior investigations, across organization mailboxes. Focus your hunt on emails sent from a specific mail account, emails with a specific subject and more. +* Get email attachment information. + Use the `ews-get-attachment` command to retrieve information on one attachment or all attachments of a message at once. It supports both file attachments and item attachments (e.g., email messages). + +* Delete email items from a mailbox. + First, make sure you obtain the email item ID. The item ID can be obtained with one of the integration’s search commands. + Use the `ews-delete-items` command to delete one or more items from the target mailbox in a single action. + A less common use case is to remove emails that were marked as malicious from a user’s mailbox. + You can delete the items permanently (hard delete), or delete the items (soft delete), so they can be recovered by running the `ews-recover-messages` command. + +## Configure EWS O365 on Demisto + +1. Navigate to **Settings** > **Integrations** > **Servers & Services**. +2. Search for EWS O365. +3. Click **Add instance** to create and configure a new integration instance. + * **Name**: a textual name for the integration instance. + * **ID / Application ID**: ID recieved from https://oproxy.demisto.ninja/ms-ews-o365 app registration, or a self deployed Application ID. + * **Token / Tenant ID**: Token recieved from https://oproxy.demisto.ninja/ms-ews-o365 app registration, or a self deployed Application Tenant ID. + * **Key / Application Secret**: Key recieved from https://oproxy.demisto.ninja/ms-ews-o365 app registration, or a self deployed Application Secret. + * **Email Address**: Mailbox to run commands on, and to fetch incidents from. This argument can take various user accounts in your organization. Usually is used as phishing mailbox. + Note: To use this functionality, your account must have impersonation rights or delegation for the account specified. For more information on impersonation rights see ‘Additional Information’ section below. + * **Name of the folder from which to fetch incidents**: Supports Exchange Folder ID and sub-folders e.g. Inbox/Phishing. Please note, if Exchange is configured with an international flavor `Inbox` will be named according to the configured language. + * **Public Folder** + * **Use system proxy settings** + * **Trust any certificate (not secure)** + * **Timeout (in seconds) for HTTP requests to Exchange Server** + * **Use a self deployed Azure Application** +4. Click **Test** to validate the URLs, token, and connection. + +## Use a Self-Deployed Azure Application + +To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal. To add the registration, refer to the [Microsoft documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) +
The Tenant ID, Client ID, and Client secret are required for the integration. +* ID - Application (Client) ID +* Token - Tenant ID +* Key - Application (Client) Secret + +## Fetched Incidents Data + +The integration imports email messages from the destination folder in the target mailbox as incidents. If the message contains any attachments, they are uploaded to the War Room as files. If the attachment is an email, Demisto fetches information about the attached email and downloads all of its attachments (if there are any) as files. + +To use Fetch incidents, configure a new instance and select the `Fetches incidents` option in the instance settings. + +IMPORTANT: The initial fetch interval is the previous 10 minutes. If no emails were fetched before from the destination folder- all emails from 10 minutes prior to the instance configuration and up to the current time will be fetched. + +Pay special attention to the following fields in the instance settings: + +`Email Address` – mailbox to fetch incidents from. +`Name of the folder from which to fetch incidents` – use this field to configure the destination folder from where emails should be fetched. The default is Inbox folder. Please note, if Exchange is configured with an international flavor `Inbox` will be named according to the configured language. + +## Commands + +You can execute these commands from the Demisto 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. + +1. [Get the attachments of an item: ews-get-attachment](#h_22ec0bbb-12b3-4f1c-9159-b1a4daa114c7) +2. [Delete the attachments of an item: ews-delete-attachment](#h_cae18768-1dd5-4cd1-b2c9-abfd0e7787f3) +3. [Get a list of searchable mailboxes: ews-get-searchable-mailboxes](#h_7bdec9fe-e3d9-4645-8da4-337ee3798a84) +5. [Move an item to a different folder: ews-move-item](#h_0661f657-850a-430a-8fe1-aacf7e3ce40b) +6. [Delete an item from a mailbox: ews-delete-items](#h_712791a3-5937-4641-8e02-1fd773ab3211) +7. [Search a single mailbox: ews-search-mailbox](#h_2b4fd205-165c-489f-b58c-3bb77a86acfc) +8. [Get the contacts for a mailbox: ews-get-contacts](#h_3b6dc53b-4c1a-4479-a529-0ff3300dc4f5) +9. [Get the out-of-office status for a mailbox: ews-get-out-of-office](#h_b592e5fe-af2a-4d3c-90aa-b933e69a7526) +10. [Recover soft-deleted messages: ews-recover-messages](#h_212102bb-4ad8-4bb8-9c05-1b1197e2a9c9) +11. [Create a folder: ews-create-folder](#h_4ab168b9-21e9-4ce1-b18c-56bc22c0e0bd) +12. [Mark an item as junk: ews-mark-item-as-junk](#h_01b093ea-bc1c-46a3-b694-8cd45effeaa0) +13. [Search for folders: ews-find-folders](#h_3f9e1f1e-e634-4f92-b2a2-cdca5ca662eb) +14. [Get items of a folder: ews-get-items-from-folder](#h_0035899d-fdd0-43b7-bf7b-11a38a2e575a) +15. [Get items: ews-get-items](#h_e8f449a2-aecf-4d65-8d04-a38c6d4bfe62) +16. [Move an item to a different mailbox: ews-move-item-between-mailboxes](#h_88c0edd5-09b0-42a1-a671-b36b73772898) +17. [Get a folder: ews-get-folder](#h_87ca72d4-d98a-462e-9829-c940321663c2) +18. [Expand a distribution list: ews-expand-group](#h_d91ca450-7004-4a19-a88d-840389b21556) +19. [Mark items as read: ews-mark-items-as-read](#h_e278dc88-b4b0-4330-b849-3069b770e5ba) + +### 1\. Get the attachments of an item + +* * * + +Retrieves the actual attachments from an item (email message). To get all attachments for a message, only specify the item-id argument. + +##### Required Permissions + +Impersonation rights required. In order to perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-get-attachment` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-id|The ID of the email message for which to get the attachments.|Required| +|target-mailbox|The mailbox in which this attachment was found. If empty, the default mailbox is used. Otherwise, the user might require impersonation rights to this mailbox.|Optional| +|attachment-ids|The attachments ids to get. If none - all attachments will be retrieved from the message. Support multiple attachments with comma-separated value or array.|Optional| + + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.FileAttachments.attachmentId|string|The attachment ID. Used for file attachments only.| +|EWS.Items.FileAttachments.attachmentName|string|The attachment name. Used for file attachments only.| +|EWS.Items.FileAttachments.attachmentSHA256|string|The SHA256 hash of the attached file.| +|EWS.Items.FileAttachments.attachmentLastModifiedTime|date|The attachment last modified time. Used for file attachments only.| +|EWS.Items.ItemAttachments.datetimeCreated|date|The created time of the attached email.| +|EWS.Items.ItemAttachments.datetimeReceived|date|The received time of the attached email.| +|EWS.Items.ItemAttachments.datetimeSent|date|The sent time of the attached email.| +|EWS.Items.ItemAttachments.receivedBy|string|The received by address of the attached email.| +|EWS.Items.ItemAttachments.subject|string|The subject of the attached email.| +|EWS.Items.ItemAttachments.textBody|string|The body of the attached email (as text).| +|EWS.Items.ItemAttachments.headers|Unknown|The headers of the attached email.| +|EWS.Items.ItemAttachments.hasAttachments|boolean|Whether the attached email has attachments.| +|EWS.Items.ItemAttachments.itemId|string|The attached email item ID.| +|EWS.Items.ItemAttachments.toRecipients|Unknown|A list of recipient email addresses for the attached email.| +|EWS.Items.ItemAttachments.body|string|The body of the attached email (as HTML).| +|EWS.Items.ItemAttachments.attachmentSHA256|string|SHA256 hash of the attached email (as EML file).| +|EWS.Items.ItemAttachments.FileAttachments.attachmentSHA256|string|SHA256 hash of the attached files inside of the attached email.| +|EWS.Items.ItemAttachments.ItemAttachments.attachmentSHA256|string|SHA256 hash of the attached emails inside of the attached email.| +|EWS.Items.ItemAttachments.isRead|String|The read status of the attachment.| + + +##### Command Example + +``` +!ews-get-attachment item-id=BBFDShfdafFSDF3FADR3434DFASDFADAFDADFADFCJebinpkUAAAfxuiVAAA= target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "ItemAttachments": { + "originalItemId": "BBFDShfdafFSDF3FADR3434DFASDFADAFDADFADFCJebinpkUAAAfxuiVAAA=", + "attachmentSize": 2956, + "receivedBy": "test@demistodev.onmicrosoft.com", + "size": 28852, + "author": "test2@demistodev.onmicrosoft.com", + "attachmentLastModifiedTime": "2019-08-11T15:01:30+00:00", + "subject": "Moving Email between mailboxes", + "body": "Some text inside", + "datetimeCreated": "2019-08-11T15:01:47Z", + "importance": "Normal", + "attachmentType": "ItemAttachment", + "toRecipients": [ + "test@demistodev.onmicrosoft.com" + ], + "mailbox": "test@demistodev.onmicrosoft.com", + "isRead": false, + "attachmentIsInline": false, + "datetimeSent": "2019-08-07T12:50:19Z", + "lastModifiedTime": "2019-08-11T15:01:30Z", + "sender": "test2@demistodev.onmicrosoft.com", + "attachmentName": "Moving Email between mailboxes", + "datetimeReceived": "2019-08-07T12:50:20Z", + "attachmentSHA256": "119e27b28dc81bdfd4f498d44bd7a6d553a74ee03bdc83e6255a53", + "hasAttachments": false, + "headers": [ + { + "name": "Subject", + "value": "Moving Email between mailboxes" + } + ... + ], + "attachmentId": "BBFDShfdafFSDF3FADR3434DFASDFADAFDADFADFCJebinpkUAAAfxuiVAAABEgAQAOpEfpzDB4dFkZ+/K4XSj44=", + "messageId": "message_id" + } + } + } + +``` + +### 2\. Delete the attachments of an item + +* * * + +Deletes the attachments of an item (email message). + +##### Required Permissions + +Impersonation rights required. In order to perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-delete-attachment` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-id|The ID of the email message for which to delete attachments.|Required| +|target-mailbox|The mailbox in which this attachment was found. If empty, the default mailbox is used. Otherwise, the user might require impersonation rights to this mailbox.|Optional| +|attachment-ids|A CSV list (or array) of attachment IDs to delete. If empty, all attachments will be deleted from the message.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.FileAttachments.attachmentId|string|The ID of the deleted attachment, in case of file attachment.| +|EWS.Items.ItemAttachments.attachmentId|string|The ID of the deleted attachment, in case of other attachment (for example, "email").| +|EWS.Items.FileAttachments.action|string|The deletion action in case of file attachment. This is a constant value: 'deleted'.| +|EWS.Items.ItemAttachments.action|string|The deletion action in case of other attachment (for example, "email"). This is a constant value: 'deleted'.| + +##### Command Example + +``` +!ews-delete-attachment item-id=AAMkADQ0NmwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUQZfBJjfaljfAFDVSDinpkUAAAfxxd9AAA= target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|action|attachmentId| +|--- |--- | +|deleted|AAMkADQ0NmwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUQZfBJjfaljfAFDVSDinpkUAAAfxxd9AAABEgAQAIUht2vrOdErec33=| + +### Context Example + +``` +{ + "EWS": { + "Items": { + "FileAttachments": { + "action": "deleted", + "attachmentId": "AAMkADQ0NmwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUQZfBJjfaljfAFDVSDinpkUAAAfxxd9AAABEgAQAIUht2vrOdErec33=" + } + } + } +} + +``` + +### 3\. Get a list of searchable mailboxes + +* * * + +Returns a list of searchable mailboxes. + +##### Required Permissions + +Requires eDiscovery permissions to the Exchange Server. For more information see the [Microsoft documentation](https://technet.microsoft.com/en-us/library/dd298059(v=exchg.160).aspx). + +##### Base Command + +`ews-get-searchable-mailboxes` + +##### Input + +There are no input arguments for this command. + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Mailboxes.mailbox|string|Addresses of the searchable mailboxes.| +|EWS.Mailboxes.mailboxId|string|IDs of the searchable mailboxes.| +|EWS.Mailboxes.displayName|string|The email display name.| +|EWS.Mailboxes.isExternal|boolean|Whether the mailbox is external.| +|EWS.Mailboxes.externalEmailAddress|string|The external email address.| + +##### Command Example + +``` +!ews-get-searchable-mailboxes +``` + +##### Human Readable Output + +|displayName|isExternal|mailbox|mailboxId| +|--- |--- |--- |--- | +|test|false|test@demistodev.onmicrosoft.com|/o=Exchange***/ou=Exchange Administrative Group ()/cn=**/cn=**-**| + +##### Context Example + +``` +{ + "EWS": { + "Mailboxes": [ + { + "mailbox": "test@demistodev.onmicrosoft.com", + "displayName": "test", + "mailboxId": "/o=Exchange***/ou=Exchange Administrative Group ()/cn=**/cn=**-**", + "isExternal": "false" + } + ... + ] + } +} + +``` + +### 4\. Move an item to a different folder + +* * * + +Move an item to a different folder in the mailbox. + +##### Required Permissions + +Impersonation rights required. In order to perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-move-item` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-id|The ID of the item to move.|Required| +|target-folder-path|The path to the folder to which to move the item. Complex paths are supported, for example, "Inbox\Phishing".|Required| +|target-mailbox|The mailbox on which to run the command.|Optional| +|is-public|Whether the target folder is a public folder.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.newItemID|string|The item ID after the move.| +|EWS.Items.messageID|string|The item message ID.| +|EWS.Items.itemId|string|The original item ID.| +|EWS.Items.action|string|The action taken. The value will be "moved".| + +##### Command Example + +``` +!ews-move-item item-id=VDAFNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU34cSCSSSfBJebinpkUAAAAAAEMAACyyVyFtlsUQZfBJebinpkUAAAfxuiRAAA= target-folder-path=Moving target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|action|itemId|messageId|newItemId| +|--- |--- |--- |--- | +|moved|VDAFNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU34cSCSSSfBJebinpkUAAAAAAEMAACyyVyFtlsUQZfBJebinpkUAAAfxuiRAAA||AAVAAAVN2NkLThmZjdmNTZjNTMxFFFFJTJPMPXU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAAa2bUBAACyyVfafainpkUAAAfxxd+AAA=| + +##### Context Example + + { + "EWS": { + "Items": { + "action": "moved", + "itemId": "VDAFNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU34cSCSSSfBJebinpkUAAAAAAEMAACyyVyFtlsUQZfBJebinpkUAAAfxuiRAAA", + "newItemId": "AAVAAAVN2NkLThmZjdmNTZjNTMxFFFFJTJPMPXU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAAa2bUBAACyyVfafainpkUAAAfxxd+AAA=", + "messageId": "" + } + } + } + +### 5\. Delete an item from a mailbox + +* * * + +Delete items from mailbox. + +##### Required Permissions + +Impersonation rights required. In order to perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-delete-items` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-ids|The item IDs to delete.|Required| +|delete-type|Deletion type. Can be "trash", "soft", or "hard".|Required| +|target-mailbox|The mailbox on which to run the command.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.itemId|string|The deleted item ID.| +|EWS.Items.messageId|string|The deleted message ID.| +|EWS.Items.action|string|The deletion action. Can be 'trash-deleted', 'soft-deleted', or 'hard-deleted'.| + +##### Command Example + +``` +!ews-delete-items item-ids=VWAFA3hmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAABjKMGAACyw+kAAA= delete-type=soft target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|action|itemId|messageId| +|--- |--- |--- | +|soft-deleted|VWAFA3hmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAABjKMGAACyw+kAAA=|| + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "action": "soft-deleted", + "itemId": "VWAFA3hmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAABjKMGAACyw+kAAA=", + "messageId": "messaage_id" + } + } +} + +``` + +### 6\. Search a single mailbox + +* * * + +Searches for items in the specified mailbox. Specific permissions are needed for this operation to search in a target mailbox other than the default. + +##### Required Permissions + +Impersonation rights required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-search-mailbox` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|query|The search query string. For more information about the query syntax, see the [Microsoft documentation](https://msdn.microsoft.com/en-us/library/ee693615.aspx).|Optional| +|folder-path|The folder path in which to search. If empty, searches all the folders in the mailbox.|Optional| +|limit|Maximum number of results to return.|Optional| +|target-mailbox|The mailbox on which to apply the search.|Optional| +|is-public|Whether the folder is a Public Folder?|Optional| +|message-id|The message ID of the email. This will be ignored if a query argument is provided.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.itemId|string|The email item ID.| +|EWS.Items.hasAttachments|boolean|Whether the email has attachments.| +|EWS.Items.datetimeReceived|date|Received time of the email.| +|EWS.Items.datetimeSent|date|Sent time of the email.| +|EWS.Items.headers|Unknown|Email headers (list).| +|EWS.Items.sender|string|Sender email address of the email.| +|EWS.Items.subject|string|Subject of the email.| +|EWS.Items.textBody|string|Body of the email (as text).| +|EWS.Items.size|number|Email size.| +|EWS.Items.toRecipients|Unknown|List of email recipients addresses.| +|EWS.Items.receivedBy|Unknown|Email received by address.| +|EWS.Items.messageId|string|Email message ID.| +|EWS.Items.body|string|Body of the email (as HTML).| +|EWS.Items.FileAttachments.attachmentId|unknown|Attachment ID of the file attachment.| +|EWS.Items.ItemAttachments.attachmentId|unknown|Attachment ID of the item attachment.| +|EWS.Items.FileAttachments.attachmentName|unknown|Attachment name of the file attachment.| +|EWS.Items.ItemAttachments.attachmentName|unknown|Attachment name of the item attachment.| +|EWS.Items.isRead|String|The read status of the email.| + +##### Command Example + +``` +!ews-search-mailbox query="subject:"Get Attachment Email" target-mailbox=test@demistodev.onmicrosoft.com limit=1 +``` + +##### Human Readable Output + +|sender|subject|hasAttachments|datetimeReceived|receivedBy|author|toRecipients| +|--- |--- |--- |--- |--- |--- |--- | +|test2@demistodev.onmicrosoft.com|Get Attachment Email|true|2019-08-11T10:57:37Z|test@demistodev.onmicrosoft.com|test2@demistodev.onmicrosoft.com|test@demistodev.onmicrosoft.com| + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "body": "\r\n\r\n\r\n\r\n\r\n\r\n

\r\n\r\n\r\n", + "itemId": "AAMkADQ0NmFFijer3FFmNTZjNTMxNwBGAAAAAAFSAAfxw+jAAA=", + "toRecipients": [ + "test@demistodev.onmicrosoft.com" + ], + "datetimeCreated": "2019-08-11T10:57:37Z", + "datetimeReceived": "2019-08-11T10:57:37Z", + "author": "test2@demistodev.onmicrosoft.com", + "hasAttachments": true, + "size": 30455, + "subject": "Get Attachment Email", + "FileAttachments": [ + { + "attachmentName": "atta1.rtf", + "attachmentSHA256": "csfd81097bc049fbcff6e637ade0407a00308bfdfa339e31a44a1c4e98f28ce36e4f", + "attachmentType": "FileAttachment", + "attachmentSize": 555, + "attachmentId": "AAMkADQ0NmFkODFkLWQ4MDEtNDE4Mi1hN2NkLThmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAABjKMGAACyyVyFtlsUQZfBJebinpkUAAAfxw+jAAABEgAQAEyq1TB2nKBLpKUiFUJ5Geg=", + "attachmentIsInline": false, + "attachmentLastModifiedTime": "2019-08-11T11:06:02+00:00", + "attachmentContentLocation": null, + "attachmentContentType": "text/rtf", + "originalItemId": "AAMkADQ0NmFFijer3FFmNTZjNTMxNwBGAAAAAAFSAAfxw+jAAA=", + "attachmentContentId": null + } + ], + "headers": [ + { + "name": "Subject", + "value": "Get Attachment Email" + }, + ... + ], + "isRead": true, + "messageId": "", + "receivedBy": "test@demistodev.onmicrosoft.com", + "datetimeSent": "2019-08-11T10:57:36Z", + "lastModifiedTime": "2019-08-11T11:13:59Z", + "mailbox": "test@demistodev.onmicrosoft.com", + "importance": "Normal", + "textBody": "Some text inside email\r\n", + "sender": "test2@demistodev.onmicrosoft.com" + } + } +} + +``` + +### 7\. Get the contacts for a mailbox + +* * * + +Retrieves contacts for a specified mailbox. + +##### Required Permissions + +Impersonation rights required. In order to perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-get-contacts` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|target-mailbox|The mailbox for which to retrieve the contacts.|Optional| +|limit|Maximum number of results to return.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|Account.Email.EwsContacts.displayName|Unknown|The contact name.| +|Account.Email.EwsContacts.lastModifiedTime|Unknown|The time that the contact was last modified.| +|Account.Email.EwsContacts.emailAddresses|Unknown|Phone numbers of the contact.| +|Account.Email.EwsContacts.physicalAddresses|Unknown|Physical addresses of the contact.| +|Account.Email.EwsContacts.phoneNumbers.phoneNumber|Unknown|Email addresses of the contact.| + +##### Command Example + +``` +!ews-get-contacts limit="1" +``` + +##### Human Readable Output + +|changekey|culture|datetimeCreated|datetimeReceived|datetimeSent|displayName|emailAddresses|fileAs|fileAsMapping|givenName|id|importance|itemClass|lastModifiedName|lastModifiedTime|postalAddressIndex|sensitivity|subject|uniqueBody|webClientReadFormQueryString| +|--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- | +|EABYACAADcsxRwRjq/zTrN6vWSzKAK1Dl3N|en-US|2019-08-05T12:35:36Z|2019-08-05T12:35:36Z|2019-08-05T12:35:36Z|Contact Name|some@dev.microsoft.com|Contact Name|LastCommaFirst|Contact Name|AHSNNK3NQNcasnc3SAS/zTrN6vWSzK4OWAAAAAAEOAADrxRwRjq/zTrNFSsfsfVWAAK1KsF3AAA=|Normal|IPM.Contact|John Smith|2019-08-05T12:35:36Z|None|Normal|Contact Name||https://outlook.office365.com/owa/?ItemID=***| + +##### Context Example + +``` +{ + "Account.Email": [ + { + "itemClass": "IPM.Contact", + "lastModifiedName": "John Smith", + "displayName": "Contact Name", + "datetimeCreated": "2019-08-05T12:35:36Z", + "datetimeReceived": "2019-08-05T12:35:36Z", + "fileAsMapping": "LastCommaFirst", + "importance": "Normal", + "sensitivity": "Normal", + "postalAddressIndex": "None", + "webClientReadFormQueryString": "https://outlook.office365.com/owa/?ItemID=***", + "uniqueBody": "", + "fileAs": "Contact Name", + "culture": "en-US", + "changekey": "EABYACAADcsxRwRjq/zTrN6vWSzKAK1Dl3N", + "lastModifiedTime": "2019-08-05T12:35:36Z", + "datetimeSent": "2019-08-05T12:35:36Z", + "emailAddresses": [ + "some@dev.microsoft.com" + ], + "givenName": "Contact Name", + "id": "AHSNNK3NQNcasnc3SAS/zTrN6vWSzK4OWAAAAAAEOAADrxRwRjq/zTrNFSsfsfVWAAK1KsF3AAA=", + "subject": "Contact Name" + } + ] +} + +``` + +### 8\. Get the out-of-office status for a mailbox + +* * * + +Retrieves the out-of-office status for a specified mailbox. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part the ApplicationImpersonation role. + +##### Base Command + +`ews-get-out-of-office` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|target-mailbox|The mailbox for which to get the out-of-office status.|Required| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|Account.Email.OutOfOffice.state|Unknown|Out-of-office state. The result can be: "Enabled", "Scheduled", or "Disabled".| +|Account.Email.OutOfOffice.externalAudience|Unknown|Out-of-office external audience. Can be "None", "Known", or "All".| +|Account.Email.OutOfOffice.start|Unknown|Out-of-office start date.| +|Account.Email.OutOfOffice.end|Unknown|Out-of-office end date.| +|Account.Email.OutOfOffice.internalReply|Unknown|Out-of-office internal reply.| +|Account.Email.OutOfOffice.externalReply|Unknown|Out-of-office external reply.| +|Account.Email.OutOfOffice.mailbox|Unknown|Out-of-office mailbox.| + +##### Command Example + +``` +!ews-get-out-of-office target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|end|externalAudience|mailbox|start|state| +|--- |--- |--- |--- |--- | +|2019-08-12T13:00:00Z|All|test@demistodev.onmicrosoft.com|2019-08-11T13:00:00Z|Disabled| + +##### Context Example + +``` +{ + "Account": { + "Email": { + "OutOfOffice": { + "start": "2019-08-11T13:00:00Z", + "state": "Disabled", + "mailbox": "test@demistodev.onmicrosoft.com", + "end": "2019-08-12T13:00:00Z", + "externalAudience": "All" + } + } + } +} + +``` + +### 9\. Recover soft-deleted messages + +* * * + +Recovers messages that were soft-deleted. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-recover-messages` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|message-ids|A CSV list of message IDs. Run the py-ews-delete-items command to retrieve the message IDs|Required| +|target-folder-path|The folder path to recover the messages to.|Required| +|target-mailbox|The mailbox in which the messages found. If empty, will use the default mailbox. If you specify a different mailbox, you might need impersonation rights to the mailbox.|Optional| +|is-public|Whether the target folder is a Public Folder.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.itemId|Unknown|The item ID of the recovered item.| +|EWS.Items.messageId|Unknown|The message ID of the recovered item.| +|EWS.Items.action|Unknown|The action taken on the item. The value will be 'recovered'.| + +##### Command Example + +``` +!ews-recover-messages message-ids= target-folder-path=Moving target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|action|itemId|messageId| +|--- |--- |--- | +|recovered|AAVCSVS1hN2NkLThmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed33wX3aBwCyyVyFtlsUQZfBJebinpkUAAAa2bUBAACyyVyFtlscfxxd/AAA=|| + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "action": "recovered", + "itemId": "AAVCSVS1hN2NkLThmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed33wX3aBwCyyVyFtlsUQZfBJebinpkUAAAa2bUBAACyyVyFtlscfxxd/AAA=", + "messageId": "" + } + } +} + +``` + +### 10\. Create a folder + +* * * + +Creates a new folder in a specified mailbox. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-create-folder` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|new-folder-name|The name of the new folder.|Required| +|folder-path|Path to locate the new folder. Exchange folder ID is also supported.|Required| +|target-mailbox|The mailbox in which to create the folder.|Optional| + +##### Context Output + +There is no context output for this command. + +##### Command Example + +``` +!ews-create-folder folder-path=Inbox new-folder-name="Created Folder" target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +Folder Inbox\Created Folder created successfully + +### 11\. Mark an item as junk + +* * * + +Marks an item as junk. This is commonly used to block an email address. For more information, see the [Microsoft documentation](https://msdn.microsoft.com/en-us/library/office/dn481311(v=exchg.150).aspx). + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-mark-item-as-junk` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-id|The item ID to mark as junk.|Required| +|move-items|Whether to move the item from the original folder to the junk folder.|Optional| +|target-mailbox|If empty, will use the default mailbox. If you specify a different mailbox, you might need impersonation rights to the mailbox.|Optional| + +##### Context Output + +There is no context output for this command. + +##### Command Example + +``` +!ews-mark-item-as-junk item-id=AAMkcSQ0NmFkOhmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUcsBJebinpkUAAAAAAEMASFDkUAAAfxuiSAAA= move-items=yes target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|action|itemId| +|--- |--- | +|marked-as-junk|AAMkcSQ0NmFkOhmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUcsBJebinpkUAAAAAAEMASFDkUAAAfxuiSAAA=| + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "action": "marked-as-junk", + "itemId": "AAMkcSQ0NmFkOhmZjdmNTZjNTMxNwBGAAAAAAA4kxh+ed3JTJPMPXU3wX3aBwCyyVyFtlsUcsBJebinpkUAAAAAAEMASFDkUAAAfxuiSAAA=" + } + } +} + +``` + +### 12\. Search for folders + +* * * + +Retrieves information for the folders of the specified mailbox. Only folders with read permissions will be returned. Your visual folders on the mailbox, such as "Inbox", are under the folder "Top of Information Store". + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-find-folders` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|target-mailbox|The mailbox on which to apply the command.|Optional| +|is-public|Whether to find Public Folders.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Folders.name|string|Folder name.| +|EWS.Folders.id|string|Folder ID.| +|EWS.Folders.totalCount|Unknown|Number of items in the folder.| +|EWS.Folders.unreadCount|number|Number of unread items in the folder.| +|EWS.Folders.changeKey|number|Folder change key.| +|EWS.Folders.childrenFolderCount|number|Number of sub-folders.| + +##### Command Example + +``` +!ews-find-folders target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +``` +root +├── AllContacts +├── AllItems +├── Common Views +├── Deferred Action +├── ExchangeSyncData +├── Favorites +├── Freebusy Data +├── Location +├── MailboxAssociations +├── My Contacts +├── MyContactsExtended +├── People I Know +├── PeopleConnect +├── Recoverable Items +│ ├── Calendar Logging +│ ├── Deletions +│ ── Purges +│ └── Versions +├── Reminders +├── Schedule +├── Sharing +├── Shortcuts +├── Spooler Queue +├── System +├── To-Do Search +├── Top of Information Store +│ ├── Calendar +│ ├── Contacts +│ │ ├── GAL Contacts +│ │ ├── Recipient Cache +│ ├── Conversation Action Settings +│ ├── Deleted Items +│ │ └── Create1 +│ ├── Drafts +│ ├── Inbox +... + +``` + +##### Context Example + +``` +{ + "EWS": { + "Folders": [ + { + "unreadCount": 1, + "name": "Inbox", + "childrenFolderCount": 1, + "totalCount": 44, + "changeKey": "**********fefsduQi0", + "id": "*******VyFtlFDSAFDSFDAAA=" + } + ... + ] + } +} + +``` + +### 13\. Get items of a folder + +* * * + +Retrieves items from a specified folder in a mailbox. The items are ordered by the item created time, most recent is first. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-get-items-from-folder` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|folder-path|The folder path from which to get the items.|Required| +|limit|Maximum number of items to return.|Optional| +|target-mailbox|The mailbox on which to apply the command.|Optional| +|is-public|Whether the folder is a Public Folder. Default is 'False'.|Optional| +|get-internal-items|If the email item contains another email as an attachment (EML or MSG file), whether to retrieve the EML/MSG file attachment. Can be "yes" or "no". Default is "no".|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.itemId|string|The item ID of the email.| +|EWS.Items.hasAttachments|boolean|Whether the email has attachments.| +|EWS.Items.datetimeReceived|date|Received time of the email.| +|EWS.Items.datetimeSent|date|Sent time of the email.| +|EWS.Items.headers|Unknown|Email headers (list).| +|EWS.Items.sender|string|Sender mail address of the email.| +|EWS.Items.subject|string|Subject of the email.| +|EWS.Items.textBody|string|Body of the email (as text).| +|EWS.Items.size|number|Email size.| +|EWS.Items.toRecipients|Unknown|Email recipients addresses (list).| +|EWS.Items.receivedBy|Unknown|Received by address of the email.| +|EWS.Items.messageId|string|Email message ID.| +|EWS.Items.body|string|Body of the email (as HTML).| +|EWS.Items.FileAttachments.attachmentId|unknown|Attachment ID of file attachment.| +|EWS.Items.ItemAttachments.attachmentId|unknown|Attachment ID of the item attachment.| +|EWS.Items.FileAttachments.attachmentName|unknown|Attachment name of the file attachment.| +|EWS.Items.ItemAttachments.attachmentName|unknown|Attachment name of the item attachment.| +|Email.Items.ItemAttachments.attachmentName|unknown|Attachment name of the item attachment.| +|EWS.Items.isRead|String|The read status of the email.| + +##### Command Example + +``` +!ews-get-items-from-folder folder-path=Test target-mailbox=test@demistodev.onmicrosoft.com limit=1 +``` + +##### Human Readable Output + +|sender|subject|hasAttachments|datetimeReceived|receivedBy|author|toRecipients|itemId| +|--- |--- |--- |--- |--- |--- |--- |--- | +|test2@demistodev.onmicrosoft.com|Get Attachment Email|true|2019-08-11T10:57:37Z|test@demistodev.onmicrosoft.com|test2@demistodev.onmicrosoft.com|test@demistodev.onmicrosoft.com|AAFSFSFFtlsUQZfBJebinpkUAAABjKMGAACyyVyFtlsUQZfBJebinpkUAAAsfw+jAAA=| + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "body": "\r\n\r\n\r\n\r\n\r\n\r\n
\r\n

Some text inside email

\r\n
\r\n\r\n\r\n", + "itemId": "AAFSFSFFtlsUQZfBJebinpkUAAABjKMGAACyyVyFtlsUQZfBJebinpkUAAAsfw+jAAA=", + "toRecipients": [ + "test@demistodev.onmicrosoft.com" + ], + "datetimeCreated": "2019-08-11T10:57:37Z", + "datetimeReceived": "2019-08-11T10:57:37Z", + "author": "test2@demistodev.onmicrosoft.com", + "hasAttachments": true, + "size": 21435, + "subject": "Get Attachment Email", + "FileAttachments": [ + { + "attachmentName": "atta1.rtf", + "attachmentSHA256": "cd81097bcvdiojf3407a00308b48039e31a44a1c4fdnfkdknce36e4f", + "attachmentType": "FileAttachment", + "attachmentSize": 535, + "attachmentId": "AAFSFSFFtlsUQZfBJebinpkUAAABjKMGAACyyVyFtlsUQZfBJebinpkUAAAsfw+jAAABEgAQAEyq1TB2nKBLpKUiFUJ5Geg=", + "attachmentIsInline": false, + "attachmentLastModifiedTime": "2019-08-11T11:06:02+00:00", + "attachmentContentLocation": null, + "attachmentContentType": "text/rtf", + "originalItemId": "AAFSFSFFtlsUQZfBJebinpkUAAABjKMGAACyyVyFtlsUQZfBJebinpkUAAAsfw+jAAA=", + "attachmentContentId": null + } + ], + "headers": [ + { + "name": "Subject", + "value": "Get Attachment Email" + }, + ... + ], + "isRead": true, + "messageId": "", + "receivedBy": "test@demistodev.onmicrosoft.com", + "datetimeSent": "2019-08-11T10:57:36Z", + "lastModifiedTime": "2019-08-11T11:13:59Z", + "mailbox": "test@demistodev.onmicrosoft.com", + "importance": "Normal", + "textBody": "Some text inside email\r\n", + "sender": "test2@demistodev.onmicrosoft.com" + } + } +} + +``` + +### 14\. Get items + +* * * + +Retrieves items by item ID. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-get-items` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-ids|A CSV list of item IDs.|Required| +|target-mailbox|The mailbox on which to run the command on.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.itemId|string|The email item ID.| +|EWS.Items.hasAttachments|boolean|Whether the email has attachments.| +|EWS.Items.datetimeReceived|date|Received time of the email.| +|EWS.Items.datetimeSent|date|Sent time of the email.| +|EWS.Items.headers|Unknown|Email headers (list).| +|EWS.Items.sender|string|Sender mail address of the email.| +|EWS.Items.subject|string|Subject of the email.| +|EWS.Items.textBody|string|Body of the email (as text).| +|EWS.Items.size|number|Email size.| +|EWS.Items.toRecipients|Unknown|Email recipients addresses (list).| +|EWS.Items.receivedBy|Unknown|Received by address of the email.| +|EWS.Items.messageId|string|Email message ID.| +|EWS.Items.body|string|Body of the email (as HTML).| +|EWS.Items.FileAttachments.attachmentId|unknown|Attachment ID of the file attachment.| +|EWS.Items.ItemAttachments.attachmentId|unknown|Attachment ID of the item attachment.| +|EWS.Items.FileAttachments.attachmentName|unknown|Attachment name of the file attachment.| +|EWS.Items.ItemAttachments.attachmentName|unknown|Attachment name of the item attachment.| +|EWS.Items.isRead|String|The read status of the email.| +|Email.CC|String|Email addresses CC'ed to the email.| +|Email.BCC|String|Email addresses BCC'ed to the email.| +|Email.To|String|The recipient of the email.| +|Email.From|String|The sender of the email.| +|Email.Subject|String|The subject of the email.| +|Email.Text|String|The plain-text version of the email.| +|Email.HTML|String|The HTML version of the email.| +|Email.HeadersMap|String|The headers of the email.| + +##### Command Example + +``` +!ews-get-items item-ids=AAMkADQ0NmFkODFkLWQ4MDEtNDFDFZjNTMxNwBGAAAAAAA4kxhFFAfxw+jAAA= target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +Identical outputs to `ews-get-items-from-folder` command. + +### 15\. Move an item to a different mailbox + +* * * + +Moves an item from one mailbox to a different mailbox. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-move-item-between-mailboxes` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-id|The item ID to move.|Required| +|destination-folder-path|The folder in the destination mailbox to which to move the item. You can specify a complex path, for example, "Inbox\Phishing".|Required| +|destination-mailbox|The mailbox to which to move the item.|Required| +|source-mailbox|The mailbox from which to move the item (conventionally called the "target-mailbox", the target mailbox on which to run the command).|Optional| +|is-public|Whether the destination folder is a Public Folder. Default is "False".|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.movedToMailbox|string|The mailbox to which the item was moved.| +|EWS.Items.movedToFolder|string|The folder to which the item was moved.| +|EWS.Items.action|string|The action taken on the item. The value will be "moved".| + +##### Command Example + +``` +!ews-move-item-between-mailboxes item-id=AAMkAGY3OTQyMzMzLWYxNjktNDE0My05NFSFSyNzBkNABGAAAAAACYCKjWAjq/zTrN6vWSzK4OWAAK2ISFSA= destination-folder-path=Moving destination-mailbox=test@demistodev.onmicrosoft.com source-mailbox=test2@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +Item was moved successfully. + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "movedToMailbox": "test@demistodev.onmicrosoft.com", + "movedToFolder": "Moving" + } + } +} + +``` + +### 16\. Get a folder + +* * * + +Retrieves a single folder. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-get-folder` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|target-mailbox|The mailbox on which to apply the search.|Optional| +|folder-path|The path of the folder to retrieve. If empty, will retrieve the folder "AllItems".|Optional| +|is-public|Whether the folder is a Public Folder. Default is "False".|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Folders.id|string|Folder ID.| +|EWS.Folders.name|string|Folder name.| +|EWS.Folders.changeKey|string|Folder change key.| +|EWS.Folders.totalCount|number|Total number of emails in the folder.| +|EWS.Folders.childrenFolderCount|number|Number of sub-folders.| +|EWS.Folders.unreadCount|number|Number of unread emails in the folder.| + +##### Command Example + +``` +!ews-get-folder folder-path=demistoEmail target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|changeKey|childrenFolderCount|id|name|totalCount|unreadCount| +|--- |--- |--- |--- |--- |--- | +|***yFtCdJSH|0|AAMkADQ0NmFkODFkLWQ4MDEtNDE4Mi1hN2NlsjflsjfSF=|demistoEmail|1|0| + +##### Context Example + +``` +{ + "EWS": { + "Folders": { + "unreadCount": 0, + "name": "demistoEmail", + "childrenFolderCount": 0, + "totalCount": 1, + "changeKey": "***yFtCdJSH", + "id": "AAMkADQ0NmFkODFkLWQ4MDEtNDE4Mi1hN2NlsjflsjfSF=" + } + } +} + +``` + +### 17\. Expand a distribution list + +* * * + +Expands a distribution list to display all members. By default, expands only the first layer of the distribution list. If recursive-expansion is "True", the command expands nested distribution lists and returns all members. + +##### Required Permissions + +Impersonation rights required. In order to perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-expand-group` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|email-address|Email address of the group to expand.|Required| +|recursive-expansion|Whether to enable recursive expansion. Default is "False".|Optional| + +##### Context Output + +There is no context output for this command. + +##### Command Example + +``` +!ews-expand-group email-address="TestPublic" recursive-expansion="False" +``` + +##### Human Readable Output + +|displayName|mailbox|mailboxType| +|--- |--- |--- | +|John Wick|john@wick.com|Mailbox| + +##### Context Example + +``` +{ + "EWS.ExpandGroup": { + "name": "TestPublic", + "members": [ + { + "mailboxType": "Mailbox", + "displayName": "John Wick", + "mailbox": "john@wick.com" + } + ] + } +} + +``` + +### 18\. Mark items as read + +* * * + +Marks items as read or unread. + +##### Required Permissions + +Impersonation rights are required. To perform actions on the target mailbox of other users, the service account must be part of the ApplicationImpersonation role. + +##### Base Command + +`ews-mark-items-as-read` + +##### Input + +|**Argument Name**|**Description**|**Required**| +|--- |--- |--- | +|item-ids|A CSV list of item IDs.|Required| +|operation|How to mark the item. Can be "read" or "unread". Default is "read".|Optional| +|target-mailbox|The mailbox on which to run the command. If empty, the command will be applied on the default mailbox.|Optional| + +##### Context Output + +|**Path**|**Type**|**Description**| +|--- |--- |--- | +|EWS.Items.action|String|The action that was performed on the item.| +|EWS.Items.itemId|String|The ID of the item.| +|EWS.Items.messageId|String|The message ID of the item.| + +##### Command Example + +``` +!ews-mark-items-as-read item-ids=AAMkADQ0NFSffU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAABjKMnpkUAAAfxw+jAAA= operation=read target-mailbox=test@demistodev.onmicrosoft.com +``` + +##### Human Readable Output + +|action|itemId|messageId| +|--- |--- |--- | +|marked-as-read|AAMkADQ0NFSffU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAABjKMnpkUAAAfxw+jAAA=|| + +##### Context Example + +``` +{ + "EWS": { + "Items": { + "action": "marked-as-read", + "itemId": "AAMkADQ0NFSffU3wX3aBwCyyVyFtlsUQZfBJebinpkUAAABjKMnpkUAAAfxw+jAAA= ", + "messageId": "message_id" + } + } +} + +``` + +## Additional Information + +* * * + +#### EWS Permissions + +To perform actions on mailboxes of other users, and to execute searches on the Exchange server, you need specific permissions. For a comparison between Delegate and Impersonation permissions, see the [Microsoft documentation](https://blogs.msdn.microsoft.com/exchangedev/2009/06/15/exchange-impersonation-vs-delegate-access/). + +|Permission|Use Case|How to Configure| +|--- |--- |--- | +|Delegate|One-to-one relationship between users.|Read more [here](https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/delegate-access-and-ews-in-exchange).| +|Impersonation|A single account needs to access multiple mailboxes.|Read more [here](https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-configure-impersonation).| +|eDiscovery|Search the Exchange server.|Read more [here](https://docs.microsoft.com/en-us/Exchange/policy-and-compliance/ediscovery/assign-permissions?view=exchserver-2019).| +|Compliance Search|Perform searches across mailboxes and get an estimate of the results.|Read more [here](https://docs.microsoft.com/en-us/office365/securitycompliance/permissions-in-the-security-and-compliance-center).| diff --git a/Packs/EWS/Integrations/EWSO365/test_data/commands_outputs.json b/Packs/EWS/Integrations/EWSO365/test_data/commands_outputs.json new file mode 100644 index 000000000000..b7e7fa4daa96 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/test_data/commands_outputs.json @@ -0,0 +1,2441 @@ +{ + "ews-get-searchable-mailboxes": { + "EWS.Mailboxes": [ + { + "mailbox": "aaaaa@demistodev.onmicrosoft.com", + "mailboxId": "/o=ExchangeLabs/ou=Exchange Administrative Group", + "displayName": "aaaa", + "isExternal": "false", + "externalEmailAddress": null + } + ] + }, + "ews-find-folders": { + "EWS.Folders(val.id == obj.id)": [ + { + "name": "Favorites", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Top of Information Store", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 19, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Calendar", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 2, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Birthdays", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "United States holidays", + "totalCount": 175, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Contacts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 7, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "{A9E2BC46-B3A0-4243-B315-60D991004455}", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "{06967759-274D-40B2-A3EB-D7F9E73727D7}", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Recipient Cache", + "totalCount": 21, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Companies", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "GAL Contacts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Organizational Contacts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "PeopleCentricConversation Buddies", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Conversation History", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Team Chat", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Deleted Items", + "totalCount": 7, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Drafts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Inbox", + "totalCount": 6, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 5 + }, + { + "name": "Journal", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Junk Email", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Notes", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Outbox", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Sent Items", + "totalCount": 7, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Tasks", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Archive", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Conversation Action Settings", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ExternalContacts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Files", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PersonMetadata", + "totalCount": 21, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": null + }, + { + "name": "Test", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Test1", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Yammer Root", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 3, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Feeds", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Inbound", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Outbound", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "My Contacts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PeopleConnect", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Recoverable Items", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 5, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Deletions", + "totalCount": 12, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 1 + }, + { + "name": "Purges", + "totalCount": 7, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 1 + }, + { + "name": "Versions", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Audits", + "totalCount": 14, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Calendar Logging", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Finder", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 3, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Voice Mail", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "OwaFV15.1AllFocusedAQMkAGZiODc1MGY3LTBiODEtNDQAN2QtOWM3Yy1lZGI4YjIxZTE5NTAALgAAA3ge9qbo93dKqujtIHDxPSgBAOP1fdDThA5Nh/9sF3X5QNkAAAIBDAAAAA==", + "totalCount": 6, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 5 + }, + { + "name": "OwaFV15.1AllOtherAQMkAGZiODc1MGY3LTBiODEtNDQAN2QtOWM3Yy1lZGI4YjIxZTE5NTAALgAAA3ge9qbo93dKqujtIHDxPSgBAOP1fdDThA5Nh/9sF3X5QNkAAAIBDAAAAA==", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "To-Do Search", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "System", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "AllCategorizedItems", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "AllContacts", + "totalCount": 21, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "AllItems", + "totalCount": 237, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 5 + }, + { + "name": "AllPersonMetadata", + "totalCount": 21, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ApplicationDataRoot", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 23, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "00000002-0000-0ff1-ce00-000000000000", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 3, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "13937bba-652e-4c46-b222-3003f4d1ff97", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateContextData", + "totalCount": 11, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "1caee58f-eb14-4a6b-9339-1fe2ddf6692b", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 2, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Recent", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Settings", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "2a486b53-dbd2-49c0-a2bc-278bdfc30833", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PersonalGrammars", + "totalCount": 5, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "32d4b5e5-7d33-4e7f-b073-f8cffbbb47a1", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "outlookfavorites", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "35d54a08-36c9-4847-9018-93934c62740c", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PeoplePredictions.profile", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "394866fc-eedb-4f01-8536-3ff84b16be2a", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "InsightInstancesActions", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "3b2e5a14-128d-48aa-b581-482aac616d32", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "3c896ded-22c5-450f-91f6-3d1ef0848f6e", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 20, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ActivitiesDaily", + "totalCount": 61, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ActivitiesWeekly", + "totalCount": 9, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "AfterHoursEmailImpact", + "totalCount": 54, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "AutomaticRepliesHistory", + "totalCount": 20, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ChatsInterruptionStatistics", + "totalCount": 53, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ComputeLogs", + "totalCount": 22, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "CumulativeNetworkSnapshot", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "CumulativeOutOfOfficeClustering", + "totalCount": 108, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "DailyAppointments", + "totalCount": 86, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "DailyInteractions", + "totalCount": 54, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "DailyNetworkSnapshot", + "totalCount": 54, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "DetailedMeetings", + "totalCount": 54, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "EmailActionStatistics", + "totalCount": 54, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "HeterogeneousItems", + "totalCount": 11, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ImportantContact", + "totalCount": 5, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ManagementOperationExecutionRecords", + "totalCount": 4, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "MeetingActionStatistics", + "totalCount": 9, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "OutOfOffice", + "totalCount": 47, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "WeeklyInteractions", + "totalCount": 7, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "WeeklyOutOfOfficeAndWorkingDay", + "totalCount": 7, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "441509e5-a165-4363-8ee7-bcf0b7d26739", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 9, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GenericWorkflowProcessor.SessionManager.Data", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Idf", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "IdfMeeting", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SimpleAcronymsIndex", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "UserDocKpeStats", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "UserDocWithKpes", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "UserKpes", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "UserKpeState", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "UserStatistics", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "48af08dc-f6d2-435f-b2a7-069abd99c086", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "InsightsProvidersSettings", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "49499048-0129-47f5-b95e-f9d315b861a6", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "OutlookAccountCloudSettings", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "4e445925-163e-42ca-b801-9073bfa46d17", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "NewsSubscriptionSourcesv2", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "644c1b11-f63f-45fa-826b-a9d2801db711", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 3, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "_PolicyContainer", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "dGVzdGJveEBkZW1pc3RvZGV2Lm9ubWljcm9zb2Z0LmNvbQ==_LabelFile", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "dGVzdGJveEBkZW1pc3RvZGV2Lm9ubWljcm9zb2Z0LmNvbQ==_PolicyContainer", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "66a88757-258c-4c72-893c-3e8bed4d6899", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 15, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.CalendarEvents", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.EmailEntities", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.EmailTokens", + "totalCount": 22, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.FreshHistory", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.GroupsRoomsMiscIndex", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.People", + "totalCount": 6, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.PeopleIndex", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.SearchHistory.Main", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.SearchHistoryBootstrapStateV2", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.SearchHistoryState", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.SharePointDocuments", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.SsaSessionManager", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.TeamsAndChannels", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.TeamsChats", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateSearch.TeamsEntities", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "766ef332-38e5-4cb4-920c-baa478e39fd9", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "CrawlerExecutionInfoCollection", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "7ae974c5-1af7-4923-af3a-fb1fd14dcb7e", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 5, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GetStartedStore", + "totalCount": 15, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "lightning", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "LightningSharedStore", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "LightningStore", + "totalCount": 44, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "WhatsNewStore", + "totalCount": 34, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "80723a00-368e-4d64-8281-210e49e593a8", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ActivityFeed_201905", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "8c22b648-ee54-4ece-a4ca-3015b6d24f8e", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 2, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Images", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Profiles", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ae8e128e-080f-4086-b0e3-4c19301ada69", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Scheduling", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "b669c6ea-1adf-453f-b8bc-6d526592b419", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "FocusedInboxMailboxData", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "d71dfe16-1070-48f3-bd3a-c3ec919d34e7", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 2, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "TxpAutoblocking", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "TxpUserSettings", + "totalCount": 10, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "e69932cd-f814-4087-8ab1-5ab3f1ad18eb", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 3, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PhishingBootstrap", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "BrokerSubscriptions", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "BulkActions", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "CalendarItemSnapshots", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "CalendarSharingCacheCollection", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Common Views", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ComplianceMetadata", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Connectors", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ConnectorConfigurations", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "CrawlerData", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "DefaultFoldersChangeHistory", + "totalCount": 389, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Deferred Action", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Document Centric Conversations", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ExchangeODataSyncData", + "totalCount": 36, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ExchangeSyncData", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "FileCollectionCache", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Folder Memberships", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Freebusy Data", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "FreeBusyLocalCache", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "FreeBusyLocalCacheSubscriptions", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphFilesAndWorkingSetSearchFolder", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphStore", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 6, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphEdges", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphNodes", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphNonSecureDrafts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphNonSecureTransactions", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphRelations", + "totalCount": 4, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Inference", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Location", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "MailboxAssociations", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "MeetingSapces", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "MergedViewFolderCollection", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "MessageIngestion", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Yammer", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "O365 Suite Notifications", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "O365 Suite Storage", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "OneDriveRoot", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Orion Notes", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PACE", + "totalCount": 2, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "DelveNotifications", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ParkedMessages", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Pass-Through Search Results", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PdpProfile", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PdpProfileV2", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "People I Know", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PeopleInsights", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "PeoplePublicData", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "QuarantinedEmail", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 1, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "QuarantinedEmailDefaultCategory", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 4, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "QedcDefaultRetention", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "QedcLongRetention", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "QedcMediumRetention", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "QedcShortRetention", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "RelevantContacts", + "totalCount": 21, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Reminders", + "totalCount": 12, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Schedule", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ShardRelevancyFolder", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SharedFilesSearchFolder", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SharePointNotifications", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Sharing", + "totalCount": 1, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Shortcuts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SkypeSpacesData", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 2, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SkypeMessages", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "TeamsMeetings", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SmsAndChatsSync", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Spooler Queue", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SpoolsSearchFolder", + "totalCount": 9, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SubstrateFiles", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 3, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "ClassicAttachments", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "GraphWorkingSet", + "totalCount": 3, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SPOOLS", + "totalCount": 9, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SuggestedUserGroupAssociations", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "SwssItems", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 3, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "TeamChatHistory", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "TeamsMessagesData", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "TemporarySaves", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "UserCuratedContacts", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "UserSocialActivityNotifications", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "Views", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmActivityClientInstrumentation", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmActivityServerInstrumentation", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmActivityStream", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmActivityStreamSearch", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmCompanySearch", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmDealSearch", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmDeletedItems", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmInsights", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmProjects", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "XrmSearch", + "totalCount": 21, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + }, + { + "name": "YammerData", + "totalCount": 0, + "id": "id", + "childrenFolderCount": 0, + "changeKey": "changekey", + "unreadCount": 0 + } + ] + }, + "ews-search-mailbox": { + "EWS.Items(val.itemId === obj.itemId || (val.messageId && obj.messageId && val.messageId === obj.messageId))": [ + { + "itemId": "itemId", + "datetimeCreated": "2020-05-21T12:36:24Z", + "datetimeReceived": "2020-05-21T12:36:25Z", + "datetimeSent": "2020-05-21T12:35:18Z", + "sender": "darbel@paloaltonetworks.com", + "hasAttachments": false, + "importance": "Normal", + "messageId": "messageId", + "lastModifiedTime": "2020-05-24T10:30:33Z", + "size": 57321, + "subject": "test with attachment", + "textBody": "\r\nDean Arbel\r\nStaff Software Engineer, Content Team, Demisto\r\nEmail: darbel@paloaltonetworks.com\r\nPhone: +972.54.7209916\r\n[https://go.demisto.com/hubfs/Demisto-Full%20Color-Logo.png]\r\n", + "headers": [ + { + "name": "Received", + "value": "from VI1PR07MB5728.eurprd07.prod.outlook.com (2603:10a6:20b:f0::25) by AM5PR0701MB2388.eurprd07.prod.outlook.com with HTTPS via AM6PR04CA0048.EURPRD04.PROD.OUTLOOK.COM; Thu, 21 May 2020 12:36:24 +0000" + }, + { + "name": "Received", + "value": "from AM6PR02CA0035.eurprd02.prod.outlook.com (2603:10a6:20b:6e::48) by VI1PR07MB5728.eurprd07.prod.outlook.com (2603:10a6:803:d4::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.13; Thu, 21 May 2020 12:36:23 +0000" + }, + { + "name": "Received", + "value": "from VE1EUR01FT047.eop-EUR01.prod.protection.outlook.com (2603:10a6:20b:6e:cafe::20) by AM6PR02CA0035.outlook.office365.com (2603:10a6:20b:6e::48) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.26 via Frontend Transport; Thu, 21 May 2020 12:36:22 +0000" + }, + { + "name": "Received", + "value": "from mx0b-00169c01.pphosted.com (67.231.156.123) by VE1EUR01FT047.mail.protection.outlook.com (10.152.3.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23 via Frontend Transport; Thu, 21 May 2020 12:36:21 +0000" + }, + { + "name": "Received", + "value": "from pps.filterd (m0048188.ppops.net [127.0.0.1])\tby mx0b-00169c01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 04LCYwj1030495\tfor ; Thu, 21 May 2020 05:36:20 -0700" + }, + { + "name": "Received", + "value": "from mail-oo1-f69.google.com (mail-oo1-f69.google.com [209.85.161.69])\tby mx0b-00169c01.pphosted.com with ESMTP id 312j0ajtmj-1\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT)\tfor ; Thu, 21 May 2020 05:36:20 -0700" + }, + { + "name": "Received", + "value": "by mail-oo1-f69.google.com with SMTP id l21so3325823oos.22 for ; Thu, 21 May 2020 05:36:20 -0700 (PDT)" + }, + { + "name": "Authentication-Results", + "value": "spf=pass (sender IP is 67.231.156.123) smtp.mailfrom=paloaltonetworks.com; demistodev.onmicrosoft.com; dkim=pass (signature was verified) header.d=paloaltonetworks.com;demistodev.onmicrosoft.com; dmarc=pass action=none header.from=paloaltonetworks.com;compauth=pass reason=100" + }, + { + "name": "Received-SPF", + "value": "Pass (protection.outlook.com: domain of paloaltonetworks.com designates 67.231.156.123 as permitted sender) receiver=protection.outlook.com; client-ip=67.231.156.123; helo=mx0b-00169c01.pphosted.com;" + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks.com; h=mime-version : from : date : message-id : subject : to : content-type; s=PPS12012017; bh=3V1MY5tIy0u3WVuB2TCXSM7iWtDLNm025KA+8pHonYQ=; b=YGiaV+dbdkA2+ttEOBtgdPSwPLUmr/EQRS+oBQ+Z7eEA56HF7aEQ48DYSpJhNKa5nTMW FiJ0bEWi9XmA2+dKy0A0ZtyJrodqpY1W8xnWRVKaO4MIsvVTyUTJSfJKDBVw6clv652/ Q9NagmlnQf6lfSF/0h/rc0BvFQoWlQ23ApabaSz2agtfWLFsvf36l14UqNCHfrwoQHcY YIDEofGu37O29lDwnDky+VJTg0jKN5BguRctMd4cFPe0xbo3M0RMijzsqCrKKTtRVF7O IcP3llqEigi5wEtawxMb4NQlZbvL6VP1G5aSdYDallFtZm5qj7aFyNpjOKyNffN6oVxX qg== " + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=3V1MY5tIy0u3WVuB2TCXSM7iWtDLNm025KA+8pHonYQ=; b=2Dtn+BoifCZ57s/MHyQJwITiYpW2HRGC8rx9kFP+/8I9Sa55DrjlSrupAqKFkmgi2e hUq56LW6PXK20T02gOFjkf6ja+f9x8/F3VoBG4ADX7rLAgbWc7YXbLjOfUohau+1UITd aMWswug+4rY7L8QTdpeQiEj8nfCB5t+/RNCoLCMV4zwvjeKQ8Nkg6sWuU/LSb+t4W5l+ 67Fq4osfFUQPwbXPBeAKhpmi4NYldZKc54MTOKi1sHyaXzADB475VZ0b9d7D++8ulxXb E3qTeWi7KYySygm45+sMZ/4AYNlgjiT6Gmx4SkQGTmvN/VqjlXLpWLs0Q3xDxNW+Ggsh M47Q==" + }, + { + "name": "X-Google-DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=3V1MY5tIy0u3WVuB2TCXSM7iWtDLNm025KA+8pHonYQ=; b=B+AzxBw/moiaMpD/h5HMIwigEukmQdzOVjIEAuFpRW1V1FdKQinxprXMalv39PQlDD WUJlmAQYCvvifA5VaUkkAuYUETq++2yVLaVSd6YW0jKwcm+yvQp10MpatmEVBBPwuRfr 8YF3L9Qhzd8bSlcg0v6UTLTs/j18jHFceBI7UNasFpsag5yVAdAiF4HTYLAO4FV8syif Ee/EaO8/qRyzzxdnqT4WyksZF1dFcgBj3Ii8E3QnbpEkElsrcOo8yFhtgiKWesQxilyK bt5y+BdwYB9dAKzAw3yxxuBYQBuJ0VPVW585moHfUJ5YvjLHsIGkag2PmRPyKpmSPUJk A6+A==" + }, + { + "name": "X-Gm-Message-State", + "value": "AOAM533KzEt3TBZth3vp/FoX67aS/igSrt7HFh+PVgZkcp1b8+Ro1jD0\tURWuKgm2VcXOnOHyWyiWgpl3L3JwGXAqFtrnEG7z6nReZEzWeyjNLm0zEXFArNjNdu5cf01PGec\tS7r8Rn5VIPtO+4Cejj6uuuZ06XpMLXmWhT8xRG54CGvL6vSZ/" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr6740225oie.142.1590064579748; Thu, 21 May 2020 05:36:19 -0700 (PDT)" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr6740179oie.142.1590064578767; Thu, 21 May 2020 05:36:18 -0700 (PDT)" + }, + { + "name": "X-Google-Smtp-Source", + "value": "ABdhPJycyvGbCUwXro6NGtBzPoJPyFIRPmnnjz60CS0xnuEXr6ubn//2nkXr6vikUMIWmI5gZY7fW0EQD1/Wo//8eeQ=" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Thu, 21 May 2020 15:35:18 +0300" + }, + { + "name": "Message-ID", + "value": "" + }, + { + "name": "Subject", + "value": "test with attachment" + }, + { + "name": "Content-Type", + "value": "multipart/mixed" + }, + { + "name": "X-Proofpoint-Virus-Version", + "value": "vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-21_06:2020-05-21,2020-05-21 signatures=0" + }, + { + "name": "X-Proofpoint-Spam-Details", + "value": "rule=outbound_spam_notspam policy=outbound_spam score=0 malwarescore=0 priorityscore=1501 bulkscore=0 cotscore=-2147483648 phishscore=0 spamscore=0 clxscore=1011 adultscore=0 mlxlogscore=438 mlxscore=0 suspectscore=0 lowpriorityscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2005210093" + }, + { + "name": "Return-Path", + "value": "darbel@paloaltonetworks.com" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTime", + "value": "21 May 2020 12:36:22.4651 (UTC)" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTimeReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationInterval", + "value": "1:00:00:00.0000000" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationIntervalReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-Network-Message-Id", + "value": "33e1ab54-578d-45ad-6123-08d7fd8391c9" + }, + { + "name": "X-EOPAttributedMessage", + "value": "0" + }, + { + "name": "X-EOPTenantAttributedMessage", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999:0" + }, + { + "name": "X-MS-Exchange-Organization-MessageDirectionality", + "value": "Incoming" + }, + { + "name": "X-Forefront-Antispam-Report", + "value": "CIP:67.231.156.123;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mx0b-00169c01.pphosted.com;PTR:mx0b-00169c01.pphosted.com;CAT:NONE;SFTY:;SFS:(4636009)(564344004)(86362001)(7636003)(42186006)(22186003)(33964004)(356005)(26005)(336012)(7596003)(3480700007)(7116003)(9686003)(8676002)(2160300002)(5660300002)(1096003)(6916009)(55446002)(58800400005)(133083001);DIR:INB;SFP:;" + }, + { + "name": "X-MS-PublicTrafficType", + "value": "Email" + }, + { + "name": "X-MS-Exchange-Organization-AuthSource", + "value": "VE1EUR01FT047.eop-EUR01.prod.protection.outlook.com" + }, + { + "name": "X-MS-Exchange-Organization-AuthAs", + "value": "Anonymous" + }, + { + "name": "X-MS-Office365-Filtering-Correlation-Id", + "value": "33e1ab54-578d-45ad-6123-08d7fd8391c9" + }, + { + "name": "X-MS-TrafficTypeDiagnostic", + "value": "VI1PR07MB5728:" + }, + { + "name": "X-MS-Exchange-AtpMessageProperties", + "value": "SA" + }, + { + "name": "X-MS-Oob-TLC-OOBClassifiers", + "value": "OLM:1728;" + }, + { + "name": "X-MS-Exchange-Organization-SCL", + "value": "1" + }, + { + "name": "X-Microsoft-Antispam", + "value": "BCL:0;" + }, + { + "name": "X-MS-Exchange-CrossTenant-OriginalArrivalTime", + "value": "21 May 2020 12:36:21.9939 (UTC)" + }, + { + "name": "X-MS-Exchange-CrossTenant-Network-Message-Id", + "value": "33e1ab54-578d-45ad-6123-08d7fd8391c9" + }, + { + "name": "X-MS-Exchange-CrossTenant-Id", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999" + }, + { + "name": "X-MS-Exchange-CrossTenant-FromEntityHeader", + "value": "Internet" + }, + { + "name": "X-MS-Exchange-Transport-CrossTenantHeadersStamped", + "value": "VI1PR07MB5728" + }, + { + "name": "X-MS-Exchange-Transport-EndToEndLatency", + "value": "00:00:02.6143909" + }, + { + "name": "X-MS-Exchange-Processed-By-BccFoldering", + "value": "15.20.3021.019" + }, + { + "name": "X-Microsoft-Antispam-Mailbox-Delivery", + "value": "ucf:0;jmr:0;auth:0;dest:I;ENG:(20160514016)(750128)(520011016)(944506383)(944626604);" + }, + { + "name": "X-Microsoft-Antispam-Message-Info", + "value": "GYMxyfjbkGHsUpWSD/+/zAqqyIHrTe+HHUexgZpYTm2UkhmvRqDi9kkwrPOItdlPtZe+zWuoZ9Dvl5I0jxgdawDRZH0/67UGmNlGddyF/PIYT6LdJsV3CBqK7h4PMRref2rqtG6LO401erigCiu8DdIxE6ikgqOkTJ9TB7/qiyNh5RcBLQqW9WKQ0wJb0HhebecR1qOIYMqSkJO11n8jv+/yAtFGpj17XsDuotY/vZVMFZWiUaQVPkqReO2Dwz6XWNsQtI5F5omzCdxpf60/MHVVDA/A1qcZI+a1Xj+ipeFYUalyzXkK5rUKXaAZtlcfY7muB2a0R+m+M0IDfEW99Fj0r0xC9ncQ5QZxoMxWBEjMhkNRXPt1YikazW7TKA43FGxow2K0PGSzZjeffQ+RgAcsnIp4+BEJBdpQK1zE4MHmlhgZ/WJPFi43qUZX0vL51H2dae8hlPHKcjogRTlecqsqhjSYujN46pKgbZ849S5negxD+yoFN1HAn9hjcban05Wz0n8SdK9eevySMrbobjBWvSKb+ZMNYLVD8UwAatsYm+5+tzgZEdxO6OOatf9Mx8/g5+/Q8F6Z859doJDTJ2oZptzvQjbVfhPw0+Hv777s6kzbUydnBxaDxQh+X95RCFcDXHurOhS+sch65hmJqkjR5IsoEmiukpsZNeHfBwmZq7KpqUE74nbTcSwfxLZvP1Wzd+1Hc0Qrq0IPQQsgdgUlgdeEZPZ7SciSXE2em++/9BnU36rFKOimEp/DQokD/1e0qsZG5FkFIifpgc9ghpROWkUMHj5sAuhq6lbs8RADc7ErAjKIppfJBMJzYu+RiTvyvxfLm0bxVQsl9ONXgfMqvJk2+Nliu8tkotPgz9SMEztVkS4kinhDrnjhF0LPZoBeJEPHVM/k1g7A4i1kEEevvJJdnmaLQ8JKNTKMFqPryQc2Tch8jDzUCEkxCrIiHVqLzHfUfGfeGx1sVLLoVjTUq2jY100+s9DCkEOsFemtxYduN32OR5rPBl2ruwqyhBnpPrEbCwSZySoZ+CK+PKdnTr6U1OQEAVvIdI/QjnqvYaoExUC2cu8whC+q/VlKk46P0DxPQHEmrlbvU2BTAlNfMBeReIJ1qKZ+Mw9rpeHbxOYi9F+zJ08COmcWqfaIeCBQxA3bnARzYBwFLbQCWBPiTTunLlZhHDl8BAaFb4qhaShjtAKaFILg1V/jJNi5uPOpazmhHCTgrQGN6BX8nQ==" + } + ], + "body": "\r\n
", + "isRead": true, + "receivedBy": "testbox@demistodev.onmicrosoft.com", + "author": "darbel@paloaltonetworks.com", + "toRecipients": [ + "testbox@demistodev.onmicrosoft.com" + ], + "mailbox": "testbox@demistodev.onmicrosoft.com" + } + ] + }, + "ews-get-contacts": { + "Account.Email(val.Address == obj.originMailbox).EwsContacts": [ + { + "itemClass": "IPM.Contact", + "subject": "Avishai Brandeis", + "sensitivity": "Normal", + "textBody": "\r\n\r\n", + "body": "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
 
\r\n
 
\r\n
\r\n\r\n\r\n", + "datetimeReceived": "2019-10-19T14:38:51Z", + "importance": "Normal", + "datetimeSent": "2019-10-19T14:38:51Z", + "datetimeCreated": "2019-10-19T14:38:53Z", + "culture": "en-US", + "lastModifiedName": "Avishai Brandeis", + "lastModifiedTime": "2019-10-19T14:42:54Z", + "webClientReadFormQueryString": "webClientReadFormQueryString", + "uniqueBody": "", + "fileAs": "Brandeis, Avishai", + "fileAsMapping": "LastCommaFirst", + "displayName": "Avishai Brandeis", + "givenName": "Avishai", + "initials": "A.B.", + "jobTitle": "test", + "postalAddressIndex": "None", + "surname": "Brandeis", + "emailAddresses": [ + "avishai@demistodev.onmicrosoft.com" + ], + "originMailbox": null + } + ] + }, + "ews-get-items-from-folder": { + "EWS.Items(val.itemId === obj.itemId || (val.messageId && obj.messageId && val.messageId === obj.messageId))": [ + { + "itemId": "itemId", + "datetimeCreated": "2020-05-24T12:05:22Z", + "datetimeReceived": "2020-05-24T12:05:23Z", + "datetimeSent": "2020-05-24T12:04:16Z", + "sender": "darbel@paloaltonetworks.com", + "hasAttachments": true, + "importance": "Normal", + "messageId": "messageId", + "lastModifiedTime": "2020-05-24T12:05:23Z", + "size": 96501, + "subject": "second fetch", + "textBody": "\r\nDean Arbel\r\nStaff Software Engineer, Content Team, Demisto\r\nEmail: darbel@paloaltonetworks.com\r\nPhone: +972.54.7209916\r\n[https://go.demisto.com/hubfs/Demisto-Full%20Color-Logo.png]\r\n", + "headers": [ + { + "name": "Received", + "value": "from AM6PR07MB5256.eurprd07.prod.outlook.com (2603:10a6:20b:2e::32) by AM5PR0701MB2388.eurprd07.prod.outlook.com with HTTPS via AM6PR05CA0019.EURPRD05.PROD.OUTLOOK.COM; Sun, 24 May 2020 12:05:22 +0000" + }, + { + "name": "Received", + "value": "from DB7PR03CA0105.eurprd03.prod.outlook.com (2603:10a6:10:72::46) by AM6PR07MB5256.eurprd07.prod.outlook.com (2603:10a6:20b:6c::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.8; Sun, 24 May 2020 12:05:21 +0000" + }, + { + "name": "Received", + "value": "from DB5EUR01FT016.eop-EUR01.prod.protection.outlook.com (2603:10a6:10:72:cafe::cb) by DB7PR03CA0105.outlook.office365.com (2603:10a6:10:72::46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.26 via Frontend Transport; Sun, 24 May 2020 12:05:21 +0000" + }, + { + "name": "Received", + "value": "from mx0b-00169c01.pphosted.com (67.231.156.123) by DB5EUR01FT016.mail.protection.outlook.com (10.152.4.255) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23 via Frontend Transport; Sun, 24 May 2020 12:05:20 +0000" + }, + { + "name": "Received", + "value": "from pps.filterd (m0048188.ppops.net [127.0.0.1])\tby mx0b-00169c01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 04OC5DAh017336\tfor ; Sun, 24 May 2020 05:05:20 -0700" + }, + { + "name": "Received", + "value": "from mail-oo1-f69.google.com (mail-oo1-f69.google.com [209.85.161.69])\tby mx0b-00169c01.pphosted.com with ESMTP id 316ygbt5we-1\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT)\tfor ; Sun, 24 May 2020 05:05:19 -0700" + }, + { + "name": "Received", + "value": "by mail-oo1-f69.google.com with SMTP id z190so8178136ooa.19 for ; Sun, 24 May 2020 05:05:19 -0700 (PDT)" + }, + { + "name": "Authentication-Results", + "value": "spf=pass (sender IP is 67.231.156.123) smtp.mailfrom=paloaltonetworks.com; demistodev.onmicrosoft.com; dkim=pass (signature was verified) header.d=paloaltonetworks.com;demistodev.onmicrosoft.com; dmarc=pass action=none header.from=paloaltonetworks.com;compauth=pass reason=100" + }, + { + "name": "Received-SPF", + "value": "Pass (protection.outlook.com: domain of paloaltonetworks.com designates 67.231.156.123 as permitted sender) receiver=protection.outlook.com; client-ip=67.231.156.123; helo=mx0b-00169c01.pphosted.com;" + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks.com; h=mime-version : from : date : message-id : subject : to : content-type; s=PPS12012017; bh=oKMkuNMg4AOkAcDm/TJAqh+DBFvZo76l5u80led3OuQ=; b=nX2L66T91eUzH+H2NOmbtH7OvFR8SPAkHv3HkC9nIgHkHBhP+0y75T9tnswbcngJ1YH4 1t1GpME1af9yXTZvlHZ33aP446gH2cai/OSYh0AyMmSJ/gcMKnfvvYB55IOofGm29UVB UQax0+RRUdAsplVfjOKp90w9ZOMC3iMfs7DNLzc3mYuwfzmDgqaoxdW9LYsva+D47Jh6 PUIvNaQtJ5gnBTRM3dS/HOj8/8qOtk1BFiQrlfSdrUlyf/YW1zA7Rgjr9camjFpRO/ug +ohq7uxL1XBbuQGGHHATOIcT1/Utb130VABe5NMOhaSaaMv6SUw4D9CMzThKJMmPwKT3 Og== " + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=oKMkuNMg4AOkAcDm/TJAqh+DBFvZo76l5u80led3OuQ=; b=zhHz86wU6AlPStMpUoctv8sqwn6RPVSqTXUR4l2o47CTg3JTG8Zzg8zPx+SEJ7TCQo 2P4XzUOgy8FwjlMmKub6YRb0MRKSV//MArs1rRpuprvEk7cPVddvVhNlq39Z2G9g0bkC I8V0yHNkK0g1PnCi16K+zkEvIniGu9Z4XTc+Gtrqte33NyrcIcQHaSDIt+rx6FA3wjqq DCuLh+QLLLLZQ0blCMIrUQndZKtqgy8TKvxAAE6lA+o4MrqKQCSNWLR8It8lfD1/kACi 56u8993bfz+ygncyZKoJnvOnN1xYMwtjReMrTGPE7DQaV9dT/8OnZMalAoPpgZJsV2c4 pnYA==" + }, + { + "name": "X-Google-DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=oKMkuNMg4AOkAcDm/TJAqh+DBFvZo76l5u80led3OuQ=; b=mqyRLna0nlMpWHgCGcSnUQQJwYwLGfVLcsefOEwHpNFCALI2axWh/g2R/bNNSnCbht YKPRSfwjnnMV7R29v+URpaFsfUIYGtvktYyA/Gpgk6UBpoqOvOTgziFxPDptPjXFUXqH 3tF5zK6Httt2C4hv3uJ7szNY2bnu21966L4Oq0OAJDJpJWt116ebwVyrtH8L95a0a+WK ymjTh7VFrWgSxvtuFGBIkpdEgbcz4Nwf6LmZ3d9QkDM4V3BE1LLdQyMr54BqesB2ZwW5 TQZ3Sy1PjbA3oAc7ClajCyuHk9vJ2TonYimF2EBsopDxrrB2x4ZC45bnllRswFsvPXJm u/AA==" + }, + { + "name": "X-Gm-Message-State", + "value": "AOAM530mhUfg9mbd/vLieicJ0PorcrLLS01V62u9nuJ96XD4gPIwHiF2\tE65GOXDh+NjlrqQTRpFCeU1EwMrkJPlRkRa+Zdb6YDwfg7T9ZRmi48TeVHS45ws3UeofplUK/H+\t/BwKWU0i7NmgwdJty+kdaAdKXVfABBAKyQ0a0FKYDv7Yeqjnt" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr8634827oie.142.1590321918013; Sun, 24 May 2020 05:05:18 -0700 (PDT)" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr8634794oie.142.1590321917402; Sun, 24 May 2020 05:05:17 -0700 (PDT)" + }, + { + "name": "X-Google-Smtp-Source", + "value": "ABdhPJyd3hDsiXnVW3uD+Am05+DCdgZ5nYUWSas3oQpGK7s6UXHxeEiBT58TFD7hfNvVejB0M8kUPg29m+om6RSsjAA=" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Sun, 24 May 2020 15:04:16 +0300" + }, + { + "name": "Message-ID", + "value": "" + }, + { + "name": "Subject", + "value": "second fetch" + }, + { + "name": "Content-Type", + "value": "multipart/mixed" + }, + { + "name": "X-Proofpoint-Virus-Version", + "value": "vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-24_02:2020-05-22,2020-05-24 signatures=0" + }, + { + "name": "X-Proofpoint-Spam-Details", + "value": "rule=outbound_spam_notspam policy=outbound_spam score=0 malwarescore=0 bulkscore=0 priorityscore=1501 spamscore=0 mlxscore=0 suspectscore=0 mlxlogscore=479 lowpriorityscore=0 adultscore=0 phishscore=0 impostorscore=0 cotscore=-2147483648 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2005240103" + }, + { + "name": "Return-Path", + "value": "darbel@paloaltonetworks.com" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTime", + "value": "24 May 2020 12:05:21.3150 (UTC)" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTimeReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationInterval", + "value": "1:00:00:00.0000000" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationIntervalReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-Network-Message-Id", + "value": "04736eb5-a8f0-4eca-aa89-08d7ffdabbb1" + }, + { + "name": "X-EOPAttributedMessage", + "value": "0" + }, + { + "name": "X-EOPTenantAttributedMessage", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999:0" + }, + { + "name": "X-MS-Exchange-Organization-MessageDirectionality", + "value": "Incoming" + }, + { + "name": "X-Forefront-Antispam-Report", + "value": "CIP:67.231.156.123;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mx0b-00169c01.pphosted.com;PTR:mx0b-00169c01.pphosted.com;CAT:NONE;SFTY:;SFS:(4636009)(336012)(564344004)(55446002)(356005)(5660300002)(8676002)(2160300002)(3480700007)(1096003)(42186006)(7596003)(26005)(33964004)(6666004)(86362001)(7636003)(9686003)(6916009)(7116003);DIR:INB;SFP:;" + }, + { + "name": "X-MS-PublicTrafficType", + "value": "Email" + }, + { + "name": "X-MS-Exchange-Organization-AuthSource", + "value": "DB5EUR01FT016.eop-EUR01.prod.protection.outlook.com" + }, + { + "name": "X-MS-Exchange-Organization-AuthAs", + "value": "Anonymous" + }, + { + "name": "X-MS-Office365-Filtering-Correlation-Id", + "value": "04736eb5-a8f0-4eca-aa89-08d7ffdabbb1" + }, + { + "name": "X-MS-TrafficTypeDiagnostic", + "value": "AM6PR07MB5256:" + }, + { + "name": "X-MS-Exchange-AtpMessageProperties", + "value": "SA" + }, + { + "name": "X-MS-Oob-TLC-OOBClassifiers", + "value": "OLM:1728;" + }, + { + "name": "X-MS-Exchange-Organization-SCL", + "value": "1" + }, + { + "name": "X-Microsoft-Antispam", + "value": "BCL:0;" + }, + { + "name": "X-MS-Exchange-CrossTenant-OriginalArrivalTime", + "value": "24 May 2020 12:05:20.9502 (UTC)" + }, + { + "name": "X-MS-Exchange-CrossTenant-Network-Message-Id", + "value": "04736eb5-a8f0-4eca-aa89-08d7ffdabbb1" + }, + { + "name": "X-MS-Exchange-CrossTenant-Id", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999" + }, + { + "name": "X-MS-Exchange-CrossTenant-FromEntityHeader", + "value": "Internet" + }, + { + "name": "X-MS-Exchange-Transport-CrossTenantHeadersStamped", + "value": "AM6PR07MB5256" + }, + { + "name": "X-MS-Exchange-Transport-EndToEndLatency", + "value": "00:00:01.7736787" + }, + { + "name": "X-MS-Exchange-Processed-By-BccFoldering", + "value": "15.20.3045.009" + }, + { + "name": "X-Microsoft-Antispam-Mailbox-Delivery", + "value": "ucf:0;jmr:0;auth:0;dest:I;ENG:(20160514016)(750128)(520011016)(944506383)(944626604);" + }, + { + "name": "X-Microsoft-Antispam-Message-Info", + "value": "8W3SISohCZB2jQsUVcqhQbQIXqqgocGxEoacfDww85zYoebJ4CFEHyfPsjUv+LWjYSozYrGJD2/XqethtTTJJW6GWACydYyIZsou4z883d0qB1DF7GfQQfgrAupBUcIj89jZALyqlQso/er4YUyuYWcW+5pUomBty6xvEErGMJYS7fxrR/7/Yt5pUoh8ZA77zrvssAXTcVkTw3kQwzzVYyvNwbAf0v4gKAoDzFaxij+5Agi89r8g9TTgz/V2b5uozJjCaJGdF8OOTEuZynKMlIv1PvIMBbZk+ODD3N+BfGPgIrRGtzDh8+mq95cFJL88feiiZk6WzkEDdmKa2UdxnZ/WWHIqUtqpukSXt7V7jxpl49ZxSU0gKeZ7O9SKBRsMtLtsCyg2lSr49/pZhIh08i0cQ05etP6iRnfI3LZyOMLKrb/MklGtS0YpnYO6fLUpUDcXZOaHkdnN5G981RHyh0SX5fZlApq90HPhgSWtNVC2Oa3P4v033t8YWR0w7SiQu4F1rYG6f0b7P7AlKLfBnNNhN7LFFEbJ6Dx/3TXZSm6Ayxmh2McwOGGTnBOBnJ5uBSXFtn7SZ83I13G1IK7YvSH0E4OpvNsZR/IlBmypFSZu9d/6/fO4IIDbn0xtGeFz0mw0gRQEKkoqYWjFNQAUQUKUoDJRV4zbBKaQrzoCHlEzcWaLURomBTq4DToNt6CC6mEqEy2//FDOAqmUgmkscmJyUYRWGvuH/rWL40IYzwULxK+sUxj7wyv2zYMFiRE0rygZn417GM9tNG1IKdxV+70QMLaNu/d2POwIEdth+yUMnnP9PCDoaQlwhIYSUlaVJM7LBHXatKf5wpu/SQQdkq5GAf6bXjowjBdrxSZqAxuI1hoCjhx4FipRCfseqyhKqBcBSKTH4fh3+xGbarFdcWnklgvya4m6ydpbg5yyXQclOOcB1hjuLL5P9/UM1jI/4EPYRHPfzC2hhO+Ncn3mznUJSuJksNz9Yw13wHynU509CyTRBbLNRxwnCzrrpYjTROeOWgP1SfhaoX5q+JPDbXeuPK+oYyXzVZeLuOuBt15euPvxeNR0Sqnhc+sQy8BRhBZcTfcKbS4RZ/tFTrmsknkaGp3wXycjVdYRGgNWv5iRBMXtpHHYly9BRqY2FXNE2F4B5Xx75VLtBQfyWaIORB7nI/tG0AbriXC/mFfE/us=" + } + ], + "body": "\r\n
", + "isRead": false, + "receivedBy": "testbox@demistodev.onmicrosoft.com", + "author": "darbel@paloaltonetworks.com", + "toRecipients": [ + "testbox@demistodev.onmicrosoft.com" + ], + "FileAttachments": [ + { + "originalItemId": "originalItemId", + "attachmentId": "attachmentId", + "attachmentName": "anar (1).jpeg", + "attachmentSHA256": "afc8f82063b4985b57292f07682c3010eef0d3cf3132482d418ad47df2993cca", + "attachmentContentType": "image/jpeg", + "attachmentContentId": "f_kal0kd8h0", + "attachmentContentLocation": null, + "attachmentSize": 31555, + "attachmentLastModifiedTime": "2020-05-24T15:05:22+03:00", + "attachmentIsInline": false, + "attachmentType": "FileAttachment" + } + ], + "mailbox": "testbox@demistodev.onmicrosoft.com" + } + ] + }, + "ews-expand-group": { + "EWS.ExpandGroup": { + "name": "testgroup-1@demistodev.onmicrosoft.com", + "members": [ + { + "mailbox": "avishai@demistodev.onmicrosoft.com", + "displayName": "Avishai Brandeis", + "mailboxType": "Mailbox" + }, + { + "mailbox": "testbox@demistodev.onmicrosoft.com", + "displayName": "test box", + "mailboxType": "Mailbox" + } + ] + } + } +} diff --git a/Packs/EWS/Integrations/EWSO365/test_data/raw_responses.json b/Packs/EWS/Integrations/EWSO365/test_data/raw_responses.json new file mode 100644 index 000000000000..ae8c52b62e73 --- /dev/null +++ b/Packs/EWS/Integrations/EWSO365/test_data/raw_responses.json @@ -0,0 +1,2426 @@ +{ + "ews-get-searchable-mailboxes": [ + { + "mailbox": "aaaaa@demistodev.onmicrosoft.com", + "mailboxId": "/o=ExchangeLabs/ou=Exchange Administrative Group", + "displayName": "aaaa", + "isExternal": "false", + "externalEmailAddress": null + } + ], + "ews-find-folders": [ + { + "name": "Favorites", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Top of Information Store", + "total_count": 0, + "id": "id", + "child_folder_count": 19, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Calendar", + "total_count": 0, + "id": "id", + "child_folder_count": 2, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Birthdays", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "United States holidays", + "total_count": 175, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Contacts", + "total_count": 0, + "id": "id", + "child_folder_count": 7, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "{A9E2BC46-B3A0-4243-B315-60D991004455}", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "{06967759-274D-40B2-A3EB-D7F9E73727D7}", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Recipient Cache", + "total_count": 21, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Companies", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "GAL Contacts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Organizational Contacts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "PeopleCentricConversation Buddies", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Conversation History", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Team Chat", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Deleted Items", + "total_count": 7, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Drafts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Inbox", + "total_count": 6, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 5 + }, + { + "name": "Journal", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Junk Email", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Notes", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Outbox", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Sent Items", + "total_count": 7, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Tasks", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Archive", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Conversation Action Settings", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ExternalContacts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Files", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PersonMetadata", + "total_count": 21, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": null + }, + { + "name": "Test", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Test1", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Yammer Root", + "total_count": 0, + "id": "id", + "child_folder_count": 3, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Feeds", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Inbound", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Outbound", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "My Contacts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PeopleConnect", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Recoverable Items", + "total_count": 0, + "id": "id", + "child_folder_count": 5, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Deletions", + "total_count": 12, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 1 + }, + { + "name": "Purges", + "total_count": 7, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 1 + }, + { + "name": "Versions", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Audits", + "total_count": 14, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Calendar Logging", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Finder", + "total_count": 0, + "id": "id", + "child_folder_count": 3, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Voice Mail", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "OwaFV15.1AllFocusedAQMkAGZiODc1MGY3LTBiODEtNDQAN2QtOWM3Yy1lZGI4YjIxZTE5NTAALgAAA3ge9qbo93dKqujtIHDxPSgBAOP1fdDThA5Nh/9sF3X5QNkAAAIBDAAAAA==", + "total_count": 6, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 5 + }, + { + "name": "OwaFV15.1AllOtherAQMkAGZiODc1MGY3LTBiODEtNDQAN2QtOWM3Yy1lZGI4YjIxZTE5NTAALgAAA3ge9qbo93dKqujtIHDxPSgBAOP1fdDThA5Nh/9sF3X5QNkAAAIBDAAAAA==", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "To-Do Search", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "System", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "AllCategorizedItems", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "AllContacts", + "total_count": 21, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "AllItems", + "total_count": 237, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 5 + }, + { + "name": "AllPersonMetadata", + "total_count": 21, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ApplicationDataRoot", + "total_count": 0, + "id": "id", + "child_folder_count": 23, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "00000002-0000-0ff1-ce00-000000000000", + "total_count": 0, + "id": "id", + "child_folder_count": 3, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "13937bba-652e-4c46-b222-3003f4d1ff97", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateContextData", + "total_count": 11, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "1caee58f-eb14-4a6b-9339-1fe2ddf6692b", + "total_count": 0, + "id": "id", + "child_folder_count": 2, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Recent", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Settings", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "2a486b53-dbd2-49c0-a2bc-278bdfc30833", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PersonalGrammars", + "total_count": 5, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "32d4b5e5-7d33-4e7f-b073-f8cffbbb47a1", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "outlookfavorites", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "35d54a08-36c9-4847-9018-93934c62740c", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PeoplePredictions.profile", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "394866fc-eedb-4f01-8536-3ff84b16be2a", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "InsightInstancesActions", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "3b2e5a14-128d-48aa-b581-482aac616d32", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "3c896ded-22c5-450f-91f6-3d1ef0848f6e", + "total_count": 0, + "id": "id", + "child_folder_count": 20, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ActivitiesDaily", + "total_count": 61, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ActivitiesWeekly", + "total_count": 9, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "AfterHoursEmailImpact", + "total_count": 54, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "AutomaticRepliesHistory", + "total_count": 20, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ChatsInterruptionStatistics", + "total_count": 53, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ComputeLogs", + "total_count": 22, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "CumulativeNetworkSnapshot", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "CumulativeOutOfOfficeClustering", + "total_count": 108, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "DailyAppointments", + "total_count": 86, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "DailyInteractions", + "total_count": 54, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "DailyNetworkSnapshot", + "total_count": 54, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "DetailedMeetings", + "total_count": 54, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "EmailActionStatistics", + "total_count": 54, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "HeterogeneousItems", + "total_count": 11, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ImportantContact", + "total_count": 5, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ManagementOperationExecutionRecords", + "total_count": 4, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "MeetingActionStatistics", + "total_count": 9, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "OutOfOffice", + "total_count": 47, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "WeeklyInteractions", + "total_count": 7, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "WeeklyOutOfOfficeAndWorkingDay", + "total_count": 7, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "441509e5-a165-4363-8ee7-bcf0b7d26739", + "total_count": 0, + "id": "id", + "child_folder_count": 9, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GenericWorkflowProcessor.SessionManager.Data", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Idf", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "IdfMeeting", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SimpleAcronymsIndex", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "UserDocKpeStats", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "UserDocWithKpes", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "UserKpes", + "total_count": 2, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "UserKpeState", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "UserStatistics", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "48af08dc-f6d2-435f-b2a7-069abd99c086", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "InsightsProvidersSettings", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "49499048-0129-47f5-b95e-f9d315b861a6", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "OutlookAccountCloudSettings", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "4e445925-163e-42ca-b801-9073bfa46d17", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "NewsSubscriptionSourcesv2", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "644c1b11-f63f-45fa-826b-a9d2801db711", + "total_count": 0, + "id": "id", + "child_folder_count": 3, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "_PolicyContainer", + "total_count": 2, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "dGVzdGJveEBkZW1pc3RvZGV2Lm9ubWljcm9zb2Z0LmNvbQ==_LabelFile", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "dGVzdGJveEBkZW1pc3RvZGV2Lm9ubWljcm9zb2Z0LmNvbQ==_PolicyContainer", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "66a88757-258c-4c72-893c-3e8bed4d6899", + "total_count": 0, + "id": "id", + "child_folder_count": 15, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.CalendarEvents", + "total_count": 2, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.EmailEntities", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.EmailTokens", + "total_count": 22, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.FreshHistory", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.GroupsRoomsMiscIndex", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.People", + "total_count": 6, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.PeopleIndex", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.SearchHistory.Main", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.SearchHistoryBootstrapStateV2", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.SearchHistoryState", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.SharePointDocuments", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.SsaSessionManager", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.TeamsAndChannels", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.TeamsChats", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateSearch.TeamsEntities", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "766ef332-38e5-4cb4-920c-baa478e39fd9", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "CrawlerExecutionInfoCollection", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "7ae974c5-1af7-4923-af3a-fb1fd14dcb7e", + "total_count": 0, + "id": "id", + "child_folder_count": 5, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GetStartedStore", + "total_count": 15, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "lightning", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "LightningSharedStore", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "LightningStore", + "total_count": 44, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "WhatsNewStore", + "total_count": 34, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "80723a00-368e-4d64-8281-210e49e593a8", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ActivityFeed_201905", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "8c22b648-ee54-4ece-a4ca-3015b6d24f8e", + "total_count": 0, + "id": "id", + "child_folder_count": 2, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Images", + "total_count": 2, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Profiles", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ae8e128e-080f-4086-b0e3-4c19301ada69", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Scheduling", + "total_count": 2, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "b669c6ea-1adf-453f-b8bc-6d526592b419", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "FocusedInboxMailboxData", + "total_count": 2, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "d71dfe16-1070-48f3-bd3a-c3ec919d34e7", + "total_count": 0, + "id": "id", + "child_folder_count": 2, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "TxpAutoblocking", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "TxpUserSettings", + "total_count": 10, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "e69932cd-f814-4087-8ab1-5ab3f1ad18eb", + "total_count": 0, + "id": "id", + "child_folder_count": 3, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PhishingBootstrap", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "BrokerSubscriptions", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "BulkActions", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "CalendarItemSnapshots", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "CalendarSharingCacheCollection", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Common Views", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ComplianceMetadata", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Connectors", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ConnectorConfigurations", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "CrawlerData", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "DefaultFoldersChangeHistory", + "total_count": 389, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Deferred Action", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Document Centric Conversations", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ExchangeODataSyncData", + "total_count": 36, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ExchangeSyncData", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "FileCollectionCache", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Folder Memberships", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Freebusy Data", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "FreeBusyLocalCache", + "total_count": 2, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "FreeBusyLocalCacheSubscriptions", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphFilesAndWorkingSetSearchFolder", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphStore", + "total_count": 0, + "id": "id", + "child_folder_count": 6, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphEdges", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphNodes", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphNonSecureDrafts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphNonSecureTransactions", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphRelations", + "total_count": 4, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Inference", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Location", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "MailboxAssociations", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "MeetingSapces", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "MergedViewFolderCollection", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "MessageIngestion", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Yammer", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "O365 Suite Notifications", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "O365 Suite Storage", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "OneDriveRoot", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Orion Notes", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PACE", + "total_count": 2, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "DelveNotifications", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ParkedMessages", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Pass-Through Search Results", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PdpProfile", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PdpProfileV2", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "People I Know", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PeopleInsights", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "PeoplePublicData", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "QuarantinedEmail", + "total_count": 0, + "id": "id", + "child_folder_count": 1, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "QuarantinedEmailDefaultCategory", + "total_count": 0, + "id": "id", + "child_folder_count": 4, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "QedcDefaultRetention", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "QedcLongRetention", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "QedcMediumRetention", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "QedcShortRetention", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "RelevantContacts", + "total_count": 21, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Reminders", + "total_count": 12, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Schedule", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ShardRelevancyFolder", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SharedFilesSearchFolder", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SharePointNotifications", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Sharing", + "total_count": 1, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Shortcuts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SkypeSpacesData", + "total_count": 0, + "id": "id", + "child_folder_count": 2, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SkypeMessages", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "TeamsMeetings", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SmsAndChatsSync", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Spooler Queue", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SpoolsSearchFolder", + "total_count": 9, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SubstrateFiles", + "total_count": 0, + "id": "id", + "child_folder_count": 3, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "ClassicAttachments", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "GraphWorkingSet", + "total_count": 3, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SPOOLS", + "total_count": 9, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SuggestedUserGroupAssociations", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "SwssItems", + "total_count": 0, + "id": "id", + "child_folder_count": 3, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "TeamChatHistory", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "TeamsMessagesData", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "TemporarySaves", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "UserCuratedContacts", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "UserSocialActivityNotifications", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "Views", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmActivityClientInstrumentation", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmActivityServerInstrumentation", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmActivityStream", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmActivityStreamSearch", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmCompanySearch", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmDealSearch", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmDeletedItems", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmInsights", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmProjects", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "XrmSearch", + "total_count": 21, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + }, + { + "name": "YammerData", + "total_count": 0, + "id": "id", + "child_folder_count": 0, + "changekey": "changekey", + "unread_count": 0 + } + ], + "ews-search-mailbox": [ + { + "itemId": "itemId", + "datetimeCreated": "2020-05-21T12:36:24Z", + "datetimeReceived": "2020-05-21T12:36:25Z", + "datetimeSent": "2020-05-21T12:35:18Z", + "sender": "darbel@paloaltonetworks.com", + "hasAttachments": false, + "importance": "Normal", + "messageId": "messageId", + "lastModifiedTime": "2020-05-24T10:30:33Z", + "size": 57321, + "subject": "test with attachment", + "textBody": "\r\nDean Arbel\r\nStaff Software Engineer, Content Team, Demisto\r\nEmail: darbel@paloaltonetworks.com\r\nPhone: +972.54.7209916\r\n[https://go.demisto.com/hubfs/Demisto-Full%20Color-Logo.png]\r\n", + "headers": [ + { + "name": "Received", + "value": "from VI1PR07MB5728.eurprd07.prod.outlook.com (2603:10a6:20b:f0::25) by AM5PR0701MB2388.eurprd07.prod.outlook.com with HTTPS via AM6PR04CA0048.EURPRD04.PROD.OUTLOOK.COM; Thu, 21 May 2020 12:36:24 +0000" + }, + { + "name": "Received", + "value": "from AM6PR02CA0035.eurprd02.prod.outlook.com (2603:10a6:20b:6e::48) by VI1PR07MB5728.eurprd07.prod.outlook.com (2603:10a6:803:d4::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.13; Thu, 21 May 2020 12:36:23 +0000" + }, + { + "name": "Received", + "value": "from VE1EUR01FT047.eop-EUR01.prod.protection.outlook.com (2603:10a6:20b:6e:cafe::20) by AM6PR02CA0035.outlook.office365.com (2603:10a6:20b:6e::48) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.26 via Frontend Transport; Thu, 21 May 2020 12:36:22 +0000" + }, + { + "name": "Received", + "value": "from mx0b-00169c01.pphosted.com (67.231.156.123) by VE1EUR01FT047.mail.protection.outlook.com (10.152.3.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23 via Frontend Transport; Thu, 21 May 2020 12:36:21 +0000" + }, + { + "name": "Received", + "value": "from pps.filterd (m0048188.ppops.net [127.0.0.1])\tby mx0b-00169c01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 04LCYwj1030495\tfor ; Thu, 21 May 2020 05:36:20 -0700" + }, + { + "name": "Received", + "value": "from mail-oo1-f69.google.com (mail-oo1-f69.google.com [209.85.161.69])\tby mx0b-00169c01.pphosted.com with ESMTP id 312j0ajtmj-1\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT)\tfor ; Thu, 21 May 2020 05:36:20 -0700" + }, + { + "name": "Received", + "value": "by mail-oo1-f69.google.com with SMTP id l21so3325823oos.22 for ; Thu, 21 May 2020 05:36:20 -0700 (PDT)" + }, + { + "name": "Authentication-Results", + "value": "spf=pass (sender IP is 67.231.156.123) smtp.mailfrom=paloaltonetworks.com; demistodev.onmicrosoft.com; dkim=pass (signature was verified) header.d=paloaltonetworks.com;demistodev.onmicrosoft.com; dmarc=pass action=none header.from=paloaltonetworks.com;compauth=pass reason=100" + }, + { + "name": "Received-SPF", + "value": "Pass (protection.outlook.com: domain of paloaltonetworks.com designates 67.231.156.123 as permitted sender) receiver=protection.outlook.com; client-ip=67.231.156.123; helo=mx0b-00169c01.pphosted.com;" + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks.com; h=mime-version : from : date : message-id : subject : to : content-type; s=PPS12012017; bh=3V1MY5tIy0u3WVuB2TCXSM7iWtDLNm025KA+8pHonYQ=; b=YGiaV+dbdkA2+ttEOBtgdPSwPLUmr/EQRS+oBQ+Z7eEA56HF7aEQ48DYSpJhNKa5nTMW FiJ0bEWi9XmA2+dKy0A0ZtyJrodqpY1W8xnWRVKaO4MIsvVTyUTJSfJKDBVw6clv652/ Q9NagmlnQf6lfSF/0h/rc0BvFQoWlQ23ApabaSz2agtfWLFsvf36l14UqNCHfrwoQHcY YIDEofGu37O29lDwnDky+VJTg0jKN5BguRctMd4cFPe0xbo3M0RMijzsqCrKKTtRVF7O IcP3llqEigi5wEtawxMb4NQlZbvL6VP1G5aSdYDallFtZm5qj7aFyNpjOKyNffN6oVxX qg== " + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=3V1MY5tIy0u3WVuB2TCXSM7iWtDLNm025KA+8pHonYQ=; b=2Dtn+BoifCZ57s/MHyQJwITiYpW2HRGC8rx9kFP+/8I9Sa55DrjlSrupAqKFkmgi2e hUq56LW6PXK20T02gOFjkf6ja+f9x8/F3VoBG4ADX7rLAgbWc7YXbLjOfUohau+1UITd aMWswug+4rY7L8QTdpeQiEj8nfCB5t+/RNCoLCMV4zwvjeKQ8Nkg6sWuU/LSb+t4W5l+ 67Fq4osfFUQPwbXPBeAKhpmi4NYldZKc54MTOKi1sHyaXzADB475VZ0b9d7D++8ulxXb E3qTeWi7KYySygm45+sMZ/4AYNlgjiT6Gmx4SkQGTmvN/VqjlXLpWLs0Q3xDxNW+Ggsh M47Q==" + }, + { + "name": "X-Google-DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=3V1MY5tIy0u3WVuB2TCXSM7iWtDLNm025KA+8pHonYQ=; b=B+AzxBw/moiaMpD/h5HMIwigEukmQdzOVjIEAuFpRW1V1FdKQinxprXMalv39PQlDD WUJlmAQYCvvifA5VaUkkAuYUETq++2yVLaVSd6YW0jKwcm+yvQp10MpatmEVBBPwuRfr 8YF3L9Qhzd8bSlcg0v6UTLTs/j18jHFceBI7UNasFpsag5yVAdAiF4HTYLAO4FV8syif Ee/EaO8/qRyzzxdnqT4WyksZF1dFcgBj3Ii8E3QnbpEkElsrcOo8yFhtgiKWesQxilyK bt5y+BdwYB9dAKzAw3yxxuBYQBuJ0VPVW585moHfUJ5YvjLHsIGkag2PmRPyKpmSPUJk A6+A==" + }, + { + "name": "X-Gm-Message-State", + "value": "AOAM533KzEt3TBZth3vp/FoX67aS/igSrt7HFh+PVgZkcp1b8+Ro1jD0\tURWuKgm2VcXOnOHyWyiWgpl3L3JwGXAqFtrnEG7z6nReZEzWeyjNLm0zEXFArNjNdu5cf01PGec\tS7r8Rn5VIPtO+4Cejj6uuuZ06XpMLXmWhT8xRG54CGvL6vSZ/" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr6740225oie.142.1590064579748; Thu, 21 May 2020 05:36:19 -0700 (PDT)" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr6740179oie.142.1590064578767; Thu, 21 May 2020 05:36:18 -0700 (PDT)" + }, + { + "name": "X-Google-Smtp-Source", + "value": "ABdhPJycyvGbCUwXro6NGtBzPoJPyFIRPmnnjz60CS0xnuEXr6ubn//2nkXr6vikUMIWmI5gZY7fW0EQD1/Wo//8eeQ=" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Thu, 21 May 2020 15:35:18 +0300" + }, + { + "name": "Message-ID", + "value": "" + }, + { + "name": "Subject", + "value": "test with attachment" + }, + { + "name": "Content-Type", + "value": "multipart/mixed" + }, + { + "name": "X-Proofpoint-Virus-Version", + "value": "vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-21_06:2020-05-21,2020-05-21 signatures=0" + }, + { + "name": "X-Proofpoint-Spam-Details", + "value": "rule=outbound_spam_notspam policy=outbound_spam score=0 malwarescore=0 priorityscore=1501 bulkscore=0 cotscore=-2147483648 phishscore=0 spamscore=0 clxscore=1011 adultscore=0 mlxlogscore=438 mlxscore=0 suspectscore=0 lowpriorityscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2005210093" + }, + { + "name": "Return-Path", + "value": "darbel@paloaltonetworks.com" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTime", + "value": "21 May 2020 12:36:22.4651 (UTC)" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTimeReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationInterval", + "value": "1:00:00:00.0000000" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationIntervalReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-Network-Message-Id", + "value": "33e1ab54-578d-45ad-6123-08d7fd8391c9" + }, + { + "name": "X-EOPAttributedMessage", + "value": "0" + }, + { + "name": "X-EOPTenantAttributedMessage", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999:0" + }, + { + "name": "X-MS-Exchange-Organization-MessageDirectionality", + "value": "Incoming" + }, + { + "name": "X-Forefront-Antispam-Report", + "value": "CIP:67.231.156.123;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mx0b-00169c01.pphosted.com;PTR:mx0b-00169c01.pphosted.com;CAT:NONE;SFTY:;SFS:(4636009)(564344004)(86362001)(7636003)(42186006)(22186003)(33964004)(356005)(26005)(336012)(7596003)(3480700007)(7116003)(9686003)(8676002)(2160300002)(5660300002)(1096003)(6916009)(55446002)(58800400005)(133083001);DIR:INB;SFP:;" + }, + { + "name": "X-MS-PublicTrafficType", + "value": "Email" + }, + { + "name": "X-MS-Exchange-Organization-AuthSource", + "value": "VE1EUR01FT047.eop-EUR01.prod.protection.outlook.com" + }, + { + "name": "X-MS-Exchange-Organization-AuthAs", + "value": "Anonymous" + }, + { + "name": "X-MS-Office365-Filtering-Correlation-Id", + "value": "33e1ab54-578d-45ad-6123-08d7fd8391c9" + }, + { + "name": "X-MS-TrafficTypeDiagnostic", + "value": "VI1PR07MB5728:" + }, + { + "name": "X-MS-Exchange-AtpMessageProperties", + "value": "SA" + }, + { + "name": "X-MS-Oob-TLC-OOBClassifiers", + "value": "OLM:1728;" + }, + { + "name": "X-MS-Exchange-Organization-SCL", + "value": "1" + }, + { + "name": "X-Microsoft-Antispam", + "value": "BCL:0;" + }, + { + "name": "X-MS-Exchange-CrossTenant-OriginalArrivalTime", + "value": "21 May 2020 12:36:21.9939 (UTC)" + }, + { + "name": "X-MS-Exchange-CrossTenant-Network-Message-Id", + "value": "33e1ab54-578d-45ad-6123-08d7fd8391c9" + }, + { + "name": "X-MS-Exchange-CrossTenant-Id", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999" + }, + { + "name": "X-MS-Exchange-CrossTenant-FromEntityHeader", + "value": "Internet" + }, + { + "name": "X-MS-Exchange-Transport-CrossTenantHeadersStamped", + "value": "VI1PR07MB5728" + }, + { + "name": "X-MS-Exchange-Transport-EndToEndLatency", + "value": "00:00:02.6143909" + }, + { + "name": "X-MS-Exchange-Processed-By-BccFoldering", + "value": "15.20.3021.019" + }, + { + "name": "X-Microsoft-Antispam-Mailbox-Delivery", + "value": "ucf:0;jmr:0;auth:0;dest:I;ENG:(20160514016)(750128)(520011016)(944506383)(944626604);" + }, + { + "name": "X-Microsoft-Antispam-Message-Info", + "value": "GYMxyfjbkGHsUpWSD/+/zAqqyIHrTe+HHUexgZpYTm2UkhmvRqDi9kkwrPOItdlPtZe+zWuoZ9Dvl5I0jxgdawDRZH0/67UGmNlGddyF/PIYT6LdJsV3CBqK7h4PMRref2rqtG6LO401erigCiu8DdIxE6ikgqOkTJ9TB7/qiyNh5RcBLQqW9WKQ0wJb0HhebecR1qOIYMqSkJO11n8jv+/yAtFGpj17XsDuotY/vZVMFZWiUaQVPkqReO2Dwz6XWNsQtI5F5omzCdxpf60/MHVVDA/A1qcZI+a1Xj+ipeFYUalyzXkK5rUKXaAZtlcfY7muB2a0R+m+M0IDfEW99Fj0r0xC9ncQ5QZxoMxWBEjMhkNRXPt1YikazW7TKA43FGxow2K0PGSzZjeffQ+RgAcsnIp4+BEJBdpQK1zE4MHmlhgZ/WJPFi43qUZX0vL51H2dae8hlPHKcjogRTlecqsqhjSYujN46pKgbZ849S5negxD+yoFN1HAn9hjcban05Wz0n8SdK9eevySMrbobjBWvSKb+ZMNYLVD8UwAatsYm+5+tzgZEdxO6OOatf9Mx8/g5+/Q8F6Z859doJDTJ2oZptzvQjbVfhPw0+Hv777s6kzbUydnBxaDxQh+X95RCFcDXHurOhS+sch65hmJqkjR5IsoEmiukpsZNeHfBwmZq7KpqUE74nbTcSwfxLZvP1Wzd+1Hc0Qrq0IPQQsgdgUlgdeEZPZ7SciSXE2em++/9BnU36rFKOimEp/DQokD/1e0qsZG5FkFIifpgc9ghpROWkUMHj5sAuhq6lbs8RADc7ErAjKIppfJBMJzYu+RiTvyvxfLm0bxVQsl9ONXgfMqvJk2+Nliu8tkotPgz9SMEztVkS4kinhDrnjhF0LPZoBeJEPHVM/k1g7A4i1kEEevvJJdnmaLQ8JKNTKMFqPryQc2Tch8jDzUCEkxCrIiHVqLzHfUfGfeGx1sVLLoVjTUq2jY100+s9DCkEOsFemtxYduN32OR5rPBl2ruwqyhBnpPrEbCwSZySoZ+CK+PKdnTr6U1OQEAVvIdI/QjnqvYaoExUC2cu8whC+q/VlKk46P0DxPQHEmrlbvU2BTAlNfMBeReIJ1qKZ+Mw9rpeHbxOYi9F+zJ08COmcWqfaIeCBQxA3bnARzYBwFLbQCWBPiTTunLlZhHDl8BAaFb4qhaShjtAKaFILg1V/jJNi5uPOpazmhHCTgrQGN6BX8nQ==" + } + ], + "body": "\r\n", + "isRead": true, + "receivedBy": "testbox@demistodev.onmicrosoft.com", + "author": "darbel@paloaltonetworks.com", + "toRecipients": [ + "testbox@demistodev.onmicrosoft.com" + ], + "mailbox": "testbox@demistodev.onmicrosoft.com" + } + ], + "ews-get-contacts": [ + { + "itemClass": "IPM.Contact", + "subject": "Avishai Brandeis", + "sensitivity": "Normal", + "textBody": "\r\n\r\n", + "body": "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
 
\r\n
 
\r\n
\r\n\r\n\r\n", + "datetimeReceived": "2019-10-19T14:38:51Z", + "importance": "Normal", + "datetimeSent": "2019-10-19T14:38:51Z", + "datetimeCreated": "2019-10-19T14:38:53Z", + "culture": "en-US", + "lastModifiedName": "Avishai Brandeis", + "lastModifiedTime": "2019-10-19T14:42:54Z", + "webClientReadFormQueryString": "webClientReadFormQueryString", + "uniqueBody": "", + "fileAs": "Brandeis, Avishai", + "fileAsMapping": "LastCommaFirst", + "displayName": "Avishai Brandeis", + "givenName": "Avishai", + "initials": "A.B.", + "jobTitle": "test", + "postalAddressIndex": "None", + "surname": "Brandeis", + "emailAddresses": [ + "avishai@demistodev.onmicrosoft.com" + ], + "originMailbox": null + } + ], + "ews-get-items-from-folder": [ + { + "itemId": "itemId", + "datetimeCreated": "2020-05-24T12:05:22Z", + "datetimeReceived": "2020-05-24T12:05:23Z", + "datetimeSent": "2020-05-24T12:04:16Z", + "sender": "darbel@paloaltonetworks.com", + "hasAttachments": true, + "importance": "Normal", + "messageId": "messageId", + "lastModifiedTime": "2020-05-24T12:05:23Z", + "size": 96501, + "subject": "second fetch", + "textBody": "\r\nDean Arbel\r\nStaff Software Engineer, Content Team, Demisto\r\nEmail: darbel@paloaltonetworks.com\r\nPhone: +972.54.7209916\r\n[https://go.demisto.com/hubfs/Demisto-Full%20Color-Logo.png]\r\n", + "headers": [ + { + "name": "Received", + "value": "from AM6PR07MB5256.eurprd07.prod.outlook.com (2603:10a6:20b:2e::32) by AM5PR0701MB2388.eurprd07.prod.outlook.com with HTTPS via AM6PR05CA0019.EURPRD05.PROD.OUTLOOK.COM; Sun, 24 May 2020 12:05:22 +0000" + }, + { + "name": "Received", + "value": "from DB7PR03CA0105.eurprd03.prod.outlook.com (2603:10a6:10:72::46) by AM6PR07MB5256.eurprd07.prod.outlook.com (2603:10a6:20b:6c::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3045.8; Sun, 24 May 2020 12:05:21 +0000" + }, + { + "name": "Received", + "value": "from DB5EUR01FT016.eop-EUR01.prod.protection.outlook.com (2603:10a6:10:72:cafe::cb) by DB7PR03CA0105.outlook.office365.com (2603:10a6:10:72::46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.26 via Frontend Transport; Sun, 24 May 2020 12:05:21 +0000" + }, + { + "name": "Received", + "value": "from mx0b-00169c01.pphosted.com (67.231.156.123) by DB5EUR01FT016.mail.protection.outlook.com (10.152.4.255) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23 via Frontend Transport; Sun, 24 May 2020 12:05:20 +0000" + }, + { + "name": "Received", + "value": "from pps.filterd (m0048188.ppops.net [127.0.0.1])\tby mx0b-00169c01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 04OC5DAh017336\tfor ; Sun, 24 May 2020 05:05:20 -0700" + }, + { + "name": "Received", + "value": "from mail-oo1-f69.google.com (mail-oo1-f69.google.com [209.85.161.69])\tby mx0b-00169c01.pphosted.com with ESMTP id 316ygbt5we-1\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT)\tfor ; Sun, 24 May 2020 05:05:19 -0700" + }, + { + "name": "Received", + "value": "by mail-oo1-f69.google.com with SMTP id z190so8178136ooa.19 for ; Sun, 24 May 2020 05:05:19 -0700 (PDT)" + }, + { + "name": "Authentication-Results", + "value": "spf=pass (sender IP is 67.231.156.123) smtp.mailfrom=paloaltonetworks.com; demistodev.onmicrosoft.com; dkim=pass (signature was verified) header.d=paloaltonetworks.com;demistodev.onmicrosoft.com; dmarc=pass action=none header.from=paloaltonetworks.com;compauth=pass reason=100" + }, + { + "name": "Received-SPF", + "value": "Pass (protection.outlook.com: domain of paloaltonetworks.com designates 67.231.156.123 as permitted sender) receiver=protection.outlook.com; client-ip=67.231.156.123; helo=mx0b-00169c01.pphosted.com;" + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks.com; h=mime-version : from : date : message-id : subject : to : content-type; s=PPS12012017; bh=oKMkuNMg4AOkAcDm/TJAqh+DBFvZo76l5u80led3OuQ=; b=nX2L66T91eUzH+H2NOmbtH7OvFR8SPAkHv3HkC9nIgHkHBhP+0y75T9tnswbcngJ1YH4 1t1GpME1af9yXTZvlHZ33aP446gH2cai/OSYh0AyMmSJ/gcMKnfvvYB55IOofGm29UVB UQax0+RRUdAsplVfjOKp90w9ZOMC3iMfs7DNLzc3mYuwfzmDgqaoxdW9LYsva+D47Jh6 PUIvNaQtJ5gnBTRM3dS/HOj8/8qOtk1BFiQrlfSdrUlyf/YW1zA7Rgjr9camjFpRO/ug +ohq7uxL1XBbuQGGHHATOIcT1/Utb130VABe5NMOhaSaaMv6SUw4D9CMzThKJMmPwKT3 Og== " + }, + { + "name": "DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=paloaltonetworks-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=oKMkuNMg4AOkAcDm/TJAqh+DBFvZo76l5u80led3OuQ=; b=zhHz86wU6AlPStMpUoctv8sqwn6RPVSqTXUR4l2o47CTg3JTG8Zzg8zPx+SEJ7TCQo 2P4XzUOgy8FwjlMmKub6YRb0MRKSV//MArs1rRpuprvEk7cPVddvVhNlq39Z2G9g0bkC I8V0yHNkK0g1PnCi16K+zkEvIniGu9Z4XTc+Gtrqte33NyrcIcQHaSDIt+rx6FA3wjqq DCuLh+QLLLLZQ0blCMIrUQndZKtqgy8TKvxAAE6lA+o4MrqKQCSNWLR8It8lfD1/kACi 56u8993bfz+ygncyZKoJnvOnN1xYMwtjReMrTGPE7DQaV9dT/8OnZMalAoPpgZJsV2c4 pnYA==" + }, + { + "name": "X-Google-DKIM-Signature", + "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=oKMkuNMg4AOkAcDm/TJAqh+DBFvZo76l5u80led3OuQ=; b=mqyRLna0nlMpWHgCGcSnUQQJwYwLGfVLcsefOEwHpNFCALI2axWh/g2R/bNNSnCbht YKPRSfwjnnMV7R29v+URpaFsfUIYGtvktYyA/Gpgk6UBpoqOvOTgziFxPDptPjXFUXqH 3tF5zK6Httt2C4hv3uJ7szNY2bnu21966L4Oq0OAJDJpJWt116ebwVyrtH8L95a0a+WK ymjTh7VFrWgSxvtuFGBIkpdEgbcz4Nwf6LmZ3d9QkDM4V3BE1LLdQyMr54BqesB2ZwW5 TQZ3Sy1PjbA3oAc7ClajCyuHk9vJ2TonYimF2EBsopDxrrB2x4ZC45bnllRswFsvPXJm u/AA==" + }, + { + "name": "X-Gm-Message-State", + "value": "AOAM530mhUfg9mbd/vLieicJ0PorcrLLS01V62u9nuJ96XD4gPIwHiF2\tE65GOXDh+NjlrqQTRpFCeU1EwMrkJPlRkRa+Zdb6YDwfg7T9ZRmi48TeVHS45ws3UeofplUK/H+\t/BwKWU0i7NmgwdJty+kdaAdKXVfABBAKyQ0a0FKYDv7Yeqjnt" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr8634827oie.142.1590321918013; Sun, 24 May 2020 05:05:18 -0700 (PDT)" + }, + { + "name": "X-Received", + "value": "by 2002:a05:6808:106:: with SMTP id b6mr8634794oie.142.1590321917402; Sun, 24 May 2020 05:05:17 -0700 (PDT)" + }, + { + "name": "X-Google-Smtp-Source", + "value": "ABdhPJyd3hDsiXnVW3uD+Am05+DCdgZ5nYUWSas3oQpGK7s6UXHxeEiBT58TFD7hfNvVejB0M8kUPg29m+om6RSsjAA=" + }, + { + "name": "MIME-Version", + "value": "1.0" + }, + { + "name": "Date", + "value": "Sun, 24 May 2020 15:04:16 +0300" + }, + { + "name": "Message-ID", + "value": "" + }, + { + "name": "Subject", + "value": "second fetch" + }, + { + "name": "Content-Type", + "value": "multipart/mixed" + }, + { + "name": "X-Proofpoint-Virus-Version", + "value": "vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-24_02:2020-05-22,2020-05-24 signatures=0" + }, + { + "name": "X-Proofpoint-Spam-Details", + "value": "rule=outbound_spam_notspam policy=outbound_spam score=0 malwarescore=0 bulkscore=0 priorityscore=1501 spamscore=0 mlxscore=0 suspectscore=0 mlxlogscore=479 lowpriorityscore=0 adultscore=0 phishscore=0 impostorscore=0 cotscore=-2147483648 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2005240103" + }, + { + "name": "Return-Path", + "value": "darbel@paloaltonetworks.com" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTime", + "value": "24 May 2020 12:05:21.3150 (UTC)" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationStartTimeReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationInterval", + "value": "1:00:00:00.0000000" + }, + { + "name": "X-MS-Exchange-Organization-ExpirationIntervalReason", + "value": "OriginalSubmit" + }, + { + "name": "X-MS-Exchange-Organization-Network-Message-Id", + "value": "04736eb5-a8f0-4eca-aa89-08d7ffdabbb1" + }, + { + "name": "X-EOPAttributedMessage", + "value": "0" + }, + { + "name": "X-EOPTenantAttributedMessage", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999:0" + }, + { + "name": "X-MS-Exchange-Organization-MessageDirectionality", + "value": "Incoming" + }, + { + "name": "X-Forefront-Antispam-Report", + "value": "CIP:67.231.156.123;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mx0b-00169c01.pphosted.com;PTR:mx0b-00169c01.pphosted.com;CAT:NONE;SFTY:;SFS:(4636009)(336012)(564344004)(55446002)(356005)(5660300002)(8676002)(2160300002)(3480700007)(1096003)(42186006)(7596003)(26005)(33964004)(6666004)(86362001)(7636003)(9686003)(6916009)(7116003);DIR:INB;SFP:;" + }, + { + "name": "X-MS-PublicTrafficType", + "value": "Email" + }, + { + "name": "X-MS-Exchange-Organization-AuthSource", + "value": "DB5EUR01FT016.eop-EUR01.prod.protection.outlook.com" + }, + { + "name": "X-MS-Exchange-Organization-AuthAs", + "value": "Anonymous" + }, + { + "name": "X-MS-Office365-Filtering-Correlation-Id", + "value": "04736eb5-a8f0-4eca-aa89-08d7ffdabbb1" + }, + { + "name": "X-MS-TrafficTypeDiagnostic", + "value": "AM6PR07MB5256:" + }, + { + "name": "X-MS-Exchange-AtpMessageProperties", + "value": "SA" + }, + { + "name": "X-MS-Oob-TLC-OOBClassifiers", + "value": "OLM:1728;" + }, + { + "name": "X-MS-Exchange-Organization-SCL", + "value": "1" + }, + { + "name": "X-Microsoft-Antispam", + "value": "BCL:0;" + }, + { + "name": "X-MS-Exchange-CrossTenant-OriginalArrivalTime", + "value": "24 May 2020 12:05:20.9502 (UTC)" + }, + { + "name": "X-MS-Exchange-CrossTenant-Network-Message-Id", + "value": "04736eb5-a8f0-4eca-aa89-08d7ffdabbb1" + }, + { + "name": "X-MS-Exchange-CrossTenant-Id", + "value": "ebac1a16-81bf-449b-8d43-5732c3c1d999" + }, + { + "name": "X-MS-Exchange-CrossTenant-FromEntityHeader", + "value": "Internet" + }, + { + "name": "X-MS-Exchange-Transport-CrossTenantHeadersStamped", + "value": "AM6PR07MB5256" + }, + { + "name": "X-MS-Exchange-Transport-EndToEndLatency", + "value": "00:00:01.7736787" + }, + { + "name": "X-MS-Exchange-Processed-By-BccFoldering", + "value": "15.20.3045.009" + }, + { + "name": "X-Microsoft-Antispam-Mailbox-Delivery", + "value": "ucf:0;jmr:0;auth:0;dest:I;ENG:(20160514016)(750128)(520011016)(944506383)(944626604);" + }, + { + "name": "X-Microsoft-Antispam-Message-Info", + "value": "8W3SISohCZB2jQsUVcqhQbQIXqqgocGxEoacfDww85zYoebJ4CFEHyfPsjUv+LWjYSozYrGJD2/XqethtTTJJW6GWACydYyIZsou4z883d0qB1DF7GfQQfgrAupBUcIj89jZALyqlQso/er4YUyuYWcW+5pUomBty6xvEErGMJYS7fxrR/7/Yt5pUoh8ZA77zrvssAXTcVkTw3kQwzzVYyvNwbAf0v4gKAoDzFaxij+5Agi89r8g9TTgz/V2b5uozJjCaJGdF8OOTEuZynKMlIv1PvIMBbZk+ODD3N+BfGPgIrRGtzDh8+mq95cFJL88feiiZk6WzkEDdmKa2UdxnZ/WWHIqUtqpukSXt7V7jxpl49ZxSU0gKeZ7O9SKBRsMtLtsCyg2lSr49/pZhIh08i0cQ05etP6iRnfI3LZyOMLKrb/MklGtS0YpnYO6fLUpUDcXZOaHkdnN5G981RHyh0SX5fZlApq90HPhgSWtNVC2Oa3P4v033t8YWR0w7SiQu4F1rYG6f0b7P7AlKLfBnNNhN7LFFEbJ6Dx/3TXZSm6Ayxmh2McwOGGTnBOBnJ5uBSXFtn7SZ83I13G1IK7YvSH0E4OpvNsZR/IlBmypFSZu9d/6/fO4IIDbn0xtGeFz0mw0gRQEKkoqYWjFNQAUQUKUoDJRV4zbBKaQrzoCHlEzcWaLURomBTq4DToNt6CC6mEqEy2//FDOAqmUgmkscmJyUYRWGvuH/rWL40IYzwULxK+sUxj7wyv2zYMFiRE0rygZn417GM9tNG1IKdxV+70QMLaNu/d2POwIEdth+yUMnnP9PCDoaQlwhIYSUlaVJM7LBHXatKf5wpu/SQQdkq5GAf6bXjowjBdrxSZqAxuI1hoCjhx4FipRCfseqyhKqBcBSKTH4fh3+xGbarFdcWnklgvya4m6ydpbg5yyXQclOOcB1hjuLL5P9/UM1jI/4EPYRHPfzC2hhO+Ncn3mznUJSuJksNz9Yw13wHynU509CyTRBbLNRxwnCzrrpYjTROeOWgP1SfhaoX5q+JPDbXeuPK+oYyXzVZeLuOuBt15euPvxeNR0Sqnhc+sQy8BRhBZcTfcKbS4RZ/tFTrmsknkaGp3wXycjVdYRGgNWv5iRBMXtpHHYly9BRqY2FXNE2F4B5Xx75VLtBQfyWaIORB7nI/tG0AbriXC/mFfE/us=" + } + ], + "body": "\r\n
", + "isRead": false, + "receivedBy": "testbox@demistodev.onmicrosoft.com", + "author": "darbel@paloaltonetworks.com", + "toRecipients": [ + "testbox@demistodev.onmicrosoft.com" + ], + "FileAttachments": [ + { + "originalItemId": "originalItemId", + "attachmentId": "attachmentId", + "attachmentName": "anar (1).jpeg", + "attachmentSHA256": "afc8f82063b4985b57292f07682c3010eef0d3cf3132482d418ad47df2993cca", + "attachmentContentType": "image/jpeg", + "attachmentContentId": "f_kal0kd8h0", + "attachmentContentLocation": null, + "attachmentSize": 31555, + "attachmentLastModifiedTime": "2020-05-24T15:05:22+03:00", + "attachmentIsInline": false, + "attachmentType": "FileAttachment" + } + ], + "mailbox": "testbox@demistodev.onmicrosoft.com" + } + ], + "ews-expand-group": [ + { + "mailbox": "avishai@demistodev.onmicrosoft.com", + "displayName": "Avishai Brandeis", + "mailboxType": "Mailbox" + }, + { + "mailbox": "testbox@demistodev.onmicrosoft.com", + "displayName": "test box", + "mailboxType": "Mailbox" + } + ] +} diff --git a/Packs/EWS/Integrations/EWSv2/README.md b/Packs/EWS/Integrations/EWSv2/README.md index 8f796c7d0fd3..25462e289497 100644 --- a/Packs/EWS/Integrations/EWSv2/README.md +++ b/Packs/EWS/Integrations/EWSv2/README.md @@ -72,7 +72,7 @@

To use Fetch incidents, configure a new instance and select the Fetches incidents option in the instance settings.

IMPORTANT: The initial fetch interval is the previous 10 minutes. If no emails were fetched before from the destination folder- all emails from 10 minutes prior to the instance configuration and up to the current time will be fetched. Additionally moving messages manually to the destination folder will not trigger fetch incident. Define rules on phishing/target mailbox instead of moving messages manually.

Pay special attention to the following fields in the instance settings:

-

Email address from which to fetch incidents – mailbox to fetch incidents from.
Name of the folder from which to fetch incidents – use this field to configure the destination folder from where emails should be fetched. The default is Inbox folder.
Has impersonation rights – mark this option if you set the target mailbox to an account different than your personal account. Otherwise Delegation access will be used instead of Impersonation.
Find more information on impersonation or delegation rights at ‘Additional Info’ section below.

+

Email address from which to fetch incidents – mailbox to fetch incidents from.
Name of the folder from which to fetch incidents – use this field to configure the destination folder from where emails should be fetched. The default is Inbox folder. Please note, if Exchange is configured with an international flavor `Inbox` will be named according to the configured language.
Has impersonation rights – mark this option if you set the target mailbox to an account different than your personal account. Otherwise Delegation access will be used instead of Impersonation.
Find more information on impersonation or delegation rights at ‘Additional Info’ section below.

Commands

You can execute these commands from the Demisto 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.

    @@ -2796,4 +2796,4 @@

     

    New-Compliance Search

    -

    The EWS v2 integration uses remote ps-session to run commands of compliance search as part of Office 365. To check if your account can connect to Office 365 Security & Compliance Center via powershell, check the following steps. New-Compliance search is a long-running task which has no limitation of searched mailboxes and therefore the suggestion is to use Office 365 Search and Deleteplaybook. New-Compliance search returns statistics of matched content search query and doesn't return preview of found emails in contrast to ews-search-mailboxes command.

    \ No newline at end of file +

    The EWS v2 integration uses remote ps-session to run commands of compliance search as part of Office 365. To check if your account can connect to Office 365 Security & Compliance Center via powershell, check the following steps. New-Compliance search is a long-running task which has no limitation of searched mailboxes and therefore the suggestion is to use Office 365 Search and Deleteplaybook. New-Compliance search returns statistics of matched content search query and doesn't return preview of found emails in contrast to ews-search-mailboxes command.

    diff --git a/Packs/EWS/ReleaseNotes/1_1_0.md b/Packs/EWS/ReleaseNotes/1_1_0.md new file mode 100644 index 000000000000..d3c94b2086f6 --- /dev/null +++ b/Packs/EWS/ReleaseNotes/1_1_0.md @@ -0,0 +1,4 @@ + +### Integrations +- __EWSO365__ +New Integration EWS O365 diff --git a/Packs/EWS/TestPlaybooks/playbook-EWS_O365_test.yml b/Packs/EWS/TestPlaybooks/playbook-EWS_O365_test.yml new file mode 100644 index 000000000000..4bedd0918809 --- /dev/null +++ b/Packs/EWS/TestPlaybooks/playbook-EWS_O365_test.yml @@ -0,0 +1,859 @@ +id: EWS_O365_test +version: -1 +name: EWS_O365_test +fromversion: 5.0.0 +description: "" +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: 868b5714-1f56-40ad-8e0b-64e807805489 + type: start + task: + description: "" + id: 868b5714-1f56-40ad-8e0b-64e807805489 + version: -1 + name: "" + iscommand: false + brand: "" + nexttasks: + '#none#': + - "1" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 50 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "1": + id: "1" + taskid: 4aa13052-7a37-4389-83c0-3b103179d59f + type: regular + task: + description: "" + id: 4aa13052-7a37-4389-83c0-3b103179d59f + version: -1 + name: DeleteContext + script: DeleteContext + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "2" + scriptarguments: + all: + simple: "yes" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 195 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "2": + id: "2" + taskid: 140a8a39-d6f0-4a0d-8652-ce4cc7b155b9 + type: regular + task: + description: "" + id: 140a8a39-d6f0-4a0d-8652-ce4cc7b155b9 + version: -1 + name: ews-get-attachment + script: '|||ews-get-attachment' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "3" + scriptarguments: + attachment-ids: {} + item-id: + simple: AAMkAGZiODc1MGY3LTBiODEtNDQ3ZC05YzdjLWVkYjhiMjFlMTk1MABGAAAAAAB4Hvam6Pd3Sqro7SBw8T0oBwDj9X3Q04QOTYf/bBd1+UDZAAAAAAEMAADj9X3Q04QOTYf/bBd1+UDZAAAHclB6AAA= + target-mailbox: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 370 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "3": + id: "3" + taskid: e4b0396b-9fd8-481b-8722-e09914b5340f + type: condition + task: + description: "" + id: e4b0396b-9fd8-481b-8722-e09914b5340f + version: -1 + name: Verify Outputs + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "6" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.FileAttachments.attachmentId + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.FileAttachments.attachmentName + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.FileAttachments.attachmentSHA256 + iscontext: true + view: |- + { + "position": { + "x": 50, + "y": 545 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "6": + id: "6" + taskid: 8e54bd48-8d5c-485f-852d-59793c325221 + type: regular + task: + description: "" + id: 8e54bd48-8d5c-485f-852d-59793c325221 + version: -1 + name: ews-get-searchable-mailboxes + script: '|||ews-get-searchable-mailboxes' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "7" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 720 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "7": + id: "7" + taskid: 4daf91b6-b466-41f3-8b7c-d6b160b086c1 + type: condition + task: + description: "" + id: 4daf91b6-b466-41f3-8b7c-d6b160b086c1 + version: -1 + name: Verify Outputs + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "14" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: EWS.Mailboxes.mailbox + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Mailboxes.mailboxId + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Mailboxes.displayName + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Mailboxes.isExternal + iscontext: true + view: |- + { + "position": { + "x": 50, + "y": 895 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "14": + id: "14" + taskid: 04028000-32ce-44b2-84bc-e4e5dad7c7f4 + type: regular + task: + description: "" + id: 04028000-32ce-44b2-84bc-e4e5dad7c7f4 + version: -1 + name: ews-search-mailbox + script: '|||ews-search-mailbox' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "15" + scriptarguments: + folder-path: {} + is-public: {} + limit: {} + message-id: {} + query: + simple: move me + selected-fields: {} + target-mailbox: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1070 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "15": + id: "15" + taskid: e034e902-096d-451d-8751-44a53b74b098 + type: condition + task: + description: "" + id: e034e902-096d-451d-8751-44a53b74b098 + version: -1 + name: Verify Outputs + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "16" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isEqualString + left: + value: + simple: EWS.Items.itemId + iscontext: true + right: + value: + simple: AAMkAGZiODc1MGY3LTBiODEtNDQ3ZC05YzdjLWVkYjhiMjFlMTk1MABGAAAAAAB4Hvam6Pd3Sqro7SBw8T0oBwDj9X3Q04QOTYf/bBd1+UDZAAAAAAEMAADj9X3Q04QOTYf/bBd1+UDZAAAHclB4AAA= + view: |- + { + "position": { + "x": 50, + "y": 1245 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "16": + id: "16" + taskid: f54e460a-9d04-4fe9-8a06-ad6272af79fb + type: regular + task: + description: "" + id: f54e460a-9d04-4fe9-8a06-ad6272af79fb + version: -1 + name: ews-get-contacts + script: '|||ews-get-contacts' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "18" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1420 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "18": + id: "18" + taskid: 0d4138c5-30e9-437b-85e4-720d8862d74f + type: regular + task: + description: "" + id: 0d4138c5-30e9-437b-85e4-720d8862d74f + version: -1 + name: ews-get-out-of-office + script: '|||ews-get-out-of-office' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "19" + scriptarguments: + target-mailbox: + simple: avishai@demistodev.onmicrosoft.com + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1595 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "19": + id: "19" + taskid: 7eb0d117-14c3-4b78-89a1-71dd92f62edf + type: condition + task: + description: "" + id: 7eb0d117-14c3-4b78-89a1-71dd92f62edf + version: -1 + name: Verify Outputs + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "24" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isEqualString + left: + value: + simple: Account.Email.OutOfOffice.state + iscontext: true + right: + value: + simple: Disabled + view: |- + { + "position": { + "x": 50, + "y": 1770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "24": + id: "24" + taskid: 9e3cacfb-f02d-4b5f-8b10-66f150c4c27f + type: regular + task: + description: "" + id: 9e3cacfb-f02d-4b5f-8b10-66f150c4c27f + version: -1 + name: ews-find-folders + script: '|||ews-find-folders' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "25" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1945 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "25": + id: "25" + taskid: e4c73fb6-9c0f-419b-85f9-116c4e4b69be + type: condition + task: + description: "" + id: e4c73fb6-9c0f-419b-85f9-116c4e4b69be + version: -1 + name: Verify Outputs + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "26" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.name + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.id + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.totalCount + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.unreadCount + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.changeKey + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.childrenFolderCount + iscontext: true + view: |- + { + "position": { + "x": 50, + "y": 2120 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "26": + id: "26" + taskid: bfc3bff4-3c18-4d72-8bcf-3a6626b047e6 + type: regular + task: + description: "" + id: bfc3bff4-3c18-4d72-8bcf-3a6626b047e6 + version: -1 + name: ews-get-items-from-folder + script: '|||ews-get-items-from-folder' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "28" + scriptarguments: + folder-path: + simple: AllItems + get-internal-item: {} + is-public: {} + limit: + simple: "5" + target-mailbox: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 2295 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "28": + id: "28" + taskid: 92eb2cdc-6f16-4597-8851-09984d8f2778 + type: regular + task: + description: "" + id: 92eb2cdc-6f16-4597-8851-09984d8f2778 + version: -1 + name: ews-get-items + script: '|||ews-get-items' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "29" + scriptarguments: + item-ids: + simple: AAMkAGZiODc1MGY3LTBiODEtNDQ3ZC05YzdjLWVkYjhiMjFlMTk1MABGAAAAAAB4Hvam6Pd3Sqro7SBw8T0oBwDj9X3Q04QOTYf/bBd1+UDZAAAAAAEMAADj9X3Q04QOTYf/bBd1+UDZAAAHclB6AAA= + target-mailbox: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 2470 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "29": + id: "29" + taskid: 5f7483e1-47b0-4686-8240-bdd61149800a + type: condition + task: + description: "" + id: 5f7483e1-47b0-4686-8240-bdd61149800a + version: -1 + name: Verify Outputs + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "32" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.itemId + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.datetimeReceived + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.datetimeSent + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.headers + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.sender + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.subject + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Items.size + iscontext: true + view: |- + { + "position": { + "x": 50, + "y": 2645 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "32": + id: "32" + taskid: 0b3e36db-8292-42ad-8789-9cebe311dc1c + type: regular + task: + description: "" + id: 0b3e36db-8292-42ad-8789-9cebe311dc1c + version: -1 + name: ews-get-folder + script: '|||ews-get-folder' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "33" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 2820 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "33": + id: "33" + taskid: cb980652-ce60-461e-82b7-82580cdab17b + type: condition + task: + description: "" + id: cb980652-ce60-461e-82b7-82580cdab17b + version: -1 + name: Verify Outputs + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "34" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.id + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.name + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.changeKey + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.totalCount + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.childrenFolderCount + iscontext: true + - - operator: isNotEmpty + left: + value: + simple: EWS.Folders.unreadCount + iscontext: true + view: |- + { + "position": { + "x": 50, + "y": 2995 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "34": + id: "34" + taskid: 0001331a-66c0-4fa3-8434-71dfee5da637 + type: regular + task: + description: "" + id: 0001331a-66c0-4fa3-8434-71dfee5da637 + version: -1 + name: ews-expand-group + script: '|||ews-expand-group' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "40" + scriptarguments: + email-address: + simple: testgroup-1@demistodev.onmicrosoft.com + recursive-expansion: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 3170 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "39": + id: "39" + taskid: 8ff5c4d0-6f1c-4a82-8e83-cc4a011931a7 + type: title + task: + description: "" + id: 8ff5c4d0-6f1c-4a82-8e83-cc4a011931a7 + version: -1 + name: Test Done + type: title + iscommand: false + brand: "" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 3695 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "40": + id: "40" + taskid: 9607062f-6cf7-495e-822e-e465eec9d0a3 + type: regular + task: + id: 9607062f-6cf7-495e-822e-e465eec9d0a3 + version: -1 + name: ews-get-items-as-eml + description: Retrieves items by item ID and uploads its content as an EML file. + script: '|||ews-get-items-as-eml' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "41" + scriptarguments: + item-id: + simple: AAMkAGZiODc1MGY3LTBiODEtNDQ3ZC05YzdjLWVkYjhiMjFlMTk1MABGAAAAAAB4Hvam6Pd3Sqro7SBw8T0oBwDj9X3Q04QOTYf/bBd1+UDZAAAAAAEMAADj9X3Q04QOTYf/bBd1+UDZAAAHclB6AAA= + target-mailbox: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 3345 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + "41": + id: "41" + taskid: 0e0078d8-7bed-4443-80ff-f12361f6626b + type: regular + task: + id: 0e0078d8-7bed-4443-80ff-f12361f6626b + version: -1 + name: Get public folder + description: Retrieves a single folder. + script: '|||ews-get-folder' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "39" + scriptarguments: + folder-path: + simple: test_p + is-public: + simple: "True" + target-mailbox: {} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 3520 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 +view: |- + { + "linkLabelsPosition": {}, + "paper": { + "dimensions": { + "height": 3710, + "width": 380, + "x": 50, + "y": 50 + } + } + } +inputs: [] +outputs: [] diff --git a/Packs/EWS/pack_metadata.json b/Packs/EWS/pack_metadata.json index d4d697d9d1e0..f1bf8773b3a7 100644 --- a/Packs/EWS/pack_metadata.json +++ b/Packs/EWS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "EWS", "description": "Exchange Web Services and Office 365 (mail)", "support": "Cortex XSOAR", - "currentVersion": "1.0.1", + "currentVersion": "1.1.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Tests/conf.json b/Tests/conf.json index 9f18602de20c..4735ee3d1426 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -2514,6 +2514,11 @@ "instance_names": "ewv2_regular", "timeout": 1200 }, + { + "integrations": "EWSO365", + "playbookID": "EWS_O365_test", + "fromversion": "5.0.0" + }, { "integrations": "QRadar", "playbookID": "QRadar Indicator Hunting Test", From 1e56e66d51a98c11ec764dc75c9ca83cde0370c7 Mon Sep 17 00:00:00 2001 From: Ika Gabashvili <45535078+IkaDemisto@users.noreply.github.com> Date: Wed, 10 Jun 2020 18:37:17 +0300 Subject: [PATCH 032/200] Removed legacy from special handling in dependencies calculation (#7493) * removed legacy from special handling * fixed unused import --- Tests/Marketplace/packs_dependencies.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Tests/Marketplace/packs_dependencies.py b/Tests/Marketplace/packs_dependencies.py index 2218af8e0826..7356834360e8 100644 --- a/Tests/Marketplace/packs_dependencies.py +++ b/Tests/Marketplace/packs_dependencies.py @@ -1,7 +1,6 @@ import os import json import argparse -import networkx as nx from Tests.Marketplace.upload_packs import PACKS_FULL_PATH, IGNORED_FILES, PACKS_FOLDER from Tests.Marketplace.marketplace_services import GCPConfig from demisto_sdk.commands.find_dependencies.find_dependencies import PackDependencies, parse_for_pack_metadata @@ -46,13 +45,6 @@ def main(): try: dependency_graph = PackDependencies.build_dependency_graph(pack_id=pack.name, id_set=id_set) - # remove Legacy node subtree - if dependency_graph.has_node("Legacy"): - legacy_sub_tree = nx.descendants(dependency_graph, "Legacy") - legacy_sub_tree.add("Legacy") - dependency_graph.remove_nodes_from(legacy_sub_tree) - dependency_graph.remove_nodes_from(list(nx.isolates(dependency_graph))) - # currently all level of dependencies is not in use first_level_dependencies, all_level_dependencies = parse_for_pack_metadata(dependency_graph, pack.name) From 37f8778ad0de0e99f91cdb11af9030a098027bf9 Mon Sep 17 00:00:00 2001 From: reut shalem <50294648+reutshal@users.noreply.github.com> Date: Wed, 10 Jun 2020 19:05:39 +0300 Subject: [PATCH 033/200] test_collect_tests_and_content_packs - Improve packs collecting (#7477) * sdk release 1-1-2 * sdk release 1-1-2 * sdk release 1-1-2 * check docs upload * deleted comments * linting * linting * linting * Fixed UT * Fixed UT * Fixed UT * Fixed UT * Fixed UT * Fixed UT * CR fixes * CR fixes --- .../collect_tests_and_content_packs.py | 51 +++++++++++++++---- .../test_collect_tests_and_content_packs.py | 20 ++++---- 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/Tests/scripts/collect_tests_and_content_packs.py b/Tests/scripts/collect_tests_and_content_packs.py index a71737907f50..e2c3741aab9a 100755 --- a/Tests/scripts/collect_tests_and_content_packs.py +++ b/Tests/scripts/collect_tests_and_content_packs.py @@ -19,7 +19,7 @@ from demisto_sdk.commands.common.constants import * # noqa: E402 from demisto_sdk.commands.common.tools import get_yaml, str2bool, get_from_version, get_to_version, \ collect_ids, get_script_or_integration_id, LOG_COLORS, print_error, print_color, \ - print_warning, server_version_compare # noqa: E402 + print_warning, server_version_compare, get_pack_name # noqa: E402 # Search Keyword for the changed file NO_TESTS_FORMAT = 'No test( - .*)?' @@ -110,7 +110,7 @@ def validate_not_a_package_test_script(file_path): return '_test' not in file_path and 'test_' not in file_path -def get_modified_files(files_string): +def get_modified_files_for_testing(files_string): """Get a string of the modified files""" is_conf_json = False is_reputations_json = False @@ -275,8 +275,7 @@ def collect_tests_and_content_packs( test_playbook_pack = test_playbook_object.get('pack') if test_playbook_pack: print( - f'Found test playbook {test_playbook_id} in pack {test_playbook_pack} - adding to packs to install' - ) + f'Found test playbook {test_playbook_id} in pack {test_playbook_pack} - adding to packs to install') packs_to_install.add(test_playbook_pack) else: print_warning(f'Found test playbook {test_playbook_id} without pack - not adding to packs to install') @@ -867,8 +866,7 @@ def get_test_conf_from_conf(test_id, server_version, conf=None): test_conf.get('playbookID') == test_id and is_runnable_in_server_version(from_v=test_conf.get('fromversion', '0.0'), server_v=server_version, - to_v=test_conf.get('toversion', '99.99.99')) - )), None) + to_v=test_conf.get('toversion', '99.99.99')))), None) return test_conf @@ -1071,17 +1069,42 @@ def get_content_pack_name_of_test(tests: set, id_set: Dict = None) -> set: return content_packs +def get_modified_packs(files_string): + modified_packs = set() + all_files = files_string.splitlines() + + for _file in all_files: + file_data = _file.split() + if not file_data: + continue + file_status = file_data[0] + if file_status.lower().startswith('r'): + file_path = file_data[2] + else: + file_path = file_data[1] + + if file_path.startswith('Documentation'): + modified_packs.add('Base') + + elif file_path.startswith('Packs'): + modified_packs.add(get_pack_name(file_path)) + + return modified_packs + + def get_test_list_and_content_packs_to_install(files_string, branch_name, two_before_ga_ver='0', conf=None, id_set=None): """Create a test list that should run""" - (modified_files, modified_tests_list, changed_common, is_conf_json, sample_tests, is_reputations_json, - is_indicator_json) = get_modified_files(files_string) + + (modified_files_with_relevant_tests, modified_tests_list, changed_common, is_conf_json, sample_tests, + is_reputations_json, + is_indicator_json) = get_modified_files_for_testing(files_string) tests = set([]) packs_to_install = set([]) - if modified_files: - tests, packs_to_install = find_tests_and_content_packs_for_modified_files(modified_files, conf, id_set) - + if modified_files_with_relevant_tests: + tests, packs_to_install = find_tests_and_content_packs_for_modified_files(modified_files_with_relevant_tests, + conf, id_set) # Adding a unique test for a json file. if is_reputations_json: tests.add('FormattingPerformance - Test') @@ -1117,6 +1140,11 @@ def get_test_list_and_content_packs_to_install(files_string, branch_name, two_be if changed_common: tests.add('TestCommonPython') + # get all modified packs - not just tests related + modified_packs = get_modified_packs(files_string) + if modified_packs: + packs_to_install = packs_to_install.union(modified_packs) + if 'NonSupported' in packs_to_install: packs_to_install.remove("NonSupported") @@ -1152,6 +1180,7 @@ def create_test_file(is_nightly, skip_save=False): print("Getting changed files from the branch: {0}".format(branch_name)) if branch_name != 'master': files_string = tools.run_command("git diff --name-status origin/master...{0}".format(branch_name)) + else: commit_string = tools.run_command("git log -n 2 --pretty='%H'") commit_string = commit_string.replace("'", "") diff --git a/Tests/scripts/infrastructure_tests/test_collect_tests_and_content_packs.py b/Tests/scripts/infrastructure_tests/test_collect_tests_and_content_packs.py index be804c9406cc..f36560dacc52 100644 --- a/Tests/scripts/infrastructure_tests/test_collect_tests_and_content_packs.py +++ b/Tests/scripts/infrastructure_tests/test_collect_tests_and_content_packs.py @@ -6,7 +6,7 @@ from ruamel.yaml import YAML from Tests.scripts.collect_tests_and_content_packs import ( - RANDOM_TESTS_NUM, TestConf, create_filter_envs_file, get_modified_files, + RANDOM_TESTS_NUM, TestConf, create_filter_envs_file, get_modified_files_for_testing, get_test_list_and_content_packs_to_install, collect_content_packs_to_install) with open('Tests/scripts/infrastructure_tests/tests_data/mock_id_set.json', 'r') as mock_id_set_f: @@ -116,7 +116,7 @@ def create_test_playbook(name, with_scripts=None, with_integration_commands=None @staticmethod def mock_get_modified_files(mocker, modified_files_list, is_conf_json=False): - return mocker.patch('Tests.scripts.collect_tests_and_content_packs.get_modified_files', + return mocker.patch('Tests.scripts.collect_tests_and_content_packs.get_modified_files_for_testing', return_value=create_get_modified_files_ret( modified_files_list=modified_files_list, is_conf_json=is_conf_json @@ -182,7 +182,7 @@ def test_changed_runnable_test__unmocked_get_modified_files(self): filterd_tests, content_packs = get_mock_test_list(git_diff_ret=self.GIT_DIFF_RET) assert filterd_tests == {self.TEST_ID} - assert content_packs == set() + assert content_packs == {"CommonPlaybooks"} class TestChangedTestPlaybook: @@ -194,7 +194,7 @@ def test_changed_runnable_test__unmocked_get_modified_files(self): filterd_tests, content_packs = get_mock_test_list(git_diff_ret=self.GIT_DIFF_RET) assert filterd_tests == {self.TEST_ID} - assert content_packs == set() + assert content_packs == {"EWS"} def test_changed_runnable_test__mocked_get_modified_files(self, mocker): # fake_test_playbook is fromversion 4.1.0 in playbook file @@ -337,7 +337,7 @@ def test_changed_runnable_test__unmocked_get_modified_files(self): filterd_tests, content_packs = get_mock_test_list(git_diff_ret=self.GIT_DIFF_RET) assert filterd_tests == {self.TEST_ID} - assert content_packs == set() + assert content_packs == {"PagerDuty"} def test_changed_unrunnable_test__integration_toversion(self, mocker): test_id = 'past_test_playbook_1' @@ -362,7 +362,7 @@ def test_changed_runnable_test__unmocked_get_modified_files(self): filterd_tests, content_packs = get_mock_test_list(git_diff_ret=self.GIT_DIFF_RET) assert filterd_tests == set(self.TEST_ID.split('\n')) - assert content_packs == set() + assert content_packs == {'CommonPlaybooks', 'PagerDuty'} class TestChangedScript: @@ -374,7 +374,7 @@ def test_changed_runnable_test__unmocked_get_modified_files(self): filterd_tests, content_packs = get_mock_test_list(git_diff_ret=self.GIT_DIFF_RET) assert filterd_tests == {self.TEST_ID} - assert content_packs == set() + assert content_packs == {"CommonScripts"} def test_changed_unrunnable_test__integration_toversion(self, mocker): test_id = 'past_test_playbook_2' @@ -427,7 +427,7 @@ def test_all_tests(self): filterd_tests, content_packs = get_mock_test_list(git_diff_ret=self.GIT_DIFF_RET) assert len(filterd_tests) >= RANDOM_TESTS_NUM - assert content_packs == {'fake_pack'} + assert content_packs == {'Base', 'fake_pack'} class TestPackageFilesModified: @@ -441,7 +441,7 @@ class TestPackageFilesModified: def test_changed_runnable_test__unmocked_get_modified_files(self): files_list, tests_list, all_tests, is_conf_json, sample_tests, is_reputations_json, is_indicator_json = \ - get_modified_files(self.GIT_DIFF_RET) + get_modified_files_for_testing(self.GIT_DIFF_RET) assert len(sample_tests) == 0 assert 'Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.yml' in files_list @@ -479,7 +479,7 @@ def get_mock_test_list(two_before_ga=TWO_BEFORE_GA_VERSION, get_modified_files_r branch_name = 'BranchA' if get_modified_files_ret is not None: mocker.patch( - 'Tests.scripts.collect_tests_and_content_packs.get_modified_files', + 'Tests.scripts.collect_tests_and_content_packs.get_modified_files_for_testing', return_value=get_modified_files_ret ) tests, content_packs = get_test_list_and_content_packs_to_install( From 042db02b0d3f169b214f148e6d605d8654d0ce99 Mon Sep 17 00:00:00 2001 From: Anar Azadaliyev Date: Wed, 10 Jun 2020 22:47:34 +0300 Subject: [PATCH 034/200] Move default types to content (#7426) * move system incident types to content * add release notes * moved types to correct packs * updated pack versions * add DefaultPlaybook to core packs * update version --- .../IncidentTypes/incidenttype-Access.json | 27 +++++++++++ .../AccessInvestigation/ReleaseNotes/1_1_2.md | 5 +++ Packs/AccessInvestigation/pack_metadata.json | 30 ++++++------- .../incidenttype-Authentication.json | 26 +++++++++++ .../incidenttype-C2Communication.json | 26 +++++++++++ .../incidenttype-Defacement.json | 26 +++++++++++ .../IncidentTypes/incidenttype-DoS.json | 26 +++++++++++ .../incidenttype-Exfiltration.json | 26 +++++++++++ .../IncidentTypes/incidenttype-Exploit.json | 26 +++++++++++ .../IncidentTypes/incidenttype-Hunt.json | 26 +++++++++++ .../IncidentTypes/incidenttype-Job.json | 25 +++++++++++ .../incidenttype-Lateral_Movement.json | 26 +++++++++++ .../IncidentTypes/incidenttype-Network.json | 26 +++++++++++ .../incidenttype-Policy_Violation.json | 26 +++++++++++ .../incidenttype-Reconnaissance.json | 26 +++++++++++ .../incidenttype-Simulation.json | 26 +++++++++++ .../incidenttype-UnknownBinary.json | 26 +++++++++++ .../incidenttype-Vulnerability.json | 26 +++++++++++ Packs/CommonTypes/ReleaseNotes/1_1_0.md | 45 +++++++++++++++++++ Packs/CommonTypes/pack_metadata.json | 2 +- .../incidenttype-DeviceLost.json | 27 +++++++++++ .../Lost_Stolen_Device/ReleaseNotes/1_0_1.md | 5 +++ Packs/Lost_Stolen_Device/pack_metadata.json | 14 ++++-- .../IncidentTypes/incidenttype-Malware.json | 27 +++++++++++ Packs/Malware/ReleaseNotes/1_0_2.md | 5 +++ Packs/Malware/pack_metadata.json | 2 +- .../IncidentTypes/incidenttype-Phishing.json | 27 +++++++++++ Packs/Phishing/ReleaseNotes/1_2_1.md | 5 +++ Packs/Phishing/pack_metadata.json | 44 +++++++++--------- .../incidenttype-Ransomware.json | 27 +++++++++++ Packs/Ransomware/ReleaseNotes/1_0_2.md | 5 +++ Packs/Ransomware/pack_metadata.json | 2 +- Tests/Marketplace/marketplace_services.py | 3 +- 33 files changed, 646 insertions(+), 45 deletions(-) create mode 100644 Packs/AccessInvestigation/IncidentTypes/incidenttype-Access.json create mode 100644 Packs/AccessInvestigation/ReleaseNotes/1_1_2.md create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Authentication.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-C2Communication.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Defacement.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-DoS.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Exfiltration.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Exploit.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Hunt.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Job.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Lateral_Movement.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Network.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Policy_Violation.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Reconnaissance.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Simulation.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-UnknownBinary.json create mode 100644 Packs/CommonTypes/IncidentTypes/incidenttype-Vulnerability.json create mode 100644 Packs/CommonTypes/ReleaseNotes/1_1_0.md create mode 100644 Packs/Lost_Stolen_Device/IncidentTypes/incidenttype-DeviceLost.json create mode 100644 Packs/Lost_Stolen_Device/ReleaseNotes/1_0_1.md create mode 100644 Packs/Malware/IncidentTypes/incidenttype-Malware.json create mode 100644 Packs/Malware/ReleaseNotes/1_0_2.md create mode 100644 Packs/Phishing/IncidentTypes/incidenttype-Phishing.json create mode 100644 Packs/Phishing/ReleaseNotes/1_2_1.md create mode 100644 Packs/Ransomware/IncidentTypes/incidenttype-Ransomware.json create mode 100644 Packs/Ransomware/ReleaseNotes/1_0_2.md diff --git a/Packs/AccessInvestigation/IncidentTypes/incidenttype-Access.json b/Packs/AccessInvestigation/IncidentTypes/incidenttype-Access.json new file mode 100644 index 000000000000..e71641feabc7 --- /dev/null +++ b/Packs/AccessInvestigation/IncidentTypes/incidenttype-Access.json @@ -0,0 +1,27 @@ +{ + "id": "Access", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Access", + "prevName": "", + "playbookId": "access_investigation_-_generic", + "color": "#B287FE", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/AccessInvestigation/ReleaseNotes/1_1_2.md b/Packs/AccessInvestigation/ReleaseNotes/1_1_2.md new file mode 100644 index 000000000000..8327a3b64eb1 --- /dev/null +++ b/Packs/AccessInvestigation/ReleaseNotes/1_1_2.md @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/Packs/AccessInvestigation/pack_metadata.json b/Packs/AccessInvestigation/pack_metadata.json index a9b2d68d7430..adfed798b3ec 100644 --- a/Packs/AccessInvestigation/pack_metadata.json +++ b/Packs/AccessInvestigation/pack_metadata.json @@ -1,16 +1,16 @@ -{ - "name": "Access Investigation", - "description": "Investigates an access incident by gathering user and IP information and interacting with the user to confirm whether or not they initiated the access action.", - "support": "xsoar", - "currentVersion": "1.1.1", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-05-25T10:39:08Z", - "categories": [ - "Network Security" - ], - "tags": [], - "useCases": ["Access"], - "keywords": [] +{ + "name": "Access Investigation", + "description": "Investigates an access incident by gathering user and IP information and interacting with the user to confirm whether or not they initiated the access action.", + "support": "xsoar", + "currentVersion": "1.1.2", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-05-25T10:39:08Z", + "categories": [ + "Network Security" + ], + "tags": [], + "useCases": ["Access"], + "keywords": [] } \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Authentication.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Authentication.json new file mode 100644 index 000000000000..7543a3a3d640 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Authentication.json @@ -0,0 +1,26 @@ +{ + "id": "Authentication", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Authentication", + "prevName": "", + "color": "#8052F3", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-C2Communication.json b/Packs/CommonTypes/IncidentTypes/incidenttype-C2Communication.json new file mode 100644 index 000000000000..719292a0009f --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-C2Communication.json @@ -0,0 +1,26 @@ +{ + "id": "C2Communication", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "C2Communication", + "prevName": "", + "color": "#C2195B", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": true, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Defacement.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Defacement.json new file mode 100644 index 000000000000..15e38986c056 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Defacement.json @@ -0,0 +1,26 @@ +{ + "id": "Defacement", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Defacement", + "prevName": "", + "color": "#FA99D0", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-DoS.json b/Packs/CommonTypes/IncidentTypes/incidenttype-DoS.json new file mode 100644 index 000000000000..0c40c56f6eb1 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-DoS.json @@ -0,0 +1,26 @@ +{ + "id": "DoS", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "DoS", + "prevName": "", + "color": "#00C853", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Exfiltration.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Exfiltration.json new file mode 100644 index 000000000000..7077fe47cce5 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Exfiltration.json @@ -0,0 +1,26 @@ +{ + "id": "Exfiltration", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Exfiltration", + "prevName": "", + "color": "#1EE8B5", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Exploit.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Exploit.json new file mode 100644 index 000000000000..6bc835418981 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Exploit.json @@ -0,0 +1,26 @@ +{ + "id": "Exploit", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Exploit", + "prevName": "", + "color": "#2979FF", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Hunt.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Hunt.json new file mode 100644 index 000000000000..962f70a3986d --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Hunt.json @@ -0,0 +1,26 @@ +{ + "id": "Hunt", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Hunt", + "prevName": "", + "color": "#FE2C8C", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Job.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Job.json new file mode 100644 index 000000000000..4035e5f994cc --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Job.json @@ -0,0 +1,25 @@ +{ + "id": "Job", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Job", + "prevName": "", + "color": "#FF1D1E", + "hours": 0, + "days": 0, + "weeks": 0, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": true, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Lateral_Movement.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Lateral_Movement.json new file mode 100644 index 000000000000..a1c63620bb1a --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Lateral_Movement.json @@ -0,0 +1,26 @@ +{ + "id": "Lateral Movement", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Lateral Movement", + "prevName": "", + "color": "#FF6318", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Network.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Network.json new file mode 100644 index 000000000000..9e810213115e --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Network.json @@ -0,0 +1,26 @@ +{ + "id": "Network", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Network", + "prevName": "", + "color": "#FDE42E", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Policy_Violation.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Policy_Violation.json new file mode 100644 index 000000000000..acb90ca9a1d2 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Policy_Violation.json @@ -0,0 +1,26 @@ +{ + "id": "Policy Violation", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Policy Violation", + "prevName": "", + "color": "#0097A7", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Reconnaissance.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Reconnaissance.json new file mode 100644 index 000000000000..6f04def920fe --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Reconnaissance.json @@ -0,0 +1,26 @@ +{ + "id": "Reconnaissance", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Reconnaissance", + "prevName": "", + "color": "#3F51B5", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Simulation.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Simulation.json new file mode 100644 index 000000000000..f28592a50c9b --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Simulation.json @@ -0,0 +1,26 @@ +{ + "id": "Simulation", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Simulation", + "prevName": "", + "color": "#F9FF10", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-UnknownBinary.json b/Packs/CommonTypes/IncidentTypes/incidenttype-UnknownBinary.json new file mode 100644 index 000000000000..e6f2ecb0a158 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-UnknownBinary.json @@ -0,0 +1,26 @@ +{ + "id": "UnknownBinary", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "UnknownBinary", + "prevName": "", + "color": "#FE2CD6", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentTypes/incidenttype-Vulnerability.json b/Packs/CommonTypes/IncidentTypes/incidenttype-Vulnerability.json new file mode 100644 index 000000000000..ab0c6e1b23c6 --- /dev/null +++ b/Packs/CommonTypes/IncidentTypes/incidenttype-Vulnerability.json @@ -0,0 +1,26 @@ +{ + "id": "Vulnerability", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Vulnerability", + "prevName": "", + "color": "#81D4FA", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/ReleaseNotes/1_1_0.md b/Packs/CommonTypes/ReleaseNotes/1_1_0.md new file mode 100644 index 000000000000..1c69f8fa5193 --- /dev/null +++ b/Packs/CommonTypes/ReleaseNotes/1_1_0.md @@ -0,0 +1,45 @@ +### IncidentTypes +Moved all system incident types to content. + \ No newline at end of file diff --git a/Packs/CommonTypes/pack_metadata.json b/Packs/CommonTypes/pack_metadata.json index 006a66cc88ff..8bdcc16d4ca6 100644 --- a/Packs/CommonTypes/pack_metadata.json +++ b/Packs/CommonTypes/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Types", "description": "Common types pack.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "1.1.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Lost_Stolen_Device/IncidentTypes/incidenttype-DeviceLost.json b/Packs/Lost_Stolen_Device/IncidentTypes/incidenttype-DeviceLost.json new file mode 100644 index 000000000000..9388af9aefc9 --- /dev/null +++ b/Packs/Lost_Stolen_Device/IncidentTypes/incidenttype-DeviceLost.json @@ -0,0 +1,27 @@ +{ + "id": "DeviceLost", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "DeviceLost", + "prevName": "", + "color": "#ADE901", + "playbookId": "playbook8", + "sla": 240, + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Lost_Stolen_Device/ReleaseNotes/1_0_1.md b/Packs/Lost_Stolen_Device/ReleaseNotes/1_0_1.md new file mode 100644 index 000000000000..951012783e59 --- /dev/null +++ b/Packs/Lost_Stolen_Device/ReleaseNotes/1_0_1.md @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/Packs/Lost_Stolen_Device/pack_metadata.json b/Packs/Lost_Stolen_Device/pack_metadata.json index 16f58fd738b2..71a7b4da77e4 100644 --- a/Packs/Lost_Stolen_Device/pack_metadata.json +++ b/Packs/Lost_Stolen_Device/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Lost / Stolen Device", "description": "This manaul playbook handles lost or stolen device. it will guide the analyst troght the various steps to validate the type and the content on the device and required stetps for the response and remidiation process", "support": "xsoar", - "currentVersion": "1.0.0", + "currentVersion": "1.0.1", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -11,6 +11,12 @@ "Utilities" ], "tags": [], - "useCases": ["Stolen Device","Lost Device"], - "keywords": ["Stolen Device","Lost Device"] -} + "useCases": [ + "Stolen Device", + "Lost Device" + ], + "keywords": [ + "Stolen Device", + "Lost Device" + ] +} \ No newline at end of file diff --git a/Packs/Malware/IncidentTypes/incidenttype-Malware.json b/Packs/Malware/IncidentTypes/incidenttype-Malware.json new file mode 100644 index 000000000000..3da2618112de --- /dev/null +++ b/Packs/Malware/IncidentTypes/incidenttype-Malware.json @@ -0,0 +1,27 @@ +{ + "id": "Malware", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Malware", + "prevName": "", + "color": "#FF8F14", + "sla": 240, + "playbookId": "", + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Malware/ReleaseNotes/1_0_2.md b/Packs/Malware/ReleaseNotes/1_0_2.md new file mode 100644 index 000000000000..234014a8f30f --- /dev/null +++ b/Packs/Malware/ReleaseNotes/1_0_2.md @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/Packs/Malware/pack_metadata.json b/Packs/Malware/pack_metadata.json index 34eb2166a46b..b5639f7a4c43 100644 --- a/Packs/Malware/pack_metadata.json +++ b/Packs/Malware/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Malware", "description": "This pack includes Endpoint Malware use-case artifacts.", "support": "xsoar", - "currentVersion": "1.0.1", + "currentVersion": "1.0.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "created": "2020-05-18T10:35:29Z", diff --git a/Packs/Phishing/IncidentTypes/incidenttype-Phishing.json b/Packs/Phishing/IncidentTypes/incidenttype-Phishing.json new file mode 100644 index 000000000000..96fedfefeeae --- /dev/null +++ b/Packs/Phishing/IncidentTypes/incidenttype-Phishing.json @@ -0,0 +1,27 @@ +{ + "id": "Phishing", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Phishing", + "prevName": "", + "color": "#3AD1D6", + "sla": 240, + "playbookId": "playbook2", + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Phishing/ReleaseNotes/1_2_1.md b/Packs/Phishing/ReleaseNotes/1_2_1.md new file mode 100644 index 000000000000..8edeffa2afca --- /dev/null +++ b/Packs/Phishing/ReleaseNotes/1_2_1.md @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/Packs/Phishing/pack_metadata.json b/Packs/Phishing/pack_metadata.json index 0c60cad4f93b..01f17214e60f 100644 --- a/Packs/Phishing/pack_metadata.json +++ b/Packs/Phishing/pack_metadata.json @@ -1,23 +1,23 @@ -{ - "name": "Phishing", - "description": "A solution for the investingation of phishing incidents.", - "support": "xsoar", - "currentVersion": "1.2.0", - "author": "Cortex XSOAR", - "url": "https://www.paloaltonetworks.com/cortex", - "email": "", - "created": "2020-05-12T10:55:43Z", - "categories": [ - "Messaging" - ], - "tags": [ - "Phishing", - "Scam", - "Email", - "Spam" - ], - "useCases": [ - "Phishing" - ], - "keywords": [] +{ + "name": "Phishing", + "description": "A solution for the investingation of phishing incidents.", + "support": "xsoar", + "currentVersion": "1.2.1", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2020-05-12T10:55:43Z", + "categories": [ + "Messaging" + ], + "tags": [ + "Phishing", + "Scam", + "Email", + "Spam" + ], + "useCases": [ + "Phishing" + ], + "keywords": [] } \ No newline at end of file diff --git a/Packs/Ransomware/IncidentTypes/incidenttype-Ransomware.json b/Packs/Ransomware/IncidentTypes/incidenttype-Ransomware.json new file mode 100644 index 000000000000..63ff9ccd1b25 --- /dev/null +++ b/Packs/Ransomware/IncidentTypes/incidenttype-Ransomware.json @@ -0,0 +1,27 @@ +{ + "id": "Ransomware", + "version": -1, + "sortValues": null, + "vcShouldIgnore": false, + "locked": false, + "name": "Ransomware", + "prevName": "", + "color": "#AA00FF", + "sla": 240, + "playbookId": "playbook3", + "hours": 0, + "days": 3, + "weeks": 1, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Ransomware/ReleaseNotes/1_0_2.md b/Packs/Ransomware/ReleaseNotes/1_0_2.md new file mode 100644 index 000000000000..8505f72259e7 --- /dev/null +++ b/Packs/Ransomware/ReleaseNotes/1_0_2.md @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/Packs/Ransomware/pack_metadata.json b/Packs/Ransomware/pack_metadata.json index 9c3656183c16..5dedfd659bbe 100644 --- a/Packs/Ransomware/pack_metadata.json +++ b/Packs/Ransomware/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Ransomware", "description": "A pack used to investigate ransomware incidents.", "support": "xsoar", - "currentVersion": "1.0.1", + "currentVersion": "1.0.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Tests/Marketplace/marketplace_services.py b/Tests/Marketplace/marketplace_services.py index 2f52efe3b30a..5c78a653806c 100644 --- a/Tests/Marketplace/marketplace_services.py +++ b/Tests/Marketplace/marketplace_services.py @@ -59,7 +59,8 @@ class GCPConfig(object): "CommonWidgets", "TIM_Processing", "TIM_SIEM", - "HelloWorld" + "HelloWorld", + "DefaultPlaybook" ] # cores packs list From 6353aac2ef721b8addd5856b801a3e601d994780 Mon Sep 17 00:00:00 2001 From: Guy Lichtman <1395797+glicht@users.noreply.github.com> Date: Thu, 11 Jun 2020 00:27:06 +0300 Subject: [PATCH 035/200] Docs: remove possible errors section (#7381) * Maltiverse: remove possible errors section * remove troubleshooting and overview * Update README.md * update zabbix --- Packs/Claroty/Integrations/Claroty/README.md | 17 +---------------- .../Integrations/Maltiverse/README.md | 12 ------------ Packs/Zabbix/Integrations/Zabbix/README.md | 9 +-------- 3 files changed, 2 insertions(+), 36 deletions(-) diff --git a/Packs/Claroty/Integrations/Claroty/README.md b/Packs/Claroty/Integrations/Claroty/README.md index 051434fd5720..ba2d6ae9c13a 100644 --- a/Packs/Claroty/Integrations/Claroty/README.md +++ b/Packs/Claroty/Integrations/Claroty/README.md @@ -1,8 +1,6 @@ -## Overview ---- - Use the Claroty CTD integration to manage assets and alerts. This integration was integrated and tested with version 4.0.1 of Claroty + ## Claroty Playbook Playbook 1: OT Asset Discovery Maintaining an accurate enterprise asset database is extremely difficult, @@ -537,16 +535,3 @@ Admin user. |AlertType|AlertTypeID|Category|Description|Indicator|NetworkID|RelatedAssets|Resolved|ResourceID|Severity| |---|---|---|---|---|---|---|---|---|---| | PortScan | 28 | Integrity | UDP Port scan: Asset 192.168.1.10 sent probe packets to 192.168.1.25 IP address on different ports | Alert ID - 75
    Description - This Event does not currently support Alert Indicators
    Points - 100

    | 1 | {'AssetID': 47, 'Name': '192.168.1.10', 'InsightName': None, 'Vendor': 'Hewlett Packard', 'Criticality': 'Low', 'AssetType': 'Endpoint', 'LastSeen': None, 'IP': None, 'MAC': ['00:1A:4B:6A:CE:FE'], 'VirtualZone': 'Endpoint: Other', 'ClassType': 'IT', 'SiteName': 'site-1', 'SiteID': 1, 'WasParsed': None, 'RiskLevel': 0, 'FirmwareVersion': None, 'ResourceID': '47-1'},
    {'AssetID': 48, 'Name': '192.168.1.25', 'InsightName': None, 'Vendor': 'VMware', 'Criticality': 'Low', 'AssetType': 'Endpoint', 'LastSeen': None, 'IP': None, 'MAC': ['00:0C:29:86:C8:36'], 'VirtualZone': 'Endpoint: Other', 'ClassType': 'IT', 'SiteName': 'site-1', 'SiteID': 1, 'WasParsed': None, 'RiskLevel': 0, 'FirmwareVersion': None, 'ResourceID': '48-1'} | false | 75-1 | Critical | - - -## Additional Information ---- - -## Known Limitations ---- - -## Troubleshooting ---- - - -## Possible Errors (DO NOT PUBLISH ON ZENDESK): diff --git a/Packs/Maltiverse/Integrations/Maltiverse/README.md b/Packs/Maltiverse/Integrations/Maltiverse/README.md index 24f68b93e350..c90cc9d4169d 100644 --- a/Packs/Maltiverse/Integrations/Maltiverse/README.md +++ b/Packs/Maltiverse/Integrations/Maltiverse/README.md @@ -1,6 +1,3 @@ -## Overview ---- - Analyze suspicious hashes, URLs, domains and IP addresses This integration was integrated and tested with version 1.0.0-oas3 of Maltiverse @@ -248,12 +245,3 @@ For additional information please visit: https://whatis.maltiverse.com/ Please see https://maltiverse.com/plans for more information about the different plans. - URL command: When running the !url command, an URL may be followed by a '/' at the end. Maltiverse requires this '/' but it might cause the indicator to not show in the war room. - -## Troubleshooting ---- - - -## Possible Errors (DO NOT PUBLISH ON ZENDESK): -* 'The given IP was invalid' -* 'Command not found.' -* f'Failed to execute {command} command. Error: {e}' diff --git a/Packs/Zabbix/Integrations/Zabbix/README.md b/Packs/Zabbix/Integrations/Zabbix/README.md index 2110268ce4b8..a11c157f4ece 100644 --- a/Packs/Zabbix/Integrations/Zabbix/README.md +++ b/Packs/Zabbix/Integrations/Zabbix/README.md @@ -1,8 +1,6 @@ -## Overview ---- - Allow integration with Zabbix api This integration was integrated and tested with version xx of Zabbix + ## Zabbix Playbook --- @@ -593,8 +591,3 @@ No current known limitations ## Troubleshooting Verify if the user has the necessary permissions to execute the operation - - -## Possible Errors (DO NOT PUBLISH ON ZENDESK): -* "Unknown command " + command -* Generic error From d1058c413dea7eee2282c5e803d85c8b98b2d730 Mon Sep 17 00:00:00 2001 From: Bar Katzir <37335599+bakatzir@users.noreply.github.com> Date: Thu, 11 Jun 2020 12:15:05 +0300 Subject: [PATCH 036/200] Securonix already fetched (#7025) * securonix fetch offset * changelog * Added max parameter to the `securonix-list-incidents` command Added the `max_fetch` parameter to the integration configuration, where the default and maximum value is 50. Fixed an issue where duplicate incidents where fetched. * linter 101 * linter 102 * linter 103 * set -> list, dumps the already_fetched * update RN and README * update dockerimage * Update Packs/Securonix/Integrations/Securonix/CHANGELOG.md Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> * Update Packs/Securonix/Integrations/Securonix/README.md Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> * Update Packs/Securonix/Integrations/Securonix/README.md Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> * Update Packs/Securonix/Integrations/Securonix/Securonix.yml Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> --- .../Integrations/Securonix/CHANGELOG.md | 4 +- .../Integrations/Securonix/README.md | 8 ++-- .../Integrations/Securonix/Securonix.py | 43 +++++++++++------- .../Integrations/Securonix/Securonix.yml | 14 +++++- .../Integrations/Securonix/Securonix_test.py | 45 ++++++++++++++++++- .../Securonix/test_data/response_constants.py | 27 +++++++++++ Packs/Securonix/ReleaseNotes/1_1_0.md | 6 +++ Packs/Securonix/pack_metadata.json | 30 ++++++------- 8 files changed, 140 insertions(+), 37 deletions(-) create mode 100644 Packs/Securonix/ReleaseNotes/1_1_0.md diff --git a/Packs/Securonix/Integrations/Securonix/CHANGELOG.md b/Packs/Securonix/Integrations/Securonix/CHANGELOG.md index 98a58d807a56..389bd3466f26 100644 --- a/Packs/Securonix/Integrations/Securonix/CHANGELOG.md +++ b/Packs/Securonix/Integrations/Securonix/CHANGELOG.md @@ -1,5 +1,7 @@ ## [Unreleased] - + - Added the `max` parameter to the `securonix-list-incidents` command. + - Added the `max_fetch` parameter to the integration configuration, where the default and maximum value is 50. + - Fixed an issue where duplicate incidents where fetched. ## [20.4.1] - 2020-04-29 - Added the *action_parameters* argument to the ***securonix-perform-action-on-incident*** command. diff --git a/Packs/Securonix/Integrations/Securonix/README.md b/Packs/Securonix/Integrations/Securonix/README.md index df5cacf72fc1..d499cd4f86d6 100644 --- a/Packs/Securonix/Integrations/Securonix/README.md +++ b/Packs/Securonix/Integrations/Securonix/README.md @@ -1,6 +1,6 @@ ## Overview Use the Securonix integration to manage incidents and watchlists. -Integration was built and tested with SNYPR Versions: 6.2, 6.3. +Integration was built and tested with SNYPR Versions: 6.2, 6.3, 6.3.1. This integration supports both cloud and on-prem instances of Securonix. To configure a cloud base instance use the *tenant* parameter only. @@ -22,6 +22,7 @@ For more information, visit: `securonix/etnants//securonix_home/resp | incident_status | Incidents to fetch | False | | incidentType | Incident type | False | | fetch_time | First fetch time range (`