From 819dd60f646f22faa106044fe0011dcead0a66f1 Mon Sep 17 00:00:00 2001 From: Ankita Sharma Date: Fri, 29 Oct 2021 17:18:47 +0530 Subject: [PATCH 1/9] Armorblox Cortex Integration Initial Commit for Cortex Integration Added README Deleted www from Armorblox url Addition of a new command to check remediation actions Added playbook and changes Removal of extra space in Armorblox Outbound Threat and renaming MailBox to Mailbox in Armorblox Abuse MailBox Threat Removed default tenant name Added changes for testing script Removed MailBox incident type Removed unwanted Threat(MailBox and Armorblox Outbound) from mapper added github users in pack metadata Co-authored-by: Rajat Upadhyaya <45485+urajat@users.noreply.github.com> --- Packs/Armorblox/.pack-ignore | 0 Packs/Armorblox/.secrets-ignore | 0 Packs/Armorblox/Author_image.png | Bin 0 -> 5283 bytes .../classifier-Armorblox_-_Classifier.json | 62 ++++ .../classifier-Armorblox_-_Mapper.json | 326 ++++++++++++++++++ .../incidentfield-Armorblox_Incident_Id.json | 32 ++ .../incidentfield-Armorblox_Policy_Names.json | 32 ++ ...ntfield-Armorblox_Remediation_Actions.json | 32 ++ ...identfield-Armorblox_Resolution_State.json | 32 ++ .../incidentfield-Armorblox_Subject.json | 32 ++ .../IncidentTypes/incidenttype-Armorblox.json | 27 ++ ...nttype-Armorblox_Abuse_Mailbox_Report.json | 27 ++ ...incidenttype-Armorblox_Inbound_Threat.json | 27 ++ ...ncidenttype-Armorblox_Outbound_Threat.json | 27 ++ .../Integrations/Armorblox/Armorblox.py | 243 +++++++++++++ .../Integrations/Armorblox/Armorblox.yml | 84 +++++ .../Armorblox/Armorblox_description.md | 9 + .../Armorblox/Armorblox_image.png | Bin 0 -> 5283 bytes .../Integrations/Armorblox/Armorblox_test.py | 97 ++++++ .../Integrations/Armorblox/README.md | 78 +++++ .../Integrations/Armorblox/command_examples | 1 + .../test_get_incident_message_ids.json | 66 ++++ .../test_get_remediation_action.json | 66 ++++ .../Playbooks/Armorblox_Needs_Review.yml | 237 +++++++++++++ .../Armorblox_Needs_Review_README.md | 39 +++ ...Armorblox_Needs_Review_Thu_Nov_11_2021.png | Bin 0 -> 53542 bytes Packs/Armorblox/README.md | 14 + .../ArmorbloxSendEmail/ArmorbloxSendEmail.py | 90 +++++ .../ArmorbloxSendEmail/ArmorbloxSendEmail.yml | 43 +++ .../Scripts/ArmorbloxSendEmail/README.md | 27 ++ Packs/Armorblox/pack_metadata.json | 20 ++ 31 files changed, 1770 insertions(+) create mode 100644 Packs/Armorblox/.pack-ignore create mode 100644 Packs/Armorblox/.secrets-ignore create mode 100644 Packs/Armorblox/Author_image.png create mode 100644 Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json create mode 100644 Packs/Armorblox/Classifiers/classifier-Armorblox_-_Mapper.json create mode 100644 Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Incident_Id.json create mode 100644 Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Policy_Names.json create mode 100644 Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Remediation_Actions.json create mode 100644 Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Resolution_State.json create mode 100644 Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Subject.json create mode 100644 Packs/Armorblox/IncidentTypes/incidenttype-Armorblox.json create mode 100644 Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Abuse_Mailbox_Report.json create mode 100644 Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Inbound_Threat.json create mode 100644 Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Outbound_Threat.json create mode 100644 Packs/Armorblox/Integrations/Armorblox/Armorblox.py create mode 100644 Packs/Armorblox/Integrations/Armorblox/Armorblox.yml create mode 100644 Packs/Armorblox/Integrations/Armorblox/Armorblox_description.md create mode 100644 Packs/Armorblox/Integrations/Armorblox/Armorblox_image.png create mode 100644 Packs/Armorblox/Integrations/Armorblox/Armorblox_test.py create mode 100644 Packs/Armorblox/Integrations/Armorblox/README.md create mode 100644 Packs/Armorblox/Integrations/Armorblox/command_examples create mode 100644 Packs/Armorblox/Integrations/Armorblox/test_data/test_get_incident_message_ids.json create mode 100644 Packs/Armorblox/Integrations/Armorblox/test_data/test_get_remediation_action.json create mode 100644 Packs/Armorblox/Playbooks/Armorblox_Needs_Review.yml create mode 100644 Packs/Armorblox/Playbooks/Armorblox_Needs_Review_README.md create mode 100644 Packs/Armorblox/Playbooks/doc_files/Armorblox_Needs_Review_Thu_Nov_11_2021.png create mode 100644 Packs/Armorblox/README.md create mode 100644 Packs/Armorblox/Scripts/ArmorbloxSendEmail/ArmorbloxSendEmail.py create mode 100644 Packs/Armorblox/Scripts/ArmorbloxSendEmail/ArmorbloxSendEmail.yml create mode 100644 Packs/Armorblox/Scripts/ArmorbloxSendEmail/README.md create mode 100644 Packs/Armorblox/pack_metadata.json diff --git a/Packs/Armorblox/.pack-ignore b/Packs/Armorblox/.pack-ignore new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/Packs/Armorblox/.secrets-ignore b/Packs/Armorblox/.secrets-ignore new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/Packs/Armorblox/Author_image.png b/Packs/Armorblox/Author_image.png new file mode 100644 index 0000000000000000000000000000000000000000..6a01966126c4f45324872a7058e453b1bdea6e87 GIT binary patch literal 5283 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 literal 0 HcmV?d00001 diff --git a/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json b/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json new file mode 100644 index 000000000000..d535a38ae2ff --- /dev/null +++ b/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Classifier.json @@ -0,0 +1,62 @@ +{ + "defaultIncidentType": "Armorblox", + "description": "Classifies Armorblox Incidents.", + "feed": false, + "id": "e8ded555-9409-4d33-842c-45d29b6ab31c", + "keyTypeMap": { + "Abuse Report": "Armorblox Abuse Mailbox Report", + "Extortion": "Armorblox Inbound Threat", + "Graymail": "Armorblox Inbound Threat", + "Impersonation: Employee": "Armorblox Inbound Threat", + "Impersonation: VIP": "Armorblox Inbound Threat", + "Impersonation: VIP (Requesting Gift Card)": "Armorblox Inbound Threat", + "Impersonation:Employee": "Armorblox Inbound Threat", + "Impersonation:VIP": "Armorblox Inbound Threat", + "PCI Bank Account Number": "Armorblox Outbound Threat", + "PCI Credit Card Number": "Armorblox Outbound Threat", + "PCI IBAN": "Armorblox Outbound Threat", + "PCI Routing Number": "Armorblox Outbound Threat", + "PII Passport": "Armorblox Outbound Threat", + "PII Social Security Number": "Armorblox Outbound Threat", + "PII Tax Number": "Armorblox Outbound Threat", + "Passwords": "Armorblox Outbound Threat", + "Payment Fraud (External)": "Armorblox Inbound Threat", + "Payment Fraud (Internal)": "Armorblox Inbound Threat", + "Payroll Fraud": "Armorblox Inbound Threat", + "Phish URL (Attachment)": "Armorblox Inbound Threat", + "Phish URL (Mail Body)": "Armorblox Inbound Threat", + "Potential Account Compromise": "Armorblox Inbound Threat", + "Ransomware": "Armorblox Inbound Threat", + "Social Engineering": "Armorblox Inbound Threat" + }, + "name": "Armorblox - Classifier", + "transformer": { + "complex": { + "accessor": "", + "filters": [], + "root": "policy_names", + "transformers": [ + { + "args": { + "descending": { + "isContext": false, + "value": { + "complex": null, + "simple": "false" + } + } + }, + "operator": "sort" + }, + { + "args": {}, + "operator": "FirstArrayElement" + } + ] + }, + "simple": "" + }, + "type": "classification", + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Mapper.json b/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Mapper.json new file mode 100644 index 000000000000..cc207de1c8c2 --- /dev/null +++ b/Packs/Armorblox/Classifiers/classifier-Armorblox_-_Mapper.json @@ -0,0 +1,326 @@ +{ + "description": "Maps incoming Armorblox incident fields.", + "feed": false, + "id": "Armorblox - Mapper", + "mapping": { + "Armorblox": { + "dontMapEventToLabels": true, + "internalMapping": { + "App": { + "complex": { + "accessor": "", + "filters": [], + "root": "app_name", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Incident Id": { + "complex": { + "accessor": "", + "filters": [], + "root": "id", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Policy Names": { + "complex": { + "accessor": "", + "filters": [], + "root": "policy_names", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Remediation Actions": { + "complex": { + "accessor": "", + "filters": [], + "root": "remediation_actions", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Resolution State": { + "complex": { + "accessor": "", + "filters": [], + "root": "resolution_state", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Subject": { + "complex": { + "accessor": "", + "filters": [], + "root": "title", + "transformers": [] + }, + "simple": "" + }, + "category": { + "complex": { + "accessor": "details.folder_categories.[0]", + "filters": [], + "root": "CustomFields", + "transformers": [] + }, + "simple": "" + }, + "occurred": { + "complex": { + "accessor": "", + "filters": [], + "root": "date", + "transformers": [ + { + "args": { + "add_utc_timezone": { + "isContext": false, + "value": { + "complex": null, + "simple": "false" + } + }, + "dayfirst": { + "isContext": false, + "value": { + "complex": null, + "simple": "false" + } + }, + "fuzzy": { + "isContext": false, + "value": { + "complex": null, + "simple": "false" + } + }, + "yearfirst": { + "isContext": false, + "value": { + "complex": null, + "simple": "true" + } + } + }, + "operator": "DateStringToISOFormat" + } + ] + }, + "simple": "" + }, + "severity": { + "complex": { + "accessor": "", + "filters": [], + "root": "priority", + "transformers": [] + }, + "simple": "" + } + } + }, + "Armorblox Abuse Mailbox Report": { + "dontMapEventToLabels": false, + "internalMapping": { + "Armorblox Incident Id": { + "complex": { + "accessor": "", + "filters": [], + "root": "id", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Policy Names": { + "complex": { + "accessor": "", + "filters": [], + "root": "policy_names", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Remediation Actions": { + "complex": { + "accessor": "", + "filters": [], + "root": "remediation_actions", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Resolution State": { + "complex": { + "accessor": "", + "filters": [], + "root": "resolution_state", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Subject": { + "complex": { + "accessor": "", + "filters": [], + "root": "title", + "transformers": [] + }, + "simple": "" + } + } + }, + "Armorblox Inbound Threat": { + "dontMapEventToLabels": false, + "internalMapping": { + "Armorblox Incident Id": { + "complex": { + "accessor": "", + "filters": [], + "root": "id", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Policy Names": { + "complex": { + "accessor": "", + "filters": [], + "root": "policy_names", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Remediation Actions": { + "complex": { + "accessor": "", + "filters": [], + "root": "remediation_actions", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Resolution State": { + "complex": { + "accessor": "", + "filters": [], + "root": "resolution_state", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Subject": { + "complex": { + "accessor": "", + "filters": [], + "root": "title", + "transformers": [] + }, + "simple": "" + } + } + }, + "Armorblox Outbound Threat": { + "dontMapEventToLabels": false, + "internalMapping": { + "Armorblox Incident Id": { + "complex": { + "accessor": "", + "filters": [], + "root": "id", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Policy Names": { + "complex": { + "accessor": "", + "filters": [], + "root": "policy_names", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Remediation Actions": { + "complex": { + "accessor": "", + "filters": [], + "root": "remediation_actions", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Resolution State": { + "complex": { + "accessor": "", + "filters": [], + "root": "resolution_state", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Subject": { + "complex": { + "accessor": "", + "filters": [], + "root": "title", + "transformers": [] + }, + "simple": "" + } + } + }, + "dbot_classification_incident_type_all": { + "dontMapEventToLabels": true, + "internalMapping": { + "App": { + "complex": { + "accessor": "", + "filters": [], + "root": "app_name", + "transformers": [] + }, + "simple": "" + }, + "Armorblox Incident Id": { + "complex": null, + "simple": "CustomFields.details.id" + }, + "category": { + "complex": { + "accessor": "details.folder_categories.[0]", + "filters": [], + "root": "CustomFields", + "transformers": [] + }, + "simple": "" + }, + "occurred": { + "complex": { + "accessor": "", + "filters": [], + "root": "date", + "transformers": [] + }, + "simple": "" + }, + "severity": { + "complex": { + "accessor": "", + "filters": [], + "root": "priority", + "transformers": [] + }, + "simple": "" + } + } + } + }, + "name": "Armorblox - Mapper", + "type": "mapping-incoming", + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Incident_Id.json b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Incident_Id.json new file mode 100644 index 000000000000..c89525f3e181 --- /dev/null +++ b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Incident_Id.json @@ -0,0 +1,32 @@ +{ + "associatedToAll": false, + "associatedTypes": [ + "Armorblox", + "Armorblox Inbound Threat", + "Armorblox Abuse Mailbox Report", + "Armorblox Outbound Threat" + ], + "caseInsensitive": true, + "cliName": "armorbloxincidentid", + "closeForm": false, + "content": true, + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_armorbloxincidentid", + "isReadOnly": false, + "locked": false, + "name": "Armorblox Incident Id", + "neverSetAsRequired": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "shortText", + "unmapped": false, + "unsearchable": false, + "useAsKpi": false, + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Policy_Names.json b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Policy_Names.json new file mode 100644 index 000000000000..41e804cdeb0c --- /dev/null +++ b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Policy_Names.json @@ -0,0 +1,32 @@ +{ + "associatedToAll": false, + "associatedTypes": [ + "Armorblox", + "Armorblox Inbound Threat", + "Armorblox Abuse Mailbox Report", + "Armorblox Outbound Threat" + ], + "caseInsensitive": true, + "cliName": "armorbloxpolicynames", + "closeForm": false, + "content": true, + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_armorbloxpolicynames", + "isReadOnly": false, + "locked": false, + "name": "Armorblox Policy Names", + "neverSetAsRequired": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "longText", + "unmapped": false, + "unsearchable": false, + "useAsKpi": false, + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Remediation_Actions.json b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Remediation_Actions.json new file mode 100644 index 000000000000..b90c8bb5ba1a --- /dev/null +++ b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Remediation_Actions.json @@ -0,0 +1,32 @@ +{ + "associatedToAll": false, + "associatedTypes": [ + "Armorblox", + "Armorblox Inbound Threat", + "Armorblox Abuse Mailbox Report", + "Armorblox Outbound Threat" + ], + "caseInsensitive": true, + "cliName": "armorbloxremediationactions", + "closeForm": false, + "content": true, + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_armorbloxremediationactions", + "isReadOnly": false, + "locked": false, + "name": "Armorblox Remediation Actions", + "neverSetAsRequired": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "longText", + "unmapped": false, + "unsearchable": false, + "useAsKpi": false, + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Resolution_State.json b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Resolution_State.json new file mode 100644 index 000000000000..322ef7c269a6 --- /dev/null +++ b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Resolution_State.json @@ -0,0 +1,32 @@ +{ + "associatedToAll": false, + "associatedTypes": [ + "Armorblox", + "Armorblox Inbound Threat", + "Armorblox Abuse Mailbox Report", + "Armorblox Outbound Threat" + ], + "caseInsensitive": true, + "cliName": "armorbloxresolutionstate", + "closeForm": false, + "content": true, + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_armorbloxresolutionstate", + "isReadOnly": false, + "locked": false, + "name": "Armorblox Resolution State", + "neverSetAsRequired": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "shortText", + "unmapped": false, + "unsearchable": false, + "useAsKpi": false, + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Subject.json b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Subject.json new file mode 100644 index 000000000000..72aef6433adb --- /dev/null +++ b/Packs/Armorblox/IncidentFields/incidentfield-Armorblox_Subject.json @@ -0,0 +1,32 @@ +{ + "associatedToAll": false, + "associatedTypes": [ + "Armorblox", + "Armorblox Inbound Threat", + "Armorblox Abuse Mailbox Report", + "Armorblox Outbound Threat" + ], + "caseInsensitive": true, + "cliName": "armorbloxsubject", + "closeForm": false, + "content": true, + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_armorbloxsubject", + "isReadOnly": false, + "locked": false, + "name": "Armorblox Subject", + "neverSetAsRequired": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "shortText", + "unmapped": false, + "unsearchable": false, + "useAsKpi": false, + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox.json b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox.json new file mode 100644 index 000000000000..1b38d12b9a5e --- /dev/null +++ b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox.json @@ -0,0 +1,27 @@ +{ + "autorun": true, + "color": "#D6EB8D", + "days": 0, + "daysR": 0, + "default": false, + "detached": false, + "disabled": false, + "extractSettings": { + "fieldCliNameToExtractSettings": {}, + "mode": "Specific" + }, + "hours": 0, + "hoursR": 0, + "id": "Armorblox", + "locked": false, + "name": "Armorblox", + "onChangeRepAlg": 0, + "playbookId": "Armorblox Needs Review", + "readonly": false, + "reputationCalc": 0, + "system": false, + "version": -1, + "weeks": 0, + "weeksR": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Abuse_Mailbox_Report.json b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Abuse_Mailbox_Report.json new file mode 100644 index 000000000000..baa5b9ba7eb1 --- /dev/null +++ b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Abuse_Mailbox_Report.json @@ -0,0 +1,27 @@ +{ + "autorun": true, + "color": "#E3FF88", + "days": 0, + "daysR": 0, + "default": false, + "detached": false, + "disabled": false, + "extractSettings": { + "fieldCliNameToExtractSettings": {}, + "mode": "Specific" + }, + "hours": 0, + "hoursR": 0, + "id": "Armorblox Abuse Mailbox Report", + "locked": false, + "name": "Armorblox Abuse Mailbox Report", + "onChangeRepAlg": 0, + "playbookId": "Armorblox Needs Review", + "readonly": false, + "reputationCalc": 0, + "system": false, + "version": -1, + "weeks": 0, + "weeksR": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Inbound_Threat.json b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Inbound_Threat.json new file mode 100644 index 000000000000..c53606775cd9 --- /dev/null +++ b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Inbound_Threat.json @@ -0,0 +1,27 @@ +{ + "autorun": true, + "color": "#D4E8F1", + "days": 0, + "daysR": 0, + "default": false, + "detached": false, + "disabled": false, + "extractSettings": { + "fieldCliNameToExtractSettings": {}, + "mode": "Specific" + }, + "hours": 0, + "hoursR": 0, + "id": "Armorblox Inbound Threat", + "locked": false, + "name": "Armorblox Inbound Threat", + "onChangeRepAlg": 0, + "playbookId": "Armorblox Needs Review", + "readonly": false, + "reputationCalc": 0, + "system": false, + "version": -1, + "weeks": 0, + "weeksR": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Outbound_Threat.json b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Outbound_Threat.json new file mode 100644 index 000000000000..b1d6cf447959 --- /dev/null +++ b/Packs/Armorblox/IncidentTypes/incidenttype-Armorblox_Outbound_Threat.json @@ -0,0 +1,27 @@ +{ + "autorun": true, + "color": "#FF979A", + "days": 0, + "daysR": 0, + "default": false, + "detached": false, + "disabled": false, + "extractSettings": { + "fieldCliNameToExtractSettings": {}, + "mode": "Specific" + }, + "hours": 0, + "hoursR": 0, + "id": "Armorblox Outbound Threat", + "locked": false, + "name": "Armorblox Outbound Threat", + "onChangeRepAlg": 0, + "playbookId": "Armorblox Needs Review", + "readonly": false, + "reputationCalc": 0, + "system": false, + "version": -1, + "weeks": 0, + "weeksR": 0, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/Armorblox/Integrations/Armorblox/Armorblox.py b/Packs/Armorblox/Integrations/Armorblox/Armorblox.py new file mode 100644 index 000000000000..617b76c1fe15 --- /dev/null +++ b/Packs/Armorblox/Integrations/Armorblox/Armorblox.py @@ -0,0 +1,243 @@ +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 +# noqa: F401 +# noqa: F401 +# noqa: F401 +# noqa: F401 +import dateparser +import requests +import json +import collections + +# disable insecure warnings +requests.packages.urllib3.disable_warnings() + +DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" +MAX_INCIDENTS_TO_FETCH = demisto.params().get('max_fetch') +FIRST_FETCH = demisto.params().get('first_fetch') +TENANT_NAME = demisto.params().get('tenantName') +INSECURE = demisto.params().get('insecure') +PROXY = demisto.params().get('proxy') +API_KEY = demisto.params().get('apikey') +verify_certificate = not demisto.params().get('insecure', False) +proxy = demisto.params().get('proxy', False) +BASE_URL = f"https://{TENANT_NAME}.armorblox.io/api/v1beta1/organizations/{TENANT_NAME}" + +payload: Dict = {} +headers = { + 'x-ab-authorization': f'{API_KEY}' +} + + +class Client(BaseClient): + """Client class to interact with the service API + This Client implements API calls, and does not contain any Demisto logic. + Should only do requests and return data. + It inherits from BaseClient defined in CommonServer Python. + Most calls use _http_request() that handles proxy, SSL verification, etc. + """ + + def get_incidents(self, orderBy="ASC", pageSize=None, pageToken=None, first_fetch=None) -> List[Dict[str, Any]]: + request_params: Dict[str, Any] = {} + + request_params['orderBy'] = orderBy + if pageToken == -1 and first_fetch: + request_params['timeFilter'] = first_fetch + elif pageToken and first_fetch: + request_params['timeFilter'] = first_fetch + request_params['pageToken'] = pageToken + if pageSize: + request_params['pageSize'] = pageSize + return self._http_request( + method='GET', + url_suffix='/incidents', + params=request_params + ) + + def get_incident_details(self, incident_id): + request_params: Dict[str, Any] = {} + return self._http_request( + method='GET', + url_suffix='/incidents/{}'.format(incident_id), + params=request_params + ) + + +def makehash(): + return collections.defaultdict(makehash) + + +def test_module(client: Client) -> str: + """Tests API connectivity and authentication' + Returning 'ok' indicates that the integration works like it is supposed to. + Connection to the service is successful. + Raises exceptions if something goes wrong. + :type client: ``Client`` + :param Client: Armorblox client to use + :type name: ``str`` + :return: 'ok' if test passed, anything else will fail the test. + :rtype: ``str`` + """ + + try: + client.get_incidents(pageSize=1) + + except DemistoException as e: + if 'Forbidden' in str(e): + return 'Authorization Error: make sure API Key is correctly set' + else: + raise e + return 'ok' + + +def get_page_token(client, pageToken=None): + response = client.get_incidents(pageSize=MAX_INCIDENTS_TO_FETCH, pageToken=pageToken, first_fetch=FIRST_FETCH) + if 'next_page_token' in response.keys(): + return response['next_page_token'] + else: + return None + + +def get_incidents_list(client, pageToken, first_fetch): + """ + Hits the Armorblox API and returns the list of fetched incidents. + """ + response = client.get_incidents(pageSize=MAX_INCIDENTS_TO_FETCH, pageToken=pageToken, first_fetch=FIRST_FETCH) + results = [] + if 'incidents' in response.keys(): + results = response['incidents'] + + # For each incident, get the details and extract the message_id + for result in results: + result['message_ids'] = get_incident_message_ids(client, result["id"]) + return results + + +def get_incident_message_ids(client, incident_id): + """ + Returns the message ids for all the events for the input incident. + """ + + detail_response = client.get_incident_details(incident_id) + message_ids = [] + # loop through all the events of this incident and collect the message ids + if 'events' in detail_response.keys(): + for event in detail_response['events']: + message_ids.append(event['message_id']) + + if 'abuse_events' in detail_response.keys(): + for event in detail_response['abuse_events']: + message_ids.append(event['message_id']) + return message_ids + + +def get_remediation_action(client, incident_id): + """ + Returns the remediation action(s) for the input incident. + """ + + detail_response = client.get_incident_details(incident_id) + remediation_actions = None + if 'remediation_actions' in detail_response.keys(): + remediation_actions = detail_response['remediation_actions'][0] + # if ('NEEDS REVIEW' in detail_response['remediation_actions']) or ('ALERT' in detail_response['remediation_actions']): + # remediation_actions = 'NEEDS REVIEW' + # else: + # remediation_actions = None + else: + remediation_actions = None + + contxt = makehash() + human_readable = makehash() + human_readable['incident_id'] = incident_id + human_readable['remediation_actions'] = remediation_actions + contxt['incident_id'] = incident_id + contxt['remediation_actions'] = remediation_actions + ec = {'Armorblox.Threat(val.incident_id && val.incident_id == obj.incident_id)': contxt} + demisto.results({ + 'Type': entryTypes['note'], + 'ContentsFormat': formats['markdown'], + 'Contents': detail_response, + 'HumanReadable': tableToMarkdown('Remediation Action is: ', human_readable), + 'EntryContext': ec, + + }) + + +def fetch_incidents_command(client): + last_run = demisto.getLastRun() + start_time: Any + # pageToken fetched from demisto lastRun + pageToken = int() + response = {} + incidents = [] + if (not last_run) is True: + pageToken = -1 + response = client.get_incidents(pageSize=1, pageToken=pageToken, first_fetch=FIRST_FETCH) + if 'incidents' in response.keys(): + start_time = response['incidents'][0]['date'] + start_time = dateparser.parse(start_time) + curr_incident = {'rawJSON': json.dumps(response['incidents'][0]), 'details': json.dumps(response['incidents'][0])} + incidents.append(curr_incident) + + if last_run and 'pageToken' in last_run.keys(): + pageToken = last_run.get('pageToken') + + if last_run and 'start_time' in last_run.keys(): + start_time = dateparser.parse(last_run.get('start_time')) + + start_time = start_time.timestamp() + incidents_data = get_incidents_list(client, pageToken=pageToken, first_fetch=FIRST_FETCH) + pageToken = get_page_token(client, pageToken=pageToken) + last_time = start_time + + for incident in incidents_data: + dt = incident['date'] + dt = dateparser.parse(dt).timestamp() + # Update last run and add incident if the incident is newer than last fetch + if dt > start_time: + + curr_incident = {'rawJSON': json.dumps(incident), 'details': json.dumps(incident)} + last_time = dt + incidents.append(curr_incident) + demisto.debug(str(len(incidents))) + # Save the next_run as a dict with the start_time key to be stored + demisto.setLastRun({'start_time': str(last_time), 'pageToken': pageToken}) + demisto.incidents(incidents) + # readable_output = f'## {len(incidents)}' + # return CommandResults( + # readable_output=readable_output, + # outputs_prefix='Armorblox', + # outputs_key_field='', + # outputs=incidents + # ) + + +def main(): + ''' EXECUTION ''' + LOG('command is %s' % (demisto.command(), )) + try: + + client = Client( + base_url=BASE_URL, + verify=verify_certificate, + headers=headers, + proxy=proxy) + + if demisto.command() == "fetch-incidents": + fetch_incidents_command(client) + return_results("Incidents fetched successfully!!") + # return_results(fetch_incidents_command(client)) + if demisto.command() == "armorblox-check-remediation-action": + incident_id = demisto.args().get('incident_id') + get_remediation_action(client, incident_id) + + elif demisto.command() == 'test-module': + result = test_module(client) + return_results(result) + except Exception as e: + return_error(str(e)) + + +if __name__ in ['__main__', 'builtin', 'builtins']: + main() diff --git a/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml b/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml new file mode 100644 index 000000000000..117da9ce5a9e --- /dev/null +++ b/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml @@ -0,0 +1,84 @@ +category: Email Gateway +commonfields: + id: Armorblox + version: -1 +configuration: +- display: Armorblox tenant name + name: tenantName + required: true + type: 0 +- defaultvalue: Armorblox + display: Incident type + name: incidentType + required: false + type: 13 +- display: API key + name: apikey + required: true + type: 4 +- defaultvalue: "50" + display: Fetch limit + name: max_fetch + required: false + type: 0 +- defaultvalue: lastDay + display: First fetch timestamp (last