From 98bece416e7ba8f47a00a007c84e5d4924dd122d Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Wed, 8 Nov 2023 23:38:26 +0200 Subject: [PATCH] Bug fixes and enchancements in integration (#30751) * Bug fixes and enchancements in integration (#30292) * New PR with all the changes * Updated RN * Fixed issues in files' format * Fixed fieldnames * Fixed field's name in layout file * Fixed field's name in layout file * Fixed field's name in layout file * Removed -Layout suffix * Updated layout file * Formatted files * Fixed playbook * Updated RNs * Made changes in object files, uploading updated ones * Formatted files and bugs, test failure fixes * Updated RN, tests, playbook changes and formatting * Updated RN --------- Co-authored-by: Yehuda Rosenberg <90599084+RosenbergYehuda@users.noreply.github.com> * RN * mistake * RN --------- Co-authored-by: cyble-dev <101622497+cyble-dev@users.noreply.github.com> Co-authored-by: Yehuda Rosenberg <90599084+RosenbergYehuda@users.noreply.github.com> Co-authored-by: Yehuda --- Packs/CybleEventsV2/.pack-ignore | 4 +- ...ssifier-CybleEventsv2-Incoming-Mapper.json | 98 ++ ...ssifier-CybleEventsv2-Outgoing-Mapper.json | 22 + .../incidentfield-Application.json | 32 + .../incidentfield-CE_Filename.json | 32 + .../incidentfield-CE_Username.json | 32 + .../incidentfield-Card_Brand.json | 32 + .../incidentfield-Card_CVV.json | 32 + .../incidentfield-Card_Expiry.json | 32 + .../incidentfield-Card_Level.json | 32 + .../IncidentFields/incidentfield-Card_No.json | 32 + .../incidentfield-Card_Type.json | 32 + .../IncidentFields/incidentfield-Keyword.json | 32 + .../incidentfield-Password.json | 32 + .../IncidentFields/incidentfield-URL.json | 32 + .../incidenttype-Cyble_Vision_Alert_V2.json | 3 +- .../CybleEventsV2/CybleEventsV2.py | 818 ++++++---- .../CybleEventsV2/CybleEventsV2.yml | 75 +- .../CybleEventsV2_description.md | 2 +- .../CybleEventsV2/CybleEventsV2_test.py | 135 +- .../Integrations/CybleEventsV2/README.md | 49 +- .../test_data/dummy_update_incident.json | 59 + ...ayoutscontainer-Cyble_Vision_Alert_V2.json | 1408 ++++++++--------- Packs/CybleEventsV2/ReleaseNotes/1_0_2.md | 52 + .../doc_files/Cyble_Vision_Alert_V2.png | Bin 0 -> 29813 bytes .../Cyble_Vision_Alert_V2_Wed_Apr_26_2023.png | Bin 20028 -> 0 bytes Packs/CybleEventsV2/pack_metadata.json | 5 +- 27 files changed, 2019 insertions(+), 1095 deletions(-) create mode 100644 Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Incoming-Mapper.json create mode 100644 Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Outgoing-Mapper.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Application.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Filename.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Username.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Brand.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Card_CVV.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Expiry.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Level.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Card_No.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Type.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Keyword.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-Password.json create mode 100644 Packs/CybleEventsV2/IncidentFields/incidentfield-URL.json create mode 100644 Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_update_incident.json create mode 100644 Packs/CybleEventsV2/ReleaseNotes/1_0_2.md create mode 100644 Packs/CybleEventsV2/doc_files/Cyble_Vision_Alert_V2.png delete mode 100644 Packs/CybleEventsV2/doc_files/Cyble_Vision_Alert_V2_Wed_Apr_26_2023.png diff --git a/Packs/CybleEventsV2/.pack-ignore b/Packs/CybleEventsV2/.pack-ignore index e9ff87892138..7627fef4ad9f 100644 --- a/Packs/CybleEventsV2/.pack-ignore +++ b/Packs/CybleEventsV2/.pack-ignore @@ -5,4 +5,6 @@ ignore=IN126 ignore=RM108 [known_words] -cyble \ No newline at end of file +cyble +CVV +autorun \ No newline at end of file diff --git a/Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Incoming-Mapper.json b/Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Incoming-Mapper.json new file mode 100644 index 000000000000..5b327d5abfb9 --- /dev/null +++ b/Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Incoming-Mapper.json @@ -0,0 +1,98 @@ +{ + "description": "", + "feed": false, + "id": "CybleEventsv2-Incoming-Mapper", + "mapping": { + "Cyble Vision Alert V2": { + "dontMapEventToLabels": false, + "internalMapping": { + "Additional Data": { + "simple": "data_message" + }, + "CybleEventsV2 Application": { + "simple": "application" + }, + "CybleEventsV2 CE Filename": { + "simple": "filename" + }, + "CybleEventsV2 CE Username": { + "simple": "username" + }, + "CybleEventsV2 Card Brand": { + "simple": "card_brand" + }, + "CybleEventsV2 Card CVV": { + "simple": "card_cvv" + }, + "CybleEventsV2 Card Expiry": { + "simple": "card_expiry" + }, + "CybleEventsV2 Card Level": { + "simple": "card_level" + }, + "CybleEventsV2 Card No.": { + "simple": "card_no" + }, + "CybleEventsV2 Card Type": { + "simple": "card_type" + }, + "Event ID": { + "complex": { + "filters": [], + "root": "event_id", + "transformers": [] + } + }, + "Event Type": { + "complex": { + "filters": [], + "root": "event_type", + "transformers": [] + } + }, + "CybleEventsV2 Keyword": { + "simple": "keyword" + }, + "CybleEventsV2 Password": { + "simple": "password" + }, + "CybleEventsV2 URL": { + "simple": "url" + }, + "dbotMirrorDirection": { + "simple": ".='Out'" + }, + "dbotMirrorId": { + "simple": "event_id" + }, + "dbotMirrorInstance": { + "simple": "mirrorInstance" + }, + "dbotMirrorTags": { + "simple": ".=['severity','status']" + }, + "name": { + "complex": { + "filters": [], + "root": "name", + "transformers": [] + } + }, + "occurred": { + "simple": "created_at" + }, + "severity": { + "complex": { + "filters": [], + "root": "severity", + "transformers": [] + } + } + } + } + }, + "name": "CybleEventsv2-Incoming-Mapper", + "type": "mapping-incoming", + "version": -1, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Outgoing-Mapper.json b/Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Outgoing-Mapper.json new file mode 100644 index 000000000000..75c6dd389930 --- /dev/null +++ b/Packs/CybleEventsV2/Classifiers/classifier-CybleEventsv2-Outgoing-Mapper.json @@ -0,0 +1,22 @@ +{ + "description": "", + "feed": false, + "id": "CybleEventsv2-Outgoing-Mapper", + "mapping": { + "Cyble Vision Alert V2": { + "dontMapEventToLabels": true, + "internalMapping": { + "id": { + "simple": "eventid" + }, + "severity": { + "simple": "severity" + } + } + } + }, + "name": "CybleEventsv2-Outgoing-Mapper", + "type": "mapping-outgoing", + "version": -1, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Application.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Application.json new file mode 100644 index 000000000000..2a50edce271b --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Application.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2application", + "version": -1, + "modified": "2023-11-03T08:12:46.912634844Z", + "name": "CybleEventsV2 Application", + "ownerOnly": false, + "description": "Compromised endpoints: Application", + "cliName": "cybleeventsv2application", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Filename.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Filename.json new file mode 100644 index 000000000000..e1f242120b0e --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Filename.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2cefilename", + "version": -1, + "modified": "2023-11-03T08:28:55.182914432Z", + "name": "CybleEventsV2 CE Filename", + "ownerOnly": false, + "description": "Compromised endpoints: Filename", + "cliName": "cybleeventsv2cefilename", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Username.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Username.json new file mode 100644 index 000000000000..801f862a598a --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-CE_Username.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2ceusername", + "version": -1, + "modified": "2023-11-03T08:14:57.291377526Z", + "name": "CybleEventsV2 CE Username", + "ownerOnly": false, + "description": "Compromised endpoints: Username", + "cliName": "cybleeventsv2ceusername", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Brand.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Brand.json new file mode 100644 index 000000000000..b02402c878d5 --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Brand.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2cardbrand", + "version": -1, + "modified": "2023-11-01T17:28:52.96473009Z", + "name": "CybleEventsV2 Card Brand", + "ownerOnly": false, + "description": "Card Brand", + "cliName": "cybleeventsv2cardbrand", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_CVV.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_CVV.json new file mode 100644 index 000000000000..1747aed8119d --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_CVV.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2cardcvv", + "version": -1, + "modified": "2023-11-01T17:28:53.399763556Z", + "name": "CybleEventsV2 Card CVV", + "ownerOnly": false, + "description": "Card CVV", + "cliName": "cybleeventsv2cardcvv", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Expiry.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Expiry.json new file mode 100644 index 000000000000..b5a699bd8bcb --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Expiry.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2cardexpiry", + "version": -1, + "modified": "2023-11-01T17:28:53.790728925Z", + "name": "CybleEventsV2 Card Expiry", + "ownerOnly": false, + "description": "Card Expiry", + "cliName": "cybleeventsv2cardexpiry", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Level.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Level.json new file mode 100644 index 000000000000..5dcee6664079 --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Level.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2cardlevel", + "version": -1, + "modified": "2023-11-01T17:28:54.409441163Z", + "name": "CybleEventsV2 Card Level", + "ownerOnly": false, + "description": "Card Level", + "cliName": "cybleeventsv2cardlevel", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_No.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_No.json new file mode 100644 index 000000000000..ccc28ff25840 --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_No.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2cardno", + "version": -1, + "modified": "2023-11-01T17:28:55.220617299Z", + "name": "CybleEventsV2 Card No.", + "ownerOnly": false, + "description": "Card No.", + "cliName": "cybleeventsv2cardno", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Type.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Type.json new file mode 100644 index 000000000000..e4b6638814a6 --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Card_Type.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2cardtype", + "version": -1, + "modified": "2023-11-01T17:28:55.661848364Z", + "name": "CybleEventsV2 Card Type", + "ownerOnly": false, + "description": "Card Type", + "cliName": "cybleeventsv2cardtype", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Keyword.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Keyword.json new file mode 100644 index 000000000000..c1704148ec4a --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Keyword.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2keyword", + "version": -1, + "modified": "2023-11-03T10:26:32.139137084Z", + "name": "CybleEventsV2 Keyword", + "ownerOnly": false, + "description": "Keyword", + "cliName": "cybleeventsv2keyword", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-Password.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-Password.json new file mode 100644 index 000000000000..16ea168e290b --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-Password.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2password", + "version": -1, + "modified": "2023-11-03T08:13:38.531471449Z", + "name": "CybleEventsV2 Password", + "ownerOnly": false, + "description": "Compromised endpoints: Password", + "cliName": "cybleeventsv2password", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentFields/incidentfield-URL.json b/Packs/CybleEventsV2/IncidentFields/incidentfield-URL.json new file mode 100644 index 000000000000..cfc373f6ebdf --- /dev/null +++ b/Packs/CybleEventsV2/IncidentFields/incidentfield-URL.json @@ -0,0 +1,32 @@ +{ + "id": "incident_cybleeventsv2url", + "version": -1, + "modified": "2023-11-03T08:13:56.548268716Z", + "name": "CybleEventsV2 URL", + "ownerOnly": false, + "description": "Compromised endpoints: URL", + "cliName": "cybleeventsv2url", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Cyble Vision Alert V2" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": false, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/IncidentTypes/incidenttype-Cyble_Vision_Alert_V2.json b/Packs/CybleEventsV2/IncidentTypes/incidenttype-Cyble_Vision_Alert_V2.json index f306f8485706..bba88441ffa0 100644 --- a/Packs/CybleEventsV2/IncidentTypes/incidenttype-Cyble_Vision_Alert_V2.json +++ b/Packs/CybleEventsV2/IncidentTypes/incidenttype-Cyble_Vision_Alert_V2.json @@ -6,7 +6,6 @@ "name": "Cyble Vision Alert V2", "prevName": "Cyble Vision Alert V2", "color": "#F8E7A5", - "playbookId": "Cyble Vision Alert V2", "hours": 0, "days": 0, "weeks": 0, @@ -16,7 +15,7 @@ "system": false, "readonly": false, "default": false, - "autorun": true, + "autorun": false, "disabled": false, "reputationCalc": 0, "onChangeRepAlg": 0, diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py index 247ffefe4ed6..1a4bf598a3d7 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.py @@ -4,15 +4,16 @@ import requests from datetime import datetime, timezone import urllib3 -from typing import Dict +import json # Disable insecure warnings urllib3.disable_warnings() ''' CONSTANTS ''' -MAX_ALERTS = 1000 -LIMIT_EVENT_ITEMS = 1000 +MAX_ALERTS = 1600 +LIMIT_EVENT_ITEMS = 1600 +MAX_RETRIES = 3 INCIDENT_SEVERITY = { 'unknown': 0, 'informational': 0.5, @@ -21,6 +22,13 @@ 'high': 3, 'critical': 4 } +INCIDENT_STATUS = [ + "VIEWED", + "UNREVIEWED", + "CONFIRMED_INCIDENT", + "UNDER_REVIEW", + "INFORMATIONAL" +] ROUTES = { "services": r"/apollo/api/v1/y/services", @@ -36,7 +44,9 @@ "cyble-vision-subscribed-services": "services", "cyble-vision-fetch-iocs": "iocs", "test-module": "test", - "fetch-incidents": "alerts" + "fetch-incidents": "alerts", + "update-remote-system": "alerts", + 'get-mapping-fields': "alerts" } @@ -46,7 +56,7 @@ class Client(BaseClient): Should only do requests and return data. """ - def get_response(self, url, headers, payload, method='POST'): + def get_response(self, url, headers, payload, method): """ Generic call to the API for all the methods :param url: Contains the API url @@ -55,16 +65,135 @@ def get_response(self, url, headers, payload, method='POST'): :param payload: Contains the request body """ - try: + for _ in range(MAX_RETRIES): - if method == 'POST': - response = requests.request(method, url, headers=headers, json=payload).json() + try: + if method == 'POST' or method == 'PUT': + response = requests.request(method, url, headers=headers, json=payload) + else: + response = requests.request(method, url, headers=headers, params=payload) + + response.raise_for_status() + + response_json = response.json() + return response_json['data'] + + except Exception: + pass + + return None + + +def validate_input(args, is_iocs=False): + """ + Check if the input params for the command are valid. Return an error if any + :param args: dictionary of input params + :param is_iocs: check if the params are for iocs command + """ + try: + # we assume all the params to be non-empty, as cortex ensures it + if int(args.get('from')) < 0: + raise ValueError(f"The parameter from has a negative value, from: {arg_to_number(args.get('from'))}'") + limit = int(args.get('limit', 1)) + + if is_iocs: + date_format = "%Y-%m-%d" + if args.get('start_date') and args.get('end_date'): + _start_date = datetime.strptime(args.get('start_date'), date_format) + _end_date = datetime.strptime(args.get('end_date'), date_format) else: - response = requests.request(method, url, headers=headers, params=payload).json() + _start_date = datetime(1, 1, 1, 0, 0) + _end_date = datetime(1, 1, 1, 0, 0) - return response['data'] - except Exception: - return [] + if limit <= 0 or limit > 1000: + raise ValueError( + f"The limit argument should contain a positive number, up to 1000, limit: {limit}") + + if _start_date > datetime.utcnow(): + raise ValueError( + f"Start date must be a date before or equal to {datetime.today().strftime(date_format)}") + if _end_date > datetime.utcnow(): + raise ValueError(f"End date must be a date before or equal to {datetime.today().strftime(date_format)}") + if _start_date > _end_date: + raise ValueError(f"Start date {args.get('start_date')} cannot be after end date {args.get('end_date')}") + + else: + date_format = "%Y-%m-%dT%H:%M:%S%z" + _start_date = datetime.strptime(args.get('start_date'), date_format) + _end_date = datetime.strptime(args.get('end_date'), date_format) + if limit <= 0 or limit > LIMIT_EVENT_ITEMS: + raise ValueError(f"The limit argument should contain a positive number, up to 1000, limit: {limit}") + + if _start_date > datetime.now(tz=timezone.utc): + raise ValueError( + f"Start date must be a date before or equal to {datetime.now(tz=timezone.utc).strftime(date_format)}") + if _end_date > datetime.now(tz=timezone.utc): + raise ValueError( + f"End date must be a date before or equal to {args.get('end_date')}") + if _start_date > _end_date: + raise ValueError(f"Start date {args.get('start_date')} cannot be after end date {args.get('end_date')}") + + return + except Exception as e: + demisto.error(f"Exception with validating inputs [{e}]") + raise e + + +def alert_input_structure(input_params): + input_params_alerts: dict[str, Any] = { + "orderBy": [ + { + "created_at": input_params['order_by'] + } + ], + "select": { + "alert_group_id": True, + "archive_date": True, + "archived": True, + "assignee_id": True, + "assignment_date": True, + "created_at": True, + "data_id": True, + "deleted_at": True, + "description": True, + "hash": True, + "id": True, + "metadata": True, + "risk_score": True, + "service": True, + "severity": True, + "status": True, + "tags": True, + "updated_at": True, + "user_severity": True + }, + "skip": input_params['from_da'], + "take": input_params['limit'], + "withDataMessage": True, + "where": { + "created_at": { + "gte": input_params['start_date'], + "lte": input_params['end_date'], + }, + "severity": { + "in": [ + "HIGH", + "MEDIUM", + "LOW" + ] + }, + "status": { + "in": [ + "VIEWED", + "UNREVIEWED", + "CONFIRMED_INCIDENT", + "UNDER_REVIEW", + "INFORMATIONAL" + ] + } + } + } + return input_params_alerts def set_request(client, method, token, input_params, url): @@ -79,30 +208,363 @@ def set_request(client, method, token, input_params, url): Returns: return data from server - """ - headers = {'Authorization': 'Bearer ' + token} - response = client.get_response(url, headers, input_params, method) - return response + """ + headers = {'Authorization': 'Bearer ' + token} + response = client.get_response(url, headers, input_params, method) + return response + + +def format_incidents(alerts, hide_cvv_expiry): + """ + Format the incidents to feed into XSOAR + :param alerts events fetched from the server + :return: incidents to feed into XSOAR + """ + events: List[dict[str, Any]] = [] + try: + for alert in alerts: + + if hide_cvv_expiry and alert['service'] == 'compromised_cards': + alert['data_message']['data']['bank']['card']['cvv'] = "xxx" + alert['data_message']['data']['bank']['card']['expiry'] = "xx/xx/xxxx" + + alert_details = { + "name": "Cyble Vision Alert on {}".format(alert['service']), + "event_type": "{}".format(alert['service']), + "severity": INCIDENT_SEVERITY.get(alert['severity'].lower()), + "alert_group_id": "{}".format(alert['alert_group_id']), + "event_id": "{}".format(alert['id']), + "data_message": json.dumps(alert['data_message']), + "keyword": "{}".format(alert['metadata']['entity']['keyword']['tag_name']), + "created_at": "{}".format(alert['created_at']), + "mirrorInstance": demisto.integrationInstance() + } + + if alert['service'] == 'compromised_cards': + + card_details = alert['data_message']['data']['bank']['card'] + + alert_details.update({ + "card_brand": card_details.get('brand'), + "card_no": card_details.get('card_no'), + "card_cvv": card_details.get('cvv'), + "card_expiry": card_details.get('expiry'), + "card_level": card_details.get('level'), + "card_type": card_details.get('type') + }) + + elif alert['service'] == 'stealer_logs': + + content = alert['data_message']['data'].get('content') + + if content: + alert_details.update({ + "application": content.get('Application'), + "password": content.get('Password'), + "url": content.get('URL'), + "username": content.get('Username') + }) + + alert_details.update({ + "filename": alert['data_message']['data']['filename'] + }) + + events.append(alert_details) + + return events + except Exception as e: + demisto.debug(f'Unable to format incidents, error: {e}') + raise Exception(f"Error: [{e}] for response [{alerts}]") + + +def fetch_service_details(client, base_url, token): + service_name_lists = fetch_subscribed_services(client, "GET", base_url, token) + + lst = [] + for service_name_list in service_name_lists: + lst.append(service_name_list['name']) + + return lst + + +def fetch_subscribed_services(client, method, base_url, token): + """ + Fetch cyble subscribed services + Args: + client: instance of client to communicate with server + method: Requests method to be used + base_url: base url for the server + token: server access token + + Returns: subscribed service list + + """ + get_subscribed_service_url = base_url + str(ROUTES[COMMAND['cyble-vision-subscribed-services']]) + subscribed_services = set_request(client, method, token, {}, get_subscribed_service_url) + service_name_list = [] + + if subscribed_services: + for subscribed_service in subscribed_services: + service_name_list.append({"name": subscribed_service['name']}) + + return service_name_list + + +def test_response(client, method, base_url, token): + """ + Test the integration state + Args: + client: client instance + method: Requests method to be used + base_url: base url for the server + token: API access token + + Returns: test response + + """ + fetch = fetch_subscribed_services(client, method, base_url, token) + if fetch: + return 'ok' + else: + demisto.error("Failed to connect") + raise Exception("failed to connect") + + +def cyble_events(client, method, token, url, args, last_run, hide_cvv_expiry, incident_collections, skip=True): + """ + Fetch alert details from server for creating incidents in XSOAR + Args: + client: instance of client to communicate with server + method: Requests method to be used + token: API access token + url: end point URL + args: input args + last_run: get last run details + hide_cvv_expiry: hide expiry / cvv number from cards + incident_collections: list of collections to be fetched + skip: skip the validation for fetch incidnet + + Returns: events from the server + + """ + + input_params = {} + + input_params['order_by'] = args.get('order_by', "asc") + input_params['from_da'] = arg_to_number(args.get('from', 0)) + input_params['limit'] = MAX_ALERTS + + max_fetch = arg_to_number(demisto.params().get('max_fetch', 1)) + + if skip: + validate_input(args, False) + + input_params['start_date'] = args.get('start_date', '') + input_params['end_date'] = args.get('end_date', '') + + if not args.get('end_date', ''): + input_params['end_date'] = datetime.utcnow().astimezone().isoformat() + + else: + initial_interval = demisto.params().get('first_fetch_timestamp', 1) + + if 'event_pull_start_date' not in last_run.keys(): + event_pull_start_date = datetime.utcnow() - timedelta(days=int(initial_interval)) + input_params['start_date'] = event_pull_start_date.astimezone().isoformat() + + else: + input_params['start_date'] = last_run['event_pull_start_date'] + + input_params['end_date'] = datetime.utcnow().astimezone().isoformat() + + latest_created_time = input_params['start_date'] + + final_input_structure = alert_input_structure(input_params) + + if "All collections" not in incident_collections and len(incident_collections) > 0: + + to_fetch = [] + + if "Darkweb Marketplaces" in incident_collections: + to_fetch.append("darkweb_marketplaces") + + if "Data Breaches" in incident_collections: + to_fetch.append("darkweb_data_breaches") + + if "Compromised Endpoints" in incident_collections: + to_fetch.append("stealer_logs") + + if "Compromised Cards" in incident_collections: + to_fetch.append("compromised_cards") + + final_input_structure['where']['service'] = { + "in": to_fetch + } + + all_alerts = set_request(client, method, token, final_input_structure, url) + timestamp_count = {} # type: ignore + + if not all_alerts: + return [], {'event_pull_start_date': latest_created_time} + + for alert in all_alerts: + + timestamp = alert['created_at'] + + if timestamp in timestamp_count: + timestamp_count[timestamp] += 1 + else: + timestamp_count[timestamp] = 1 + + alert_count = 0 + prev_timestamp = all_alerts[0].get('created_at') + last_timestamp = all_alerts[-1].get('created_at') + + alerts = [] + + for alert in all_alerts: + + current_timestamp = alert.get('created_at') + + if current_timestamp == prev_timestamp: + alerts.append(alert) + else: + alert_count += timestamp_count[prev_timestamp] + prev_timestamp = current_timestamp + + if alert_count + timestamp_count[current_timestamp] <= max_fetch and current_timestamp != last_timestamp: + alerts.append(alert) + else: + break + + del all_alerts + del timestamp_count + + incidents = [] + + if alerts: + + timestamp_str = alerts[-1].get('created_at') + original_datetime = datetime.strptime(timestamp_str, "%Y-%m-%dT%H:%M:%S.%fZ") + updated_datetime = original_datetime + timedelta(microseconds=1000) + latest_created_time = updated_datetime.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + + events = format_incidents(alerts, hide_cvv_expiry) + + for event in events: + + inci = { + 'name': event.get('name'), + 'severity': event.get('severity'), + 'rawJSON': json.dumps(event), + 'alert_group_id': event.get('alert_group_id'), + 'event_id': event.get('event_id'), + 'keyword': event.get('keyword'), + 'created': event.get('created_at') + } + incidents.append(inci) + + next_run = {'event_pull_start_date': latest_created_time} + + return incidents, next_run + else: + return [], {'event_pull_start_date': latest_created_time} + + +def update_remote_system(client, method, token, args, url): + """ + Updates any changes in any mappable incident to remote server + Args: + client: instance of client to communicate with server + method: Requests method to be used + token: API access token + url: end point URL + args: input args + + Returns: None + """ + + parsed_args = UpdateRemoteSystemArgs(args) + + if parsed_args.delta: + + severities = { + "1": "LOW", + "2": "MEDIUM", + "3": "HIGH", + "4": "CRITICAL" + } + + data = parsed_args.data + + incident_id = data.get('id') + status = data.get('status') + assignee_id = data.get('assignee_id') + updated_severity = str(data.get('severity')) + + updated_event = { + "id": incident_id + } + + if status in INCIDENT_STATUS: + updated_event["status"] = status + + if assignee_id: + updated_event["assignee_id"] = assignee_id + + if updated_severity: + if updated_severity == "0.5" or updated_severity == "0": + updated_event["user_severity"] = None + else: + updated_event["user_severity"] = severities.get(updated_severity) + + body = { + "alerts": [updated_event] + } + + set_request(client, method, token, body, url) + + +def get_mapping_fields(client, token, url): + """ + Fetches all the fields associated with incidents for creating outgoing mapper + Args: + client: instance of client to communicate with server + token: API access token + url: end point URL + + Returns: None + """ + + input_params: dict[str, Any] = {} + + input_params['order_by'] = "asc" + input_params['from_da'] = 0 + input_params['limit'] = 500 + + initial_interval = 1 + + event_pull_start_date = datetime.utcnow() - timedelta(days=int(initial_interval)) + + input_params['start_date'] = event_pull_start_date.astimezone().isoformat() + input_params['end_date'] = datetime.utcnow().astimezone().isoformat() + + final_input_structure = alert_input_structure(input_params) + + alerts = set_request(client, 'POST', token, final_input_structure, url) + + fields = {} + for alert in alerts: + for key in alert: + fields[key] = alert[key] -def test_response(client, method, base_url, token): - """ - Test the integration state - Args: - client: client instance - method: Requests method to be used - base_url: base url for the server - token: API access token + incident_type_scheme = SchemeTypeMapping(type_name='cyble_outgoing_mapper') - Returns: test response + for field, description in fields.items(): + incident_type_scheme.add_field(field, description) - """ - fetch = fetch_subscribed_services(client, method, base_url, token) - if fetch: - return 'ok' - else: - demisto.error("Failed to connect") - raise Exception("failed to connect") + return GetMappingFieldsResponse([incident_type_scheme]) def fetch_subscribed_services_alert(client, method, base_url, token): @@ -133,28 +595,6 @@ def fetch_subscribed_services_alert(client, method, base_url, token): ) -def fetch_subscribed_services(client, method, base_url, token): - """ - Fetch cyble subscribed services - Args: - client: instance of client to communicate with server - method: Requests method to be used - base_url: base url for the server - token: server access token - - Returns: subscribed service list - - """ - get_subscribed_service_url = base_url + str(ROUTES[COMMAND['cyble-vision-subscribed-services']]) - subscribed_services = set_request(client, method, token, {}, get_subscribed_service_url) - service_name_list = [] - - for subscribed_service in subscribed_services: - service_name_list.append({"name": subscribed_service['name']}) - - return service_name_list - - def cyble_alert_group(client, method, token, url, args): """ Call the client module to fetch alert group using the input parameters @@ -169,10 +609,10 @@ def cyble_alert_group(client, method, token, url, args): """ - input_params_alerts_group: Dict[str, Any] = { + input_params_alerts_group: dict[str, Any] = { "orderBy": [ { - "created_at": args.get('order_by', "desc") + "created_at": args.get('order_by', "asc") } ], "skip": arg_to_number(args.get('from', 0)), @@ -277,11 +717,11 @@ def cyble_fetch_iocs(client, method, token, args, url): 'risk_rating': "{}".format(ioc['risk_rating']), 'confident_rating': "{}".format(ioc['confident_rating']), 'ioc_type': "{}".format(ioc['ioc_type']['name']), - 'attack': "{}".format(lst_attack), - 'tags': "{}".format(lst_tags) + 'attack': f"{lst_attack}", + 'tags': f"{lst_tags}" }) except Exception as e: - raise Exception("Error: [{}] for response [{}]".format(e, iocs)) + raise Exception(f"Error: [{e}] for response [{iocs}]") markdown = tableToMarkdown('Indicator of Compromise:', lst_iocs, ) @@ -294,243 +734,7 @@ def cyble_fetch_iocs(client, method, token, args, url): return command_results -def format_incidents(alerts): - """ - Format the incidents to feed into XSOAR - :param alerts events fetched from the server - :return: incidents to feed into XSOAR - """ - events: List[Dict[str, Any]] = [] - try: - for alert in alerts: - alert_details = { - "name": "Cyble Vision Alert on {}".format(alert['service']), - "event_type": "{}".format(alert['service']), - "severity": INCIDENT_SEVERITY.get(alert['severity'].lower()), - "alert_group_id": "{}".format(alert['alert_group_id']), - "event_id": "{}".format(alert['id']), - "data_message": "{}".format(alert['data_message']), - "keyword": "{}".format(alert['metadata']['entity']['keyword']['tag_name']), - "created_at": "{}".format(alert['created_at']) - } - - events.append(alert_details) - - return events - except Exception as e: - demisto.debug('Unable to format incidents, error: {}'.format(e)) - raise Exception("Error: [{}] for response [{}]".format(e, alerts)) - - -def cyble_events(client, method, token, url, args, base_url, last_run, skip=True): - """ - Fetch alert details from server for creating incidents in XSOAR - Args: - last_run: get last run details - base_url: base url for subscribed services - client: instance of client to communicate with server - method: Requests method to be used - token: API access token - url: end point URL - args: input args - skip: skip the validation for fetch incidnet - - Returns: events from the server - - """ - - input_params = {} - - input_params['order_by'] = args.get('order_by', "desc") - input_params['from_da'] = arg_to_number(args.get('from', 0)) - - if skip: - validate_input(args, False) - - input_params['limit'] = arg_to_number(args.get('limit', 10)) - input_params['start_date'] = args.get('start_date', '') - input_params['end_date'] = args.get('end_date', '') - - if not args.get('end_date', ''): - input_params['end_date'] = datetime.now().astimezone().replace(microsecond=0).isoformat() - - else: - initial_interval = demisto.params().get('first_fetch_timestamp', 1) - - if 'event_pull_start_date' not in last_run.keys(): - event_pull_start_date = datetime.utcnow() - timedelta(days=int(initial_interval)) - input_params['start_date'] = event_pull_start_date.astimezone().replace(microsecond=0).isoformat() - else: - input_params['start_date'] = last_run['event_pull_start_date'] - - # Convert the argument to an int using helper function or set to MAX_INCIDENTS_TO_FETCH - max_results = arg_to_number(demisto.params().get('max_fetch', 0)) - - if not max_results or max_results > MAX_ALERTS: - input_params['limit'] = MAX_ALERTS - else: - input_params['limit'] = max_results - - input_params['end_date'] = datetime.now().astimezone().replace(microsecond=0).isoformat() - - latest_created_time = input_params['start_date'] - - final_input_structure = alert_input_structure(input_params) - - alerts = set_request(client, method, token, final_input_structure, url) - incidents = [] - - if alerts: - events = format_incidents(alerts) - - for event in events: - incident_created_time = datetime.strptime(event.get('created_at'), - "%Y-%m-%dT%H:%M:%S.%fZ").astimezone().isoformat() - inci = { - 'name': event.get('name'), - 'severity': event.get('severity'), - 'rawJSON': json.dumps(event), - 'alert_group_id': event.get('alert_group_id'), - 'event_id': event.get('event_id'), - 'keyword': event.get('keyword'), - 'created': event.get('created_at'), - } - incidents.append(inci) - - if incident_created_time > latest_created_time: - latest_created_time = incident_created_time - - next_run = {'event_pull_start_date': latest_created_time} - - return incidents, next_run - else: - return [], {'event_pull_start_date': latest_created_time} - - -def validate_input(args, is_iocs=False): - """ - Check if the input params for the command are valid. Return an error if any - :param args: dictionary of input params - :param is_iocs: check if the params are for iocs command - """ - try: - # we assume all the params to be non-empty, as cortex ensures it - if int(args.get('from')) < 0: - raise ValueError(f"The parameter from has a negative value, from: {arg_to_number(args.get('from'))}'") - limit = int(args.get('limit', 1)) - - if is_iocs: - date_format = "%Y-%m-%d" - if args.get('start_date') and args.get('end_date'): - _start_date = datetime.strptime(args.get('start_date'), date_format) - _end_date = datetime.strptime(args.get('end_date'), date_format) - else: - _start_date = datetime(1, 1, 1, 0, 0) - _end_date = datetime(1, 1, 1, 0, 0) - - if limit <= 0 or limit > 1000: - raise ValueError( - f"The limit argument should contain a positive number, up to 1000, limit: {limit}") - - if _start_date > datetime.utcnow(): - raise ValueError( - f"Start date must be a date before or equal to {datetime.today().strftime(date_format)}") - if _end_date > datetime.utcnow(): - raise ValueError(f"End date must be a date before or equal to {datetime.today().strftime(date_format)}") - if _start_date > _end_date: - raise ValueError(f"Start date {args.get('start_date')} cannot be after end date {args.get('end_date')}") - - else: - date_format = "%Y-%m-%dT%H:%M:%S%z" - _start_date = datetime.strptime(args.get('start_date'), date_format) - _end_date = datetime.strptime(args.get('end_date'), date_format) - if limit <= 0 or limit > LIMIT_EVENT_ITEMS: - raise ValueError(f"The limit argument should contain a positive number, up to 1000, limit: {limit}") - - if _start_date > datetime.now(tz=timezone.utc): - raise ValueError( - f"Start date must be a date before or equal to {datetime.now(tz=timezone.utc).strftime(date_format)}") - if _end_date > datetime.now(tz=timezone.utc): - raise ValueError( - f"End date must be a date before or equal to {args.get('end_date')}") - if _start_date > _end_date: - raise ValueError(f"Start date {args.get('start_date')} cannot be after end date {args.get('end_date')}") - - return None - except Exception as e: - demisto.error("Exception with validating inputs [{}]".format(e)) - raise e - - -def fetch_service_details(client, base_url, token): - service_name_lists = fetch_subscribed_services(client, "GET", base_url, token) - - lst = [] - for service_name_list in service_name_lists: - lst.append(service_name_list['name']) - - return lst - - -def alert_input_structure(input_params): - - input_params_alerts: Dict[str, Any] = { - "orderBy": [ - { - "created_at": input_params['order_by'] - } - ], - "select": { - "alert_group_id": True, - "archive_date": True, - "archived": True, - "assignee_id": True, - "assignment_date": True, - "created_at": True, - "data_id": True, - "deleted_at": True, - "description": True, - "hash": True, - "id": True, - "metadata": True, - "risk_score": True, - "service": True, - "severity": True, - "status": True, - "tags": True, - "updated_at": True, - "user_severity": True - }, - "skip": input_params['from_da'], - "take": input_params['limit'], - "withDataMessage": True, - "where": { - "created_at": { - "gte": input_params['start_date'], - "lte": input_params['end_date'], - }, - "severity": { - "in": [ - "HIGH", - "MEDIUM", - "LOW" - ] - }, - "status": { - "in": [ - "VIEWED", - "UNREVIEWED", - "CONFIRMED_INCIDENT", - "UNDER_REVIEW", - "INFORMATIONAL" - ] - } - } - } - return input_params_alerts - - -def main(): +def main(): # pragma: no cover """ PARSE AND VALIDATE INTEGRATION PARAMS """ @@ -541,7 +745,10 @@ def main(): token = demisto.params().get('credentials', {}).get('password', "") verify_certificate = not params.get('insecure', False) proxy = params.get('proxy', False) + hide_cvv_expiry = params.get('hide_data', False) demisto.debug(f'Command being called is {params}') + mirror = params.get('mirror', False) + incident_collections = params.get("incident_collections", []) try: @@ -560,11 +767,26 @@ def main(): last_run = demisto.getLastRun() url = base_url + str(ROUTES[COMMAND[demisto.command()]]) - data, next_run = cyble_events(client, 'POST', token, url, args, base_url, last_run, False) + data, next_run = cyble_events(client, 'POST', token, url, args, last_run, + hide_cvv_expiry, incident_collections, False) demisto.setLastRun(next_run) demisto.incidents(data) + elif demisto.command() == 'update-remote-system': + # Updates changes in incidents to remote system + if mirror: + url = base_url + str(ROUTES[COMMAND[demisto.command()]]) + return_results(update_remote_system(client, 'PUT', token, args, url)) + + return + + elif demisto.command() == 'get-mapping-fields': + # Fetches mapping fields for outgoing mapper + url = base_url + str(ROUTES[COMMAND[demisto.command()]]) + + return_results(get_mapping_fields(client, token, url)) + elif demisto.command() == "cyble-vision-subscribed-services": # This is the call made when subscribed-services command. return_results(fetch_subscribed_services_alert(client, "GET", base_url, token)) @@ -589,7 +811,7 @@ def main(): # This is the call made when cyble-vision-v2-fetch-alerts command. url = base_url + str(ROUTES[COMMAND[demisto.command()]]) - lst_alerts, next_run = cyble_events(client, 'POST', token, url, args, base_url, {}, True) + lst_alerts, next_run = cyble_events(client, 'POST', token, url, args, {}, hide_cvv_expiry, incident_collections, True) markdown = tableToMarkdown('Alerts Details:', lst_alerts) diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml index eeef6d432dfa..adb0cd26237a 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2.yml @@ -14,6 +14,18 @@ configuration: required: true hiddenusername: true type: 9 +- display: Colletions to fetch + name: incident_collections + type: 16 + required: false + additionalinfo: Type(s) of incidents to fetch. + options: + - Darkweb Marketplaces + - Data Breaches + - Compromised Endpoints + - Compromised Cards + - All collections + hidden: false - display: Trust any certificate (not secure) name: insecure type: 8 @@ -22,12 +34,12 @@ configuration: name: proxy type: 8 required: false -- additionalinfo: Maximum incidents to be fetched every time. Upper limit is 1000 incidents. - defaultvalue: '1' - display: Incident Fetch Limit +- display: Incident Fetch Limit name: max_fetch type: 0 required: false + additionalinfo: Maximum incidents to be fetched every time. Upper limit is 1000 incidents. + defaultvalue: '1' - display: Incident type name: incidentType type: 13 @@ -42,12 +54,22 @@ configuration: name: first_fetch_timestamp type: 0 required: false +- display: Hide Card Details + hidden: false + name: hide_data + required: false + type: 8 +- display: Update Incident to Remote System + hidden: false + name: mirror + required: false + type: 8 description: Cyble Events for Vision Users. Must have Vision API access to use the threat intelligence. display: CybleEvents v2 name: cybleeventsv2 script: commands: - - description: Get list of Subscribed services + - description: Get list of Subscribed services. name: cyble-vision-subscribed-services outputs: - contextPath: CybleEvents.SubscribedServices @@ -68,7 +90,7 @@ script: - IPv6 - URL - Emai - - description: Returns records for the specified indicator value + - description: Returns records for the specified indicator value. name: ioc - defaultValue: '0' description: Returns records that starts from the given page number (the value of the form parameter) in the results list. @@ -78,7 +100,7 @@ script: name: limit - auto: PREDEFINED defaultValue: last_seen - description: Sorting based on the column(last_seen,first_seen,ioc_type) + description: Sorting based on the column (last_seen, first_seen, ioc_type). name: sort_by predefined: - last_seen @@ -86,13 +108,13 @@ script: - ioc_type - auto: PREDEFINED default: true - defaultValue: desc - description: A sorting order for ioc. Either Ascending or Descending. The default value is Descending. + defaultValue: asc + description: A sorting order for ioc. name: order predefined: - asc - desc - - description: Returns records for the specified tags + - description: Returns records for the specified tags. name: tags - description: Timeline start date in the format "YYYY-MM-DD". Should be used with start_date as timeline range. name: start_date @@ -102,21 +124,21 @@ script: name: cyble-vision-fetch-iocs outputs: - contextPath: CybleEvents.IoCs.Data - description: Returns indicator with risk score, confident rating, first seen and last seen + description: Returns indicator with risk score, confident rating, first seen and last seen. type: String - arguments: - defaultValue: '5' description: Number of records to return (max 50). Using a smaller limit will get faster responses. name: limit - - description: Timeline start date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601) + - description: Timeline start date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601). name: start_date required: true - - description: Timeline end date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601) + - description: Timeline end date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601). name: end_date required: true - auto: PREDEFINED - defaultValue: desc - description: A sorting order for the fetched alerts. Either Ascending or Descending. The default value is Descending. + defaultValue: asc + description: A sorting order for the fetched alerts. name: order_by predefined: - asc @@ -129,21 +151,21 @@ script: name: cyble-vision-fetch-alerts outputs: - contextPath: CybleEvents.Events.name - description: Return Event name + description: Return Event name. type: String - contextPath: CybleEvents.Events.alert_group_id - description: Return alert group id + description: Return alert group id. type: String - contextPath: CybleEvents.Events.event_id description: Return event id. type: String - contextPath: CybleEvents.Events.keyword - description: Return keywords + description: Return keywords. type: Unknown - arguments: - auto: PREDEFINED - defaultValue: desc - description: A sorting order for the fetched alerts. Either Ascending or Descending. he default value is Descending. + defaultValue: asc + description: A sorting order for the fetched alerts. name: order_by predefined: - asc @@ -151,28 +173,33 @@ script: - defaultValue: '5' description: Number of records to return (max 50). Using a smaller limit will get faster responses. name: limit - - description: Timeline start date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601) + - description: Timeline start date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601). name: start_date required: true - - description: Timeline end date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601) + - description: Timeline end date in the format "%Y-%m-%dT%H:%M:%S%z" (iso-8601). name: end_date required: true - defaultValue: '0' description: Returns records for the timeline starting from the given indice. name: from required: true - description: Fetch incident event group + description: Fetch incident event group. name: cyble-vision-fetch-alert-groups outputs: - contextPath: CybleEvents.AlertGroup - description: Fetch all the alert groups + description: Fetch all the alert groups. type: String - dockerimage: demisto/python3:3.10.12.63474 + - description: Retrieves a User Profile schema, which holds all of the user fields within the application. Used for outgoing-mapping through the Get Schema option. + name: get-mapping-fields + dockerimage: demisto/python3:3.10.13.80014 isfetch: true runonce: false script: '-' subtype: python3 type: python + ismappable: true + isremotesyncin: true + isremotesyncout: true tests: - No tests (auto formatted) fromversion: 6.2.0 diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_description.md b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_description.md index b4c4176f2a74..1760b909943b 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_description.md +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_description.md @@ -8,4 +8,4 @@ Existing users need to use the URL and Access Token as part of Cyble Vision subs For an Access Token, go to Utilities in your Cyble Vision account, and press 'Access APIs' and Generate API Key button. -You can also contact your Account Manager to get the Access Token. +You can also contact your Account Manager to get the Access Token. \ No newline at end of file diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py index ed71550a791f..271a6586b6b8 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/CybleEventsV2_test.py @@ -10,7 +10,6 @@ you are implementing with your integration """ -import io import json from datetime import datetime, timezone, timedelta @@ -20,7 +19,7 @@ def util_load_json(path): - with io.open("test_data/" + path, mode='r', encoding='utf-8') as f: + with open("test_data/" + path, encoding='utf-8') as f: return json.loads(f.read()) @@ -189,7 +188,9 @@ def test_get_alert(requests_mock): url = "https://test.com/apollo/api/v1/y/alerts" - response, next = cyble_events(client, 'POST', "some_random_token", url, args, 'https://test.com', {}) + collections = ["random_collections", "Darkweb Marketplaces", "Data Breaches", "Compromised Endpoints", "Compromised Cards"] + + response, next = cyble_events(client, 'POST', "some_random_token", url, args, {}, False, collections, False) assert isinstance(response, list) assert len(response) == 1 @@ -197,7 +198,7 @@ def test_get_alert(requests_mock): @pytest.mark.parametrize( "offset,limit", [ - ('0', '1289'), ('0', '-2') + ('0', '1789'), ('0', '-2') ] ) def test_limit_cyble_vision_fetch_detail(requests_mock, capfd, offset, limit): @@ -221,10 +222,12 @@ def test_limit_cyble_vision_fetch_detail(requests_mock, capfd, offset, limit): url = "https://test.com/apollo/api/v1/y/alerts" - with capfd.disabled(): - with pytest.raises(ValueError, - match=f"The limit argument should contain a positive number, up to 1000, limit: {limit}"): - cyble_events(client, 'POST', "some_random_token", url, args, "https://test.com", {}, True) + collections = ["random_collections", "Darkweb Marketplaces", "Data Breaches", "Compromised Endpoints", "Compromised Cards"] + + with capfd.disabled(), pytest.raises(ValueError, + match="The limit argument should contain a positive number," + f" up to 1000, limit: {limit}"): + cyble_events(client, 'POST', "some_random_token", url, args, {}, False, collections, True) def test_limit_validate_input(capfd): @@ -236,11 +239,10 @@ def test_limit_validate_input(capfd): 'from': '0', 'limit': '-1', } - with capfd.disabled(): - with pytest.raises(ValueError, - match=f"The limit argument should contain a positive number," - f" up to 1000, limit: {args.get('limit', '50')}"): - validate_input(args=args) + with capfd.disabled(), pytest.raises(ValueError, + match="The limit argument should contain a positive number," + f" up to 1000, limit: {args.get('limit', '50')}"): + validate_input(args=args) def test_limit_validate_ioc_input(capfd): @@ -252,11 +254,10 @@ def test_limit_validate_ioc_input(capfd): 'from': '0', 'limit': '-1', } - with capfd.disabled(): - with pytest.raises(ValueError, - match=f"The limit argument should contain a positive number, " - f"up to 1000, limit: {args.get('limit', '50')}"): - validate_input(args=args, is_iocs=True) + with capfd.disabled(), pytest.raises(ValueError, + match="The limit argument should contain a positive number," + f" up to 1000, limit: {args.get('limit', '50')}"): + validate_input(args=args, is_iocs=True) def test_datecheck_validate_input(capfd): @@ -269,11 +270,10 @@ def test_datecheck_validate_input(capfd): 'limit': '1' } - with capfd.disabled(): - with pytest.raises(ValueError, - match=f"Start date {args.get('start_date')} cannot " - f"be after end date {args.get('end_date')}"): - validate_input(args=args, is_iocs=True) + with capfd.disabled(), pytest.raises(ValueError, + match=f"Start date {args.get('start_date')} cannot " + f"be after end date {args.get('end_date')}"): + validate_input(args=args, is_iocs=True) def test_edate_validate_input(capfd): @@ -289,7 +289,7 @@ def test_edate_validate_input(capfd): with capfd.disabled(): with pytest.raises(ValueError) as excinfo: validate_input(args=args) - assert str("End date must be a date before or equal to") in str(excinfo) + assert "End date must be a date before or equal to" in str(excinfo) def test_date_validate_input(capfd): @@ -305,7 +305,7 @@ def test_date_validate_input(capfd): with capfd.disabled(): with pytest.raises(ValueError) as excinfo: validate_input(args=args) - assert str("cannot be after end date") in str(excinfo) + assert "cannot be after end date" in str(excinfo) def test_offset_cyble_vision_fetch_detail(requests_mock, capfd): @@ -338,12 +338,10 @@ def test_offset_cyble_vision_fetch_detail(requests_mock, capfd): } url = "https://test.com/apollo/api/v1/y/alerts" - base_url = "https://test.com" - with capfd.disabled(): - with pytest.raises(ValueError, - match="The parameter from has a negative value, from: -1'"): - cyble_events(client, 'POST', "some_random_token", url, args, base_url, {}, True) + with capfd.disabled(), pytest.raises(ValueError, + match=f"The parameter from has a negative value, from: {args.get('from')}'"): + cyble_events(client, 'POST', "some_random_token", url, args, {}, True, "random_collections", True) def test_get_alert_fetch(requests_mock): @@ -362,9 +360,47 @@ def test_get_alert_fetch(requests_mock): verify=False ) + args = { + 'from': 1, + 'limit': 1, + 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z") + } + + url = "https://test.com/apollo/api/v1/y/alerts" + + response, next = cyble_events(client, 'POST', "some_random_token", url, args, {}, False, "random_collections", False) + + assert isinstance(response, list) + assert len(response) == 1 + + +def test_get_alert_fetch2(requests_mock): + """ + Test the module fetch details + :param requests_mock: + :return: + """ + from CybleEventsV2 import Client, cyble_events + + mock_response_1 = util_load_json("dummy_fetch_incidents.json") + requests_mock.post('https://test.com/apollo/api/v1/y/alerts', json=mock_response_1) + + client = Client( + base_url='https://test.com', + verify=False + ) + + args = { + 'from': 1, + 'limit': 1, + 'start_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z"), + 'end_date': datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S%z") + } + url = "https://test.com/apollo/api/v1/y/alerts" - response, next = cyble_events(client, 'POST', "some_random_token", url, {}, 'https://test.com', {}, False) + response, next = cyble_events(client, 'POST', "some_random_token", url, args, {}, False, "random_collections", True) assert isinstance(response, list) assert len(response) == 1 @@ -395,7 +431,7 @@ def test_get_alert_output(requests_mock): url = "https://test.com/apollo/api/v1/y/alerts" - response, next = cyble_events(client, 'POST', "some_random_token", url, args, 'https://test.com', {}) + response, next = cyble_events(client, 'POST', "some_random_token", url, args, {}, False, "random_collections", False) assert isinstance(response, list) assert response[0]['alert_group_id'] == '00000000-0000-0000-0000-000000000000' @@ -416,7 +452,7 @@ def test_data_alert_invalidate_date(capfd): with capfd.disabled(): with pytest.raises(ValueError) as excinfo: validate_input(args=args) - assert str("does not match format") in str(excinfo) + assert "does not match format" in str(excinfo) def test_data_alert_iocs_date(capfd): @@ -432,7 +468,7 @@ def test_data_alert_iocs_date(capfd): with capfd.disabled(): with pytest.raises(ValueError) as excinfo: validate_input(args=args, is_iocs=True) - assert str("unconverted data remains") in str(excinfo) + assert "unconverted data remains" in str(excinfo) def test_get_subscribed_services_for_other_alert(requests_mock): @@ -453,3 +489,34 @@ def test_get_subscribed_services_for_other_alert(requests_mock): response = fetch_subscribed_services_alert(client, 'GET', 'https://test.com', "some_random_token").outputs assert isinstance(response, list) assert response[0]['name'] == 'name_1' + + +def test_update_incident(requests_mock): + """ + Test the module update-remote-system + :param requests_mock: + :return: + """ + from CybleEventsV2 import Client, cyble_events + + mock_response_1 = util_load_json("dummy_update_incident.json") + requests_mock.put('https://test.com/apollo/api/v1/y/alerts', json=mock_response_1) + + client = Client( + base_url='https://test.com', + verify=False + ) + + args = { + 'from': 0, + 'limit': 1, + 'start_date': '2023-09-18T00:00:00+00:00', + 'end_date': '2023-09-19T00:00:00+00:00' + } + + url = "https://test.com/apollo/api/v1/y/alerts" + + response, next = cyble_events(client, 'PUT', "some_random_token", url, args, {}, False, "random_collections", False) + + assert isinstance(response, list) + assert len(response) == 1 diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md b/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md index 6392aee318ff..22ebeab18f30 100644 --- a/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/README.md @@ -4,16 +4,19 @@ This integration was integrated and tested with version 2.0 of cybleeventsv2 ## Configure CybleEventsV2 on Cortex XSOAR 1. Navigate to **Settings** > **Integrations** > **Servers & Services**. -2. Search for CybleEventsV2. -3. Click **Add instance** to create and configure a new integration instance. - - | **Parameter** | **Description** | **Required** | - | --- | --- | --- | - | URL | Server URL \(e.g. ) | True | - | Access Token | Access Token | True | - | Trust any certificate (not secure) | | False | - | Use system proxy settings | | False | - | Incident Fetch Limit | Maximum incidents to be fetched every time. Upper limit is 50 incidents. | False | + Search for CybleEventsV2. + Click **Add instance** to create and configure a new integration instance. + + | **Parameter** | **Description** | **Required** | + |------------------------------------|-------------------------------------------------------------------------|--------------| + | URL | Server URL \(e.g., ) | True | + | Access Token | Access Token | True | + | Collections to Fetch | Select collections of incidents to be fetched from the dropdown menu | False | + | Trust any certificate (not secure) | | False | + | Use system proxy settings | | False | + | Incident Fetch Limit | Maximum incidents to be fetched every time. Upper limit is 50 incidents | False | + | Hide Card Details | Select to hide CVV and Expiry date of card | False | + | Update Incident to Remote System | Select to update changes in any incident to Vision | False | 4. To ensure that fetch incidents works: * Select the Fetches incidents radio button. @@ -41,9 +44,9 @@ There are no input arguments for this command. #### Context Output -| **Path** | **Type** | **Description** | -| --- | --- |-------------------------------------------------| -| CybleEvents.SubscribedServices | String | A list of subscribed services from Cyble vision | +| **Path** | **Type** | **Description** | +|--------------------------------|----------|-------------------------------------------------| +| CybleEvents.SubscribedServices | String | A list of subscribed services from Cyble vision | ### cyble-vision-fetch-iocs @@ -57,16 +60,16 @@ Fetch the indicators in the given timeline. #### Input | **Argument Name** | **Description** | **Required** | -|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------| --- | -| ioc_type | Returns records according to their type (Domain, FileHash-MD5, FileHash-SHA1, FileHash-SHA256, IPv4, IPv6, URL, Email). Default is Domain. | Optional | -| ioc | Returns records for the specified indicator value. | Optional | -| from | Returns records that starts from the given page number (the value of the form parameter) in the results list. Default is 0. | Optional | -| limit | Number of records to return (max 1000). Using a smaller limit will get faster responses. Default is 1. | Optional | -| sort_by | Sorting based on the column(last_seen,first_seen,ioc_type). Possible values are: last_seen, first_seen, ioc_type. Default is last_seen. | Optional | -| order | Sorting order for ioc either Ascending or Descending based on sort by. Default is desc. | Optional | -| tags | Returns records for the specified tags. | Optional | -| start_date | Timeline start date in the format "YYYY-MM-DD". Should be used with start_date as timeline range. | Optional | -| end_date | Timeline end date in the format "YYYY-MM-DD". Should be used with end_date as timeline range. | Optional | +|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------| +| ioc_type | Returns records according to their type (Domain, FileHash-MD5, FileHash-SHA1, FileHash-SHA256, IPv4, IPv6, URL, Email). Default is Domain. | Optional | +| ioc | Returns records for the specified indicator value. | Optional | +| from | Returns records that starts from the given page number (the value of the form parameter) in the results list. Default is 0. | Optional | +| limit | Number of records to return (max 1000). Using a smaller limit will get faster responses. Default is 1. | Optional | +| sort_by | Sorting based on the column(last_seen,first_seen,ioc_type). Possible values are: last_seen, first_seen, ioc_type. Default is last_seen. | Optional | +| order | Sorting order for ioc either Ascending or Descending based on sort by. Default is desc. | Optional | +| tags | Returns records for the specified tags. | Optional | +| start_date | Timeline start date in the format "YYYY-MM-DD". Should be used with start_date as timeline range. | Optional | +| end_date | Timeline end date in the format "YYYY-MM-DD". Should be used with end_date as timeline range. | Optional | #### Context Output diff --git a/Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_update_incident.json b/Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_update_incident.json new file mode 100644 index 000000000000..bbf65f895751 --- /dev/null +++ b/Packs/CybleEventsV2/Integrations/CybleEventsV2/test_data/dummy_update_incident.json @@ -0,0 +1,59 @@ +{ + "success": true, + "data": [{ + "created_at": "2023-09-11T11:51:55.509Z", + "updated_at": "2023-09-11T11:53:55.524Z", + "deleted_at": null, + "id": "00000000-0000-0000-0000-000000000000", + "data_message": "abc", + "hash": "00000000000000000000000000000000000000", + "data_id": "00000000-0000-0000-0000-000000000000", + "entity_id": 24251, + "entity_type": 0, + "service": "service", + "metadata": { + "created_at": "2023-09-11T11:51:03.799706412Z", + "entity": { + "entity_type": 0, + "entity_id": 24251, + "keyword": { + "id": 24251, + "tag_name": "tag_name", + "bucket_id": 441, + "company_id": 41, + "display_name": "keyword", + "created_at": "2021-11-01T07:53:20Z", + "updated_at": "2023-06-12T11:40:33Z", + "k_query": { + "query": { + "search_Keyword": "", + "search_by_file_name": "", + "search_by_language": "", + "search_by_extension": "", + "short_by": "", + "per_page": "" + } + }, + "queries": null + } + } + }, + "company_id": 10, + "priority": null, + "description": null, + "status": "UNDER_REVIEW", + "assignee_id": null, + "assignment_date": null, + "archived": false, + "archive_date": null, + "severity": "MEDIUM", + "updated_by_id": "00000000-0000-0000-0000-000000000000", + "created_by": null, + "tags": {}, + "user_severity": "MEDIUM", + "risk_score": null, + "ai_enriched": true, + "filter_enriched": false, + "alert_group_id": "00000000-0000-0000-0000-000000000000" + }] +} \ No newline at end of file diff --git a/Packs/CybleEventsV2/Layouts/layoutscontainer-Cyble_Vision_Alert_V2.json b/Packs/CybleEventsV2/Layouts/layoutscontainer-Cyble_Vision_Alert_V2.json index 0e41734b0081..b2b570602359 100644 --- a/Packs/CybleEventsV2/Layouts/layoutscontainer-Cyble_Vision_Alert_V2.json +++ b/Packs/CybleEventsV2/Layouts/layoutscontainer-Cyble_Vision_Alert_V2.json @@ -5,39 +5,653 @@ "system": false, "version": -1, "close": { + "sections": [] + }, + "fromVersion": "6.10.0", + "edit": { "sections": [ { "description": "", "fields": [ { - "fieldId": "incident_closereason", + "fieldId": "incident_name", + "isVisible": true + }, + { + "fieldId": "incident_type", + "isVisible": true + }, + { + "fieldId": "incident_severity", + "isVisible": true + }, + { + "fieldId": "incident_eventtype", "isVisible": true }, { - "fieldId": "incident_closenotes", + "fieldId": "incident_eventid", "isVisible": true } ], "isVisible": true, - "name": "Basic Information", + "name": "Incident Information", "query": null, "queryType": "", "readOnly": false, "type": "" + } + ] + }, + "detailsV2": { + "tabs": [ + { + "id": "summary", + "name": "Legacy Summary", + "type": "summary" }, { - "description": "", - "isVisible": true, - "name": "Custom Fields", - "query": null, - "queryType": "", - "readOnly": false, - "type": "" + "id": "caseinfoid", + "name": "Incident Info", + "sections": [ + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-field-changed-caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "isVisible": true, + "items": [ + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "name", + "height": 22, + "id": "6de4ba00-62f5-11ee-b822-35f227e570c5", + "index": 0, + "listId": "caseinfoid-field-changed-caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "type", + "height": 22, + "id": "a08d04d0-62f5-11ee-b822-35f227e570c5", + "index": 1, + "listId": "caseinfoid-field-changed-caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "severity", + "height": 22, + "id": "incident-severity-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "cybleeventsv2keyword", + "height": 22, + "id": "8e1b3d30-7a56-11ee-8189-632627f06ba5", + "index": 3, + "listId": "caseinfoid-field-changed-caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourcebrand", + "height": 22, + "id": "incident-sourceBrand-field", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourceinstance", + "height": 22, + "id": "incident-sourceInstance-field", + "index": 5, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Case Details", + "static": false, + "w": 1, + "x": 0, + "y": 0 + }, + { + "h": 2, + "i": "caseinfoid-field-changed-caseinfoid-61263cc0-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Notes", + "static": false, + "type": "notes", + "w": 1, + "x": 0, + "y": 6 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-field-changed-caseinfoid-6aabad20-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Work Plan", + "static": false, + "type": "workplan", + "w": 1, + "x": 0, + "y": 4 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-field-changed-caseinfoid-7ce69dd0-a07f-11e9-936c-5395a1acf11e", + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Indicators", + "query": "", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 2, + "x": 1, + "y": 4 + }, + { + "displayType": "CARD", + "h": 2, + "i": "caseinfoid-field-changed-caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", + "items": [ + { + "dropEffect": "move", + "endCol": 1, + "fieldId": "dbotcreated", + "height": 53, + "id": "incident-created-field", + "index": 0, + "listId": "caseinfoid-field-changed-caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 1, + "fieldId": "dbotmodified", + "height": 53, + "id": "incident-modified-field", + "index": 1, + "listId": "caseinfoid-field-changed-caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "occurred", + "height": 53, + "id": "f3eab960-62f5-11ee-b822-35f227e570c5", + "index": 0, + "listId": "caseinfoid-field-changed-caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", + "sectionItemType": "field", + "startCol": 1 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Timeline Information", + "static": false, + "w": 1, + "x": 0, + "y": 2 + }, + { + "displayType": "CARD", + "h": 4, + "i": "caseinfoid-field-changed-caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "isVisible": true, + "items": [ + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "eventtype", + "height": 53, + "id": "90bd78f0-62f5-11ee-b822-35f227e570c5", + "index": 0, + "listId": "caseinfoid-field-changed-caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "eventid", + "height": 53, + "id": "1ebcca70-62f6-11ee-b822-35f227e570c5", + "index": 1, + "listId": "caseinfoid-field-changed-caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "cybleeventsv2cardno", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "compromised_cards" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "3e4d2670-6349-11ee-a524-b7d5eab87dde", + "index": 2, + "listId": "caseinfoid-field-changed-caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "cybleeventsv2cardcvv", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "compromised_cards" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "3861a5b0-6349-11ee-a524-b7d5eab87dde", + "index": 3, + "listId": "caseinfoid-field-changed-caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "cybleeventsv2cardexpiry", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "compromised_cards" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "3acb52b0-6349-11ee-a524-b7d5eab87dde", + "index": 4, + "listId": "caseinfoid-field-changed-caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2cardbrand", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "compromised_cards" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "36e65050-6349-11ee-a524-b7d5eab87dde", + "index": 5, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2cardtype", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "compromised_cards" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "3f6ca030-6349-11ee-a524-b7d5eab87dde", + "index": 6, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2cardlevel", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "compromised_cards" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "3cbdfaf0-6349-11ee-a524-b7d5eab87dde", + "index": 7, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2application", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "stealer_logs" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "ab24daa0-7a22-11ee-b92f-3731270154f9", + "index": 8, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2password", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "stealer_logs" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "b3dd0ff0-7a22-11ee-b92f-3731270154f9", + "index": 9, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2url", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "stealer_logs" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "b56e1030-7a22-11ee-b92f-3731270154f9", + "index": 10, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2ceusername", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "stealer_logs" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "b6ca6be0-7a22-11ee-b92f-3731270154f9", + "index": 11, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cybleeventsv2cefilename", + "filters": [ + [ + { + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "eventtype" + } + }, + "operator": "isEqualString", + "right": { + "isContext": false, + "value": { + "simple": "stealer_logs" + } + }, + "type": "shortText" + } + ] + ], + "height": 53, + "id": "109183c0-7a23-11ee-b92f-3731270154f9", + "index": 12, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Investigation Data", + "static": false, + "w": 1, + "x": 1, + "y": 0 + }, + { + "displayType": "ROW", + "h": 4, + "hideItemTitleOnlyOne": false, + "hideName": false, + "i": "caseinfoid-field-changed-caseinfoid-300ae660-62fe-11ee-b633-db924c2e7426", + "items": [ + { + "endCol": 2, + "fieldId": "additionaldata", + "height": 22, + "id": "b0044d20-7a23-11ee-b92f-3731270154f9", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Additional Information", + "static": false, + "w": 1, + "x": 2, + "y": 0 + } + ], + "type": "custom" + }, + { + "id": "warRoom", + "name": "War Room", + "type": "warRoom" + }, + { + "id": "workPlan", + "name": "Work Plan", + "type": "workPlan" + }, + { + "id": "evidenceBoard", + "name": "Evidence Board", + "type": "evidenceBoard" + }, + { + "id": "relatedIncidents", + "name": "Related Incidents", + "type": "relatedIncidents" + }, + { + "id": "canvas", + "name": "Canvas", + "type": "canvas" } ] }, - "fromVersion": "6.2.0", - "edit": { + "quickView": { "sections": [ { "description": "", @@ -46,22 +660,6 @@ "fieldId": "incident_name", "isVisible": true }, - { - "fieldId": "incident_occurred", - "isVisible": true - }, - { - "fieldId": "incident_reminder", - "isVisible": true - }, - { - "fieldId": "incident_owner", - "isVisible": true - }, - { - "fieldId": "incident_roles", - "isVisible": true - }, { "fieldId": "incident_type", "isVisible": true @@ -71,28 +669,28 @@ "isVisible": true }, { - "fieldId": "incident_playbookid", + "fieldId": "incident_cybleeventsv2keyword", "isVisible": true }, { - "fieldId": "incident_labels", + "fieldId": "incident_sourcebrand", "isVisible": true }, { - "fieldId": "incident_phase", + "fieldId": "incident_sourceinstance", "isVisible": true }, { - "fieldId": "incident_details", + "fieldId": "incident_eventtype", "isVisible": true }, { - "fieldId": "incident_attachment", + "fieldId": "incident_eventid", "isVisible": true } ], "isVisible": true, - "name": "Basic Information", + "name": "Incident Information", "query": null, "queryType": "", "readOnly": false, @@ -102,728 +700,120 @@ "description": "", "fields": [ { - "fieldId": "incident_additionaldata", - "isVisible": true - }, - { - "fieldId": "incident_agentid", - "isVisible": true - }, - { - "fieldId": "incident_agentsid", - "isVisible": true - }, - { - "fieldId": "incident_agentversion", - "isVisible": true - }, - { - "fieldId": "incident_alertcategory", - "isVisible": true - }, - { - "fieldId": "incident_alertid", - "isVisible": true - }, - { - "fieldId": "incident_alertname", - "isVisible": true - }, - { - "fieldId": "incident_alertsource", - "isVisible": true - }, - { - "fieldId": "incident_alerttypeid", - "isVisible": true - }, - { - "fieldId": "incident_app", - "isVisible": true - }, - { - "fieldId": "incident_appchannelname", - "isVisible": true - }, - { - "fieldId": "incident_appmessage", - "isVisible": true - }, - { - "fieldId": "incident_assigneduser", - "isVisible": true - }, - { - "fieldId": "incident_assignmentgroup", - "isVisible": true - }, - { - "fieldId": "incident_birthday", - "isVisible": true - }, - { - "fieldId": "incident_caller", - "isVisible": true - }, - { - "fieldId": "incident_categories", - "isVisible": true - }, - { - "fieldId": "incident_changed", - "isVisible": true - }, - { - "fieldId": "incident_childprocess", - "isVisible": true - }, - { - "fieldId": "incident_classification", - "isVisible": true - }, - { - "fieldId": "incident_cloudaccountid", - "isVisible": true - }, - { - "fieldId": "incident_cloudinstanceid", - "isVisible": true - }, - { - "fieldId": "incident_cmd", - "isVisible": true - }, - { - "fieldId": "incident_cmdline", - "isVisible": true - }, - { - "fieldId": "incident_commandline", + "fieldId": "incident_dbotcreated", "isVisible": true }, { - "fieldId": "incident_comment", - "isVisible": true - }, - { - "fieldId": "incident_country", - "isVisible": true - }, - { - "fieldId": "incident_countrycode", - "isVisible": true - }, - { - "fieldId": "incident_countrycodenumber", - "isVisible": true - }, - { - "fieldId": "incident_dbotprediction", - "isVisible": true - }, - { - "fieldId": "incident_dbotpredictionprobability", - "isVisible": true - }, - { - "fieldId": "incident_description", - "isVisible": true - }, - { - "fieldId": "incident_destinationhostname", - "isVisible": true - }, - { - "fieldId": "incident_destinationip", - "isVisible": true - }, - { - "fieldId": "incident_destinationnetwork", - "isVisible": true - }, - { - "fieldId": "incident_destinationnetworks", - "isVisible": true - }, - { - "fieldId": "incident_destinationport", - "isVisible": true - }, - { - "fieldId": "incident_detectedendpoints", - "isVisible": true - }, - { - "fieldId": "incident_detectedips", - "isVisible": true - }, - { - "fieldId": "incident_detecteduser", - "isVisible": true - }, - { - "fieldId": "incident_detectionurl", - "isVisible": true - }, - { - "fieldId": "incident_deviceexternalip", - "isVisible": true - }, - { - "fieldId": "incident_deviceexternalips", - "isVisible": true - }, - { - "fieldId": "incident_devicehash", - "isVisible": true - }, - { - "fieldId": "incident_deviceid", - "isVisible": true - }, - { - "fieldId": "incident_deviceinternalips", - "isVisible": true - }, - { - "fieldId": "incident_devicelocalip", - "isVisible": true - }, - { - "fieldId": "incident_devicemacaddress", - "isVisible": true - }, - { - "fieldId": "incident_devicemodel", - "isVisible": true - }, - { - "fieldId": "incident_devicename", - "isVisible": true - }, - { - "fieldId": "incident_deviceosname", - "isVisible": true - }, - { - "fieldId": "incident_deviceosversion", + "fieldId": "incident_occurred", "isVisible": true }, { - "fieldId": "incident_deviceusername", + "fieldId": "incident_dbotmodified", "isVisible": true - }, + } + ], + "isVisible": true, + "name": "Timeline Information", + "query": null, + "queryType": "", + "readOnly": false, + "type": "" + }, + { + "description": "Compromised Card Details", + "fields": [ { - "fieldId": "incident_domainname", + "fieldId": "incident_cybleeventsv2cardno", "isVisible": true }, { - "fieldId": "incident_dsts", + "fieldId": "incident_cybleeventsv2cardcvv", "isVisible": true }, { - "fieldId": "incident_emaildeletefrombrand", + "fieldId": "incident_cybleeventsv2cardexpiry", "isVisible": true }, { - "fieldId": "incident_emaildeletereason", + "fieldId": "incident_cybleeventsv2cardbrand", "isVisible": true }, { - "fieldId": "incident_emaildeleteresult", + "fieldId": "incident_cybleeventsv2cardtype", "isVisible": true }, { - "fieldId": "incident_emaildeletetype", + "fieldId": "incident_cybleeventsv2cardlevel", "isVisible": true - }, + } + ], + "isVisible": true, + "name": "Compromised Card Details", + "query": null, + "queryType": "", + "readOnly": false, + "type": "" + }, + { + "description": "Compromised Endpoints Details", + "fields": [ { - "fieldId": "incident_endpoint", + "fieldId": "incident_cybleeventsv2application", "isVisible": true }, { - "fieldId": "incident_escalation", + "fieldId": "incident_cybleeventsv2password", "isVisible": true }, { - "fieldId": "incident_eventid", + "fieldId": "incident_cybleeventsv2url", "isVisible": true }, { - "fieldId": "incident_eventtype", + "fieldId": "incident_cybleeventsv2ceusername", "isVisible": true }, { - "fieldId": "incident_externalcategoryid", + "fieldId": "incident_cybleeventsv2cefilename", "isVisible": true - }, + } + ], + "isVisible": false, + "name": "Compromised Endpoints Details", + "query": null, + "queryType": "", + "readOnly": false, + "type": "" + }, + { + "description": "Additional Information", + "fields": [ { - "fieldId": "incident_externalcategoryname", + "fieldId": "incident_additionaldata", "isVisible": true - }, + } + ], + "isVisible": true, + "name": "Additional Information", + "query": null, + "queryType": "", + "readOnly": false, + "type": "" + }, + { + "description": "", + "fields": [ { - "fieldId": "incident_externalconfidence", - "isVisible": true - }, - { - "fieldId": "incident_externalendtime", - "isVisible": true - }, - { - "fieldId": "incident_externallink", - "isVisible": true - }, - { - "fieldId": "incident_externalseverity", - "isVisible": true - }, - { - "fieldId": "incident_externalstarttime", - "isVisible": true - }, - { - "fieldId": "incident_externalstatus", - "isVisible": true - }, - { - "fieldId": "incident_externalsubcategoryid", - "isVisible": true - }, - { - "fieldId": "incident_externalsubcategoryname", - "isVisible": true - }, - { - "fieldId": "incident_externalsystemid", - "isVisible": true - }, - { - "fieldId": "incident_filehash", - "isVisible": true - }, - { - "fieldId": "incident_filemd5", - "isVisible": true - }, - { - "fieldId": "incident_filename", - "isVisible": true - }, - { - "fieldId": "incident_filenames", - "isVisible": true - }, - { - "fieldId": "incident_filepath", - "isVisible": true - }, - { - "fieldId": "incident_filepaths", - "isVisible": true - }, - { - "fieldId": "incident_filesha1", - "isVisible": true - }, - { - "fieldId": "incident_filesha256", - "isVisible": true - }, - { - "fieldId": "incident_filesize", - "isVisible": true - }, - { - "fieldId": "incident_firstname", - "isVisible": true - }, - { - "fieldId": "incident_fullname", - "isVisible": true - }, - { - "fieldId": "incident_hostnames", - "isVisible": true - }, - { - "fieldId": "incident_incidentlink", - "isVisible": true - }, - { - "fieldId": "incident_incomingmirrorerror", - "isVisible": true - }, - { - "fieldId": "incident_investigationstage", - "isVisible": true - }, - { - "fieldId": "incident_isactive", - "isVisible": true - }, - { - "fieldId": "incident_lastname", - "isVisible": true - }, - { - "fieldId": "incident_logsource", - "isVisible": true - }, - { - "fieldId": "incident_lowlevelcategoriesevents", - "isVisible": true - }, - { - "fieldId": "incident_macaddress", - "isVisible": true - }, - { - "fieldId": "incident_md5", - "isVisible": true - }, - { - "fieldId": "incident_mitretacticid", - "isVisible": true - }, - { - "fieldId": "incident_mitretacticname", - "isVisible": true - }, - { - "fieldId": "incident_mitretechniqueid", - "isVisible": true - }, - { - "fieldId": "incident_mitretechniquename", - "isVisible": true - }, - { - "fieldId": "incident_mobiledevicemodel", - "isVisible": true - }, - { - "fieldId": "incident_objective", - "isVisible": true - }, - { - "fieldId": "incident_orglevel1", - "isVisible": true - }, - { - "fieldId": "incident_orglevel2", - "isVisible": true - }, - { - "fieldId": "incident_orglevel3", - "isVisible": true - }, - { - "fieldId": "incident_orgunit", - "isVisible": true - }, - { - "fieldId": "incident_os", - "isVisible": true - }, - { - "fieldId": "incident_ostype", - "isVisible": true - }, - { - "fieldId": "incident_osversion", - "isVisible": true - }, - { - "fieldId": "incident_outgoingmirrorerror", - "isVisible": true - }, - { - "fieldId": "incident_parentcmdline", - "isVisible": true - }, - { - "fieldId": "incident_parentprocess", - "isVisible": true - }, - { - "fieldId": "incident_parentprocesscmd", - "isVisible": true - }, - { - "fieldId": "incident_parentprocessfilepath", - "isVisible": true - }, - { - "fieldId": "incident_parentprocessids", - "isVisible": true - }, - { - "fieldId": "incident_parentprocessmd5", - "isVisible": true - }, - { - "fieldId": "incident_parentprocessname", - "isVisible": true - }, - { - "fieldId": "incident_parentprocesspath", - "isVisible": true - }, - { - "fieldId": "incident_parentprocesssha256", - "isVisible": true - }, - { - "fieldId": "incident_phonenumber", - "isVisible": true - }, - { - "fieldId": "incident_pid", - "isVisible": true - }, - { - "fieldId": "incident_policyactions", - "isVisible": true - }, - { - "fieldId": "incident_processcmd", - "isVisible": true - }, - { - "fieldId": "incident_processcreationtime", - "isVisible": true - }, - { - "fieldId": "incident_processid", - "isVisible": true - }, - { - "fieldId": "incident_processmd5", - "isVisible": true - }, - { - "fieldId": "incident_processname", - "isVisible": true - }, - { - "fieldId": "incident_processnames", - "isVisible": true - }, - { - "fieldId": "incident_processpath", - "isVisible": true - }, - { - "fieldId": "incident_processpaths", - "isVisible": true - }, - { - "fieldId": "incident_processsha256", - "isVisible": true - }, - { - "fieldId": "incident_protocol", - "isVisible": true - }, - { - "fieldId": "incident_protocolnames", - "isVisible": true - }, - { - "fieldId": "incident_registryhive", - "isVisible": true - }, - { - "fieldId": "incident_registrykey", - "isVisible": true - }, - { - "fieldId": "incident_registryvalue", - "isVisible": true - }, - { - "fieldId": "incident_registryvaluetype", - "isVisible": true - }, - { - "fieldId": "incident_renderedhtml", - "isVisible": true - }, - { - "fieldId": "incident_rulename", - "isVisible": true - }, - { - "fieldId": "incident_scenario", - "isVisible": true - }, - { - "fieldId": "incident_sha1", - "isVisible": true - }, - { - "fieldId": "incident_sha256", - "isVisible": true - }, - { - "fieldId": "incident_sha512", - "isVisible": true - }, - { - "fieldId": "incident_similarincidents", - "isVisible": true - }, - { - "fieldId": "incident_similarincidentsdbot", - "isVisible": true - }, - { - "fieldId": "incident_sourcecategory", - "isVisible": true - }, - { - "fieldId": "incident_sourcecreatedby", - "isVisible": true - }, - { - "fieldId": "incident_sourceexternalips", - "isVisible": true - }, - { - "fieldId": "incident_sourcehostname", - "isVisible": true - }, - { - "fieldId": "incident_sourceip", - "isVisible": true - }, - { - "fieldId": "incident_sourcenetwork", - "isVisible": true - }, - { - "fieldId": "incident_sourcenetworks", - "isVisible": true - }, - { - "fieldId": "incident_sourceport", - "isVisible": true - }, - { - "fieldId": "incident_sourcepriority", - "isVisible": true - }, - { - "fieldId": "incident_sourcestatus", - "isVisible": true - }, - { - "fieldId": "incident_sourceusername", - "isVisible": true - }, - { - "fieldId": "incident_srcs", - "isVisible": true - }, - { - "fieldId": "incident_state", - "isVisible": true - }, - { - "fieldId": "incident_subcategory", - "isVisible": true - }, - { - "fieldId": "incident_tactic", - "isVisible": true - }, - { - "fieldId": "incident_tacticid", - "isVisible": true - }, - { - "fieldId": "incident_tags", - "isVisible": true - }, - { - "fieldId": "incident_teamname", - "isVisible": true - }, - { - "fieldId": "incident_technique", - "isVisible": true - }, - { - "fieldId": "incident_techniqueid", - "isVisible": true - }, - { - "fieldId": "incident_tenantname", - "isVisible": true - }, - { - "fieldId": "incident_threatfamilyname", - "isVisible": true - }, - { - "fieldId": "incident_threathuntingdetectedhostnames", - "isVisible": true - }, - { - "fieldId": "incident_threathuntingdetectedip", - "isVisible": true - }, - { - "fieldId": "incident_threatname", - "isVisible": true - }, - { - "fieldId": "incident_ticketacknowledgeddate", - "isVisible": true - }, - { - "fieldId": "incident_ticketcloseddate", - "isVisible": true - }, - { - "fieldId": "incident_ticketnumber", - "isVisible": true - }, - { - "fieldId": "incident_ticketopeneddate", - "isVisible": true - }, - { - "fieldId": "incident_urls", - "isVisible": true - }, - { - "fieldId": "incident_urlsslverification", - "isVisible": true - }, - { - "fieldId": "incident_usecasedescription", - "isVisible": true - }, - { - "fieldId": "incident_useraccountcontrol", - "isVisible": true - }, - { - "fieldId": "incident_users", - "isVisible": true - }, - { - "fieldId": "incident_usersid", + "fieldId": "incident_labels", "isVisible": true } ], "isVisible": true, - "name": "Custom Fields", + "name": "Labels", "query": null, "queryType": "", - "readOnly": false, - "type": "" + "readOnly": true, + "type": "labels" } ] }, diff --git a/Packs/CybleEventsV2/ReleaseNotes/1_0_2.md b/Packs/CybleEventsV2/ReleaseNotes/1_0_2.md new file mode 100644 index 000000000000..5998538b86b6 --- /dev/null +++ b/Packs/CybleEventsV2/ReleaseNotes/1_0_2.md @@ -0,0 +1,52 @@ +#### Integrations + +##### CybleEvents v2 + +- Updated the Docker image to: *demisto/python3:3.10.13.80014*. +- Added the outgoing mirroring functionality. +- Fixed an issue with incident fetching from a remote server that was causing duplicate alerts. +- Added a functionality to hide card details. +- Improved implementation by changing sorting order of IOCs from descending to ascending. +- Improved implementation by changing sorting order of fetched alerts from descending to ascending. +- Added a new functionality to select incident collection to be fetched. + + +#### Layouts + +##### Cyble Vision Alert V2 + +- Fixed an issue with layout visualization. + + +#### Mappers + +##### New: CybleEventsv2-Incoming-Mapper + +- New incoming mapper for better visualization of incidents. + +##### New: CybleEventsv2-Outgoing-Mapper + +- New outgoing mapper for mirroring functionality. + + +#### Incident Fields + +- New: **CybleEventsV2 Application** +- New: **CybleEventsV2 CE Filename** +- New: **CybleEventsV2 CE Username** +- New: **CybleEventsV2 Card Brand** +- New: **CybleEventsV2 Card CVV** +- New: **CybleEventsV2 Card Expiry** +- New: **CybleEventsV2 Card Level** +- New: **CybleEventsV2 Card No.** +- New: **CybleEventsV2 Card Type** +- New: **CybleEventsV2 Keyword** +- New: **CybleEventsV2 Password** +- New: **CybleEventsV2 URL** + + +#### Incident Types + +##### Cyble Vision Alert V2 + +- Fixed an issue by removing playbook's execution and autorun. \ No newline at end of file diff --git a/Packs/CybleEventsV2/doc_files/Cyble_Vision_Alert_V2.png b/Packs/CybleEventsV2/doc_files/Cyble_Vision_Alert_V2.png new file mode 100644 index 0000000000000000000000000000000000000000..d1ffcfa38e153a363e950fa35ea1b755b2567110 GIT binary patch literal 29813 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 TZ3X;}DAo;SEp(-#dD#B}w`_Et literal 0 HcmV?d00001 diff --git a/Packs/CybleEventsV2/doc_files/Cyble_Vision_Alert_V2_Wed_Apr_26_2023.png b/Packs/CybleEventsV2/doc_files/Cyble_Vision_Alert_V2_Wed_Apr_26_2023.png deleted file mode 100644 index 64d34eb4f5cb3ff29e15852d0be962129cd56dc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20028 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 sl$@&}p^cZpArhIEY{@z^2f>ass%yc0uWCjdm