From 3cb67f062fdf38181f2729c23024c3129b19cf86 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 21 May 2024 18:06:17 +0200 Subject: [PATCH 01/27] [feedly] Fix new intrusion set objects --- .../Integrations/FeedFeedly/FeedFeedly.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index 56c98fc38959..9d84a8e9ef2b 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -246,14 +246,20 @@ def parse_indicator(self, indicator_obj: dict[str, Any]) -> list[dict[str, Any]] indicators.extend( self.get_indicators_from_indicator_groups( - indicator_groups, indicator_obj, STIX_2_TYPES_TO_CORTEX_TYPES, field_map, + indicator_groups, + indicator_obj, + STIX_2_TYPES_TO_CORTEX_TYPES, + field_map, ) ) cidr_groups = self.extract_indicator_groups_from_pattern(trimmed_pattern, self.cidr_regexes) indicators.extend( self.get_indicators_from_indicator_groups( - cidr_groups, indicator_obj, STIX_2_TYPES_TO_CORTEX_CIDR_TYPES, field_map, + cidr_groups, + indicator_obj, + STIX_2_TYPES_TO_CORTEX_CIDR_TYPES, + field_map, ) ) self.change_ip_to_cidr(indicators) @@ -540,6 +546,7 @@ def parse_intrusion_set(intrusion_set_obj: dict[str, Any]) -> list[dict[str, Any "primary_motivation": intrusion_set_obj.get("primary_motivation", ""), "secondary_motivations": intrusion_set_obj.get("secondary_motivations", []), "publications": publications, + "tags": list(set(intrusion_set_obj.get("labels", []))), } intrusion_set["customFields"] = fields return [intrusion_set] @@ -691,7 +698,7 @@ def parse_relationships(self, relationships_lst: list[dict[str, Any]]) -> dict[s for ref in b_object["rawJSON"].get("external_references", []) if ref.get("source_name") == "mitre-attack" ) - a_object["customFields"]["tags"].append(mitre_id) + a_object["customFields"].setdefault("tags", []).append(mitre_id) mapping_fields = { "lastseenbysource": relationships_object.get("modified"), @@ -935,7 +942,7 @@ def get_indicators_command( indicators = client.fetch_indicators_from_stream( params["feedly_stream_id"], newer_than=time.time() - 24 * 3600, limit=int(args.get("limit", "10")) ) - demisto.createIndicators(indicators) + demisto.createIndicators(indicators) # type: ignore return CommandResults(readable_output=f"Created {len(indicators)} indicators.") @@ -949,7 +956,7 @@ def fetch_indicators_command(client: Client, params: dict[str, str], context: di Indicators. """ return client.fetch_indicators_from_stream( - params["feedly_stream_id"], newer_than=float(context.get("last_successful_run", time.time() - 7 * 24 * 3600)), + params["feedly_stream_id"], newer_than=float(context.get("last_successful_run", time.time() - 7 * 24 * 3600)) ) @@ -979,7 +986,7 @@ def main(): # pragma: no cover now = time.time() indicators = fetch_indicators_command(client, params, demisto.getLastRun()) for indicators_batch in batch(indicators, batch_size=2000): - demisto.createIndicators(indicators_batch) + demisto.createIndicators(indicators_batch) # type: ignore demisto.setLastRun({"last_successful_run": str(now)}) else: From 8550c2a9bcac51fb199cce7d7fd88d3e5248f999 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 21 May 2024 18:53:02 +0200 Subject: [PATCH 02/27] [feedly] update image version --- Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml index ab8cac63bf3d..8b4b6a214bd6 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml @@ -117,7 +117,7 @@ script: description: Gets indicators from the feed. execution: false name: feedly-get-indicators - dockerimage: demisto/python3:3.10.13.84405 + dockerimage: demisto/python3:3.10.14.94490 feed: true isfetch: false longRunning: false From 7c21a9c710328ccb3e894f11332c33f8ae7398d1 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Wed, 22 May 2024 13:22:14 +0200 Subject: [PATCH 03/27] [feedly] parse vulnerabilities --- .../Integrations/FeedFeedly/FeedFeedly.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index 9d84a8e9ef2b..81b6edbcf2fb 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -63,6 +63,7 @@ "sha-1": FeedIndicatorType.File, "sha-256": FeedIndicatorType.File, "file:hashes": FeedIndicatorType.File, + "vulnerability": FeedIndicatorType.CVE, "attack-pattern": ThreatIntel.ObjectsNames.ATTACK_PATTERN, "malware": ThreatIntel.ObjectsNames.MALWARE, "tool": ThreatIntel.ObjectsNames.TOOL, @@ -176,6 +177,7 @@ class STIX2Parser: "windows-registry-key", "relationship", "extension-definition", + "vulnerability", ] def __init__(self): @@ -658,6 +660,31 @@ def parse_sco_windows_registry_key_indicator(registry_key_obj: dict[str, Any]) - ) return registry_key_indicator + @staticmethod + def parse_vulnerability(vulnerability_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses vulnerability indicator type to cortex format. + + Args: + vulnerability_obj (dict): indicator as an observable object of vulnerability type. + """ + vulnerability = { + "value": vulnerability_obj.get("name"), + "indicator_type": FeedIndicatorType.CVE, + "rawJSON": vulnerability_obj, + } + fields = { + "stixid": vulnerability_obj.get("id"), + "firstseenbysource": vulnerability_obj.get("created"), + "modified": vulnerability_obj.get("modified"), + "description": vulnerability_obj.get("description", ""), + "external_references": vulnerability_obj.get("external_references", []), + "tags": list(set(vulnerability_obj.get("labels", []))), + } + + vulnerability["customFields"] = fields + return [vulnerability] + def parse_relationships(self, relationships_lst: list[dict[str, Any]]) -> dict[str, Any]: """Parse the Relationships objects retrieved from the feed. @@ -753,6 +780,7 @@ def load_stix_objects_from_envelope(self, envelopes: dict[str, Any]): "mutex": self.parse_sco_mutex_indicator, "user-account": self.parse_sco_account_indicator, "windows-registry-key": self.parse_sco_windows_registry_key_indicator, + "vulnerability": self.parse_vulnerability, } indicators = self.parse_dict_envelope(envelopes, parse_stix_2_objects) return indicators From 349022c5f8446b48117b34174821b6db6758ab09 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Wed, 22 May 2024 13:22:55 +0200 Subject: [PATCH 04/27] [feedly] update version --- Packs/FeedFeedly/ReleaseNotes/1_0_3.md | 5 +++++ Packs/FeedFeedly/pack_metadata.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Packs/FeedFeedly/ReleaseNotes/1_0_3.md diff --git a/Packs/FeedFeedly/ReleaseNotes/1_0_3.md b/Packs/FeedFeedly/ReleaseNotes/1_0_3.md new file mode 100644 index 000000000000..bea2b373a523 --- /dev/null +++ b/Packs/FeedFeedly/ReleaseNotes/1_0_3.md @@ -0,0 +1,5 @@ +#### Integrations +##### Feedly Feed +- Updated the Docker image to: *demisto/python3:3.10.14.94490*. +- Fixed an issue with the labels of the intrusion sets. +- Adding support for vulnerabilities diff --git a/Packs/FeedFeedly/pack_metadata.json b/Packs/FeedFeedly/pack_metadata.json index d66fb1d2bb78..7e4205acc8c2 100644 --- a/Packs/FeedFeedly/pack_metadata.json +++ b/Packs/FeedFeedly/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Feedly", "description": "Import Articles from Feedly with enriched IOCs", "support": "partner", - "currentVersion": "1.0.2", + "currentVersion": "1.0.3", "author": "Feedly", "url": "https://feedly.com/i/landing/threatIntelligence", "email": "support@feedly.com", From 01a408617e08ae096ea865556bf92231d93d6a81 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Mon, 7 Oct 2024 14:35:10 +0200 Subject: [PATCH 05/27] [feedly] (incidents) WIP --- .../IncidentsFeedly/IncidentsFeedly.py | 31 +++++++++ .../IncidentsFeedly/IncidentsFeedly.yml | 62 ++++++++++++++++++ .../IncidentsFeedly/IncidentsFeedly_image.png | Bin 0 -> 6623 bytes 3 files changed, 93 insertions(+) create mode 100644 Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py create mode 100644 Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml create mode 100644 Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_image.png diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py new file mode 100644 index 000000000000..756bfc1a3f61 --- /dev/null +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py @@ -0,0 +1,31 @@ +import random + +from CommonServerPython import * # noqa: F401 + + +def fetch_incidents() -> list[dict]: + event_id = random.randint(1, 1000000) + events = [ + { + "name": f"event_test_{event_id}", + "create_time": datetime.now().isoformat(), + "event_id": event_id, + }, + ] + + incidents = [] + for event in events: + incident = { + "name": event["name"], + "occured": event["create_time"], + "dbotMirrorId": str(event["event_id"]), + "rawJSON": json.dumps(event), + } + incidents.append(incident) + return incidents + + +def main() -> None: + command = demisto.command() + if command == "fetch-incidents": + demisto.incidents(fetch_incidents()) diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml new file mode 100644 index 000000000000..ec01820b65dc --- /dev/null +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml @@ -0,0 +1,62 @@ +fromversion: 6.11.0 +category: Data Enrichment & Threat Intelligence +sectionOrder: +- Connect +- Collect +commonfields: + id: IncidentsFeedly + version: -1 +configuration: +- displaypassword: API key + name: credentials + type: 9 + required: true + hiddenusername: true + section: Connect +- display: Trust any certificate (not secure) + name: insecure + required: false + type: 8 + section: Connect + advanced: true +- display: Use system proxy settings + name: proxy + required: false + type: 8 + section: Connect + advanced: true +- display: Fetch incidents + name: isFetch + type: 8 + section: Collect +- display: Maximum number of incidents per fetch + defaultvalue: '50' + name: max_fetch + type: 0 + required: false + section: Collect +- display: Days to fetch for first run + name: days_to_backfill + required: true + type: 0 + defaultvalue: '7' + additionalinfo: Number of days to fetch articles from when running the integration for the first time + section: Collect +description: 'Fetch Feedly reports as incidents.' +display: IncidentsFeedly +name: IncidentsFeedly +script: + commands: + - name: fetch-incidents + description: Fetch Feedly reports as incidents. + dockerimage: demisto/python3:3.11.9.105369 + feed: false + isfetch: true + longRunning: false + longRunningPort: false + runonce: false + script: '-' + subtype: python3 + type: python +tests: +- No tests (auto formatted). \ No newline at end of file diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_image.png b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_image.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e4955a727c6c809bdac45bd248bae29ab3574d GIT binary patch literal 6623 zcmY*;1yo#3v+WETAV84d!QCymYj7v%0D(b*O@Kjy6C}7>a1RnJxRV5z!9BP;gA5Yj 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 HV;=NBMK_#I literal 0 HcmV?d00001 From 2b185272d73f97f9c7c019c5ee4509dbfa2a8d09 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Wed, 30 Oct 2024 12:15:48 -0700 Subject: [PATCH 06/27] [feedly] first version of the integration to ingest reports as incidents --- .../classifier-Feedly_-_Report_Mapper.json | 90 ++ .../IncidentFields/incident_customfields.json | 248 ++++ .../IncidentTypes/customIncidentTypes.json | 121 ++ .../Integrations/FeedFeedly/FeedFeedly.py | 5 +- .../IncidentsFeedly/IncidentsFeedly.py | 1029 ++++++++++++++++- .../IncidentsFeedly/IncidentsFeedly.yml | 15 +- .../layoutscontainer-Feedly_Report.json | 723 ++++++++++++ 7 files changed, 2209 insertions(+), 22 deletions(-) create mode 100644 Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json create mode 100644 Packs/FeedFeedly/IncidentFields/incident_customfields.json create mode 100644 Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json create mode 100644 Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json diff --git a/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json b/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json new file mode 100644 index 000000000000..f1c0167cdfd2 --- /dev/null +++ b/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json @@ -0,0 +1,90 @@ +{ + "brands": null, + "cacheVersn": 0, + "defaultIncidentType": "", + "definitionId": "", + "description": "", + "feed": false, + "fromServerVersion": "", + "id": "610827cc-e32a-4caf-84b3-8c91fbee7fd0", + "incidentSamples": null, + "indicatorSamples": null, + "instanceIds": null, + "itemVersion": "", + "keyTypeMap": {}, + "locked": false, + "logicalVersion": 8, + "mapping": { + "dbot_classification_incident_type_all": { + "dontMapEventToLabels": true, + "internalMapping": { + "Additional Email Addresses": { + "simple": "indicators.Email" + }, + "CVE List": { + "simple": "indicators.CVE" + }, + "Detected IPs": { + "simple": "indicators.IP" + }, + "Domain Name": { + "simple": "indicators.Domain" + }, + "Event ID": { + "simple": "event_id" + }, + "Feedly crawled date": { + "simple": "create_time" + }, + "Feedly url": { + "simple": "feedly_url" + }, + "File MD5": { + "simple": "indicators.File" + }, + "MITRE Technique ID": { + "simple": "indicators.TTP" + }, + "MITRE Technique Name": { + "simple": "indicators.Attack Pattern" + }, + "Source name": { + "simple": "source.name" + }, + "Source url": { + "simple": "source.url" + }, + "Tags": { + "complex": { + "filters": [], + "root": "tags", + "transformers": [] + } + }, + "URLs": { + "simple": "indicators.URL" + }, + "Use Case Description": { + "simple": "content" + }, + "name": { + "simple": "name" + } + } + } + }, + "name": "Feedly - Report Mapper", + "nameRaw": "Feedly - Report Mapper", + "packID": "", + "packName": "", + "propagationLabels": [ + "all" + ], + "sourceClassifierId": "", + "system": false, + "toServerVersion": "", + "transformer": {}, + "type": "mapping-incoming", + "unclassifiedCases": null, + "version": -1 +} \ No newline at end of file diff --git a/Packs/FeedFeedly/IncidentFields/incident_customfields.json b/Packs/FeedFeedly/IncidentFields/incident_customfields.json new file mode 100644 index 000000000000..0dbd96a9637d --- /dev/null +++ b/Packs/FeedFeedly/IncidentFields/incident_customfields.json @@ -0,0 +1,248 @@ +{ + "incidentFields": [ + { + "id": "incident_feedlycrawleddate", + "version": 1, + "cacheVersn": 0, + "modified": "2024-10-10T12:19:12.752862283Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Feedly crawled date", + "prevName": "Feedly crawled date", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "feedlycrawleddate", + "type": "shortText", + "orgType": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": null, + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": false, + "associatedTypes": null, + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" + }, + { + "id": "incident_feedlyurl", + "version": 3, + "cacheVersn": 0, + "modified": "2024-10-10T14:33:09.220777761Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Feedly url", + "prevName": "Feedly url", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "feedlyurl", + "type": "url", + "orgType": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": [], + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": false, + "associatedTypes": [], + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" + }, + { + "id": "incident_sourcename", + "version": 2, + "cacheVersn": 0, + "modified": "2024-10-10T12:23:08.304820086Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Source name", + "prevName": "Source name", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "sourcename", + "type": "shortText", + "orgType": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": [], + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": false, + "associatedTypes": [], + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" + }, + { + "id": "incident_sourceurl", + "version": 3, + "cacheVersn": 0, + "modified": "2024-10-10T14:33:25.185611243Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Source url", + "prevName": "Source url", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "sourceurl", + "type": "url", + "orgType": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": [], + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": false, + "associatedTypes": [], + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" + } + ] +} \ No newline at end of file diff --git a/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json b/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json new file mode 100644 index 000000000000..f10b28d3edd2 --- /dev/null +++ b/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json @@ -0,0 +1,121 @@ +[ + { + "id": "Feedly Report", + "version": 6, + "cacheVersn": 0, + "modified": "2024-10-10T13:51:44.813997902Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "locked": false, + "name": "Feedly Report", + "prevName": "Feedly Report", + "color": "#F8E7A5", + "hours": 0, + "days": 0, + "weeks": 0, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "preProcessingScript": "", + "closureScript": "", + "disabled": false, + "reputationCalc": 0, + "onChangeRepAlg": 0, + "layout": "e53027fa-56c1-4521-8c38-822af5c0f6de", + "detached": false, + "extractSettings": { + "mode": "Specific", + "fieldCliNameToExtractSettings": { + "additionalemailaddresses": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "emailRep" + ] + }, + "cvelist": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "cveRep" + ] + }, + "detectedips": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "ipRep" + ] + }, + "domainname": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "domainRepUnified" + ] + }, + "filemd5": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "unifiedFileRep" + ] + }, + "filesha1": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "unifiedFileRep" + ] + }, + "filesha256": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "unifiedFileRep" + ] + }, + "mitretechniqueid": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "Attack Pattern" + ] + }, + "mitretechniquename": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "Attack Pattern" + ] + }, + "selectedindicators": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": true, + "extractIndicatorTypesIDs": [] + }, + "urls": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "urlRep" + ] + } + } + } + } +] \ No newline at end of file diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index 81b6edbcf2fb..8955e3b135e0 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -984,7 +984,10 @@ def fetch_indicators_command(client: Client, params: dict[str, str], context: di Indicators. """ return client.fetch_indicators_from_stream( - params["feedly_stream_id"], newer_than=float(context.get("last_successful_run", time.time() - 7 * 24 * 3600)) + params["feedly_stream_id"], + newer_than=float( + context.get("last_successful_run", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600) + ), ) diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py index 756bfc1a3f61..64e5b53f383c 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py @@ -1,31 +1,1020 @@ -import random +import copy +from collections import defaultdict +from contextlib import suppress +from urllib.parse import parse_qs from CommonServerPython import * # noqa: F401 +FEEDLY_BASE_URL = "https://api.feedly.com" -def fetch_incidents() -> list[dict]: - event_id = random.randint(1, 1000000) - events = [ - { - "name": f"event_test_{event_id}", - "create_time": datetime.now().isoformat(), - "event_id": event_id, - }, + +# Constants copied from the command StixParser +DFLT_LIMIT_PER_REQUEST = 100 +API_USERNAME = "_api_token_key" +HEADER_USERNAME = "_header:" +SYSTEM_FIELDS = [ + "id", + "version", + "modified", + "sortValues", + "timestamp", + "indicator_type", + "value", + "sourceInstances", + "sourceBrands", + "investigationIDs", + "lastSeen", + "firstSeen", + "firstSeenEntryID", + "score", + "insightCache", + "moduleToFeedMap", + "expirationStatus", + "expirationSource", + "calculatedTime", + "lastReputationRun", + "modifiedTime", + "aggregatedReliability", +] + +DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" + +# Pattern Regexes - used to extract indicator type and value, spaces are removed before matching the following regexes +INDICATOR_OPERATOR_VAL_FORMAT_PATTERN = r"(\w.*?{value}{operator})'(.*?)'" +INDICATOR_IN_VAL_PATTERN = r"(\w.*?valueIN)\(+('.*?')\)" +INDICATOR_EQUALS_VAL_PATTERN = INDICATOR_OPERATOR_VAL_FORMAT_PATTERN.format(value="value", operator="=") +CIDR_ISSUBSET_VAL_PATTERN = INDICATOR_OPERATOR_VAL_FORMAT_PATTERN.format(value="value", operator="ISSUBSET") +CIDR_ISUPPERSET_VAL_PATTERN = INDICATOR_OPERATOR_VAL_FORMAT_PATTERN.format(value="value", operator="ISSUPPERSET") +HASHES_EQUALS_VAL_PATTERN = INDICATOR_OPERATOR_VAL_FORMAT_PATTERN.format(value=r"hashes\..*?", operator="=") +REGISTRY_EQUALS_VAL_PATTERN = INDICATOR_OPERATOR_VAL_FORMAT_PATTERN.format(value="key", operator="=") + + +STIX_2_TYPES_TO_CORTEX_TYPES = { + "mutex": FeedIndicatorType.MUTEX, + "windows-registry-key": FeedIndicatorType.Registry, + "user-account": FeedIndicatorType.Account, + "email-addr": FeedIndicatorType.Email, + "autonomous-system": FeedIndicatorType.AS, + "ipv4-addr": FeedIndicatorType.IP, + "ipv6-addr": FeedIndicatorType.IPv6, + "domain": FeedIndicatorType.Domain, + "domain-name": FeedIndicatorType.Domain, + "url": FeedIndicatorType.URL, + "file": FeedIndicatorType.File, + "md5": FeedIndicatorType.File, + "sha-1": FeedIndicatorType.File, + "sha-256": FeedIndicatorType.File, + "file:hashes": FeedIndicatorType.File, + "vulnerability": FeedIndicatorType.CVE, + "attack-pattern": ThreatIntel.ObjectsNames.ATTACK_PATTERN, + "malware": ThreatIntel.ObjectsNames.MALWARE, + "tool": ThreatIntel.ObjectsNames.TOOL, + "report": "Feedly Report", + "threat-actor": ThreatIntel.ObjectsNames.THREAT_ACTOR, + "course-of-action": ThreatIntel.ObjectsNames.COURSE_OF_ACTION, + "campaign": ThreatIntel.ObjectsNames.CAMPAIGN, + "infrastructure": ThreatIntel.ObjectsNames.INFRASTRUCTURE, + "intrusion-set": ThreatIntel.ObjectsNames.INTRUSION_SET, +} + +MITRE_CHAIN_PHASES_TO_DEMISTO_FIELDS = { + "build-capabilities": ThreatIntel.KillChainPhases.BUILD_CAPABILITIES, + "privilege-escalation": ThreatIntel.KillChainPhases.PRIVILEGE_ESCALATION, + "adversary-opsec": ThreatIntel.KillChainPhases.ADVERSARY_OPSEC, + "credential-access": ThreatIntel.KillChainPhases.CREDENTIAL_ACCESS, + "exfiltration": ThreatIntel.KillChainPhases.EXFILTRATION, + "lateral-movement": ThreatIntel.KillChainPhases.LATERAL_MOVEMENT, + "defense-evasion": ThreatIntel.KillChainPhases.DEFENSE_EVASION, + "persistence": ThreatIntel.KillChainPhases.PERSISTENCE, + "collection": ThreatIntel.KillChainPhases.COLLECTION, + "impact": ThreatIntel.KillChainPhases.IMPACT, + "initial-access": ThreatIntel.KillChainPhases.INITIAL_ACCESS, + "discovery": ThreatIntel.KillChainPhases.DISCOVERY, + "execution": ThreatIntel.KillChainPhases.EXECUTION, + "installation": ThreatIntel.KillChainPhases.INSTALLATION, + "delivery": ThreatIntel.KillChainPhases.DELIVERY, + "weaponization": ThreatIntel.KillChainPhases.WEAPONIZATION, + "act-on-objectives": ThreatIntel.KillChainPhases.ACT_ON_OBJECTIVES, + "command-and-control": ThreatIntel.KillChainPhases.COMMAND_AND_CONTROL, +} + +STIX_2_TYPES_TO_CORTEX_CIDR_TYPES = { + "ipv4-addr": FeedIndicatorType.CIDR, + "ipv6-addr": FeedIndicatorType.IPv6CIDR, +} + +THREAT_INTEL_TYPE_TO_DEMISTO_TYPES = { + "campaign": ThreatIntel.ObjectsNames.CAMPAIGN, + "attack-pattern": ThreatIntel.ObjectsNames.ATTACK_PATTERN, + "report": ThreatIntel.ObjectsNames.REPORT, + "malware": ThreatIntel.ObjectsNames.MALWARE, + "course-of-action": ThreatIntel.ObjectsNames.COURSE_OF_ACTION, + "intrusion-set": ThreatIntel.ObjectsNames.INTRUSION_SET, + "tool": ThreatIntel.ObjectsNames.TOOL, + "threat-actor": ThreatIntel.ObjectsNames.THREAT_ACTOR, + "infrastructure": ThreatIntel.ObjectsNames.INFRASTRUCTURE, +} + + +class Client(BaseClient): + def fetch_incidents_from_stream(self, stream_id: str, newer_than: float) -> list[dict]: + params = { + "streamId": stream_id, + "count": 20, + "newerThan": int(newer_than * 1_000), + "client": "feedly.demisto.client", + } + + objects = [] + + while True: + resp = self._http_request("GET", "/v3/enterprise/ioc", params=params, resp_type="response") + objects.extend(resp.json().get("objects", [])) + + if "link" not in resp.headers: + break + + next_url = resp.headers["link"][1:].split(">")[0] + params["continuation"] = parse_qs(next_url)["continuation"][0] + + demisto.debug(f"Fetched {len(objects)} objects from stream {stream_id}") + + indicators = STIX2Parser().parse_stix2_objects(objects) + + incidents = create_incidents_from_indicators(indicators) + + return incidents + + +class STIX2Parser: + """ + STIX2 Parser copied from the command StixParser + """ + + OBJECTS_TO_PARSE = [ + "indicator", + "report", + "malware", + "campaign", + "attack-pattern", + "course-of-action", + "intrusion-set", + "tool", + "threat-actor", + "infrastructure", + "autonomous-system", + "domain-name", + "email-addr", + "file", + "ipv4-addr", + "ipv6-addr", + "mutex", + "url", + "user-account", + "windows-registry-key", + "relationship", + "extension-definition", + "vulnerability", ] - incidents = [] - for event in events: - incident = { - "name": event["name"], - "occured": event["create_time"], - "dbotMirrorId": str(event["event_id"]), - "rawJSON": json.dumps(event), + def __init__(self): + self.indicator_regexes = [ + re.compile(INDICATOR_EQUALS_VAL_PATTERN), + re.compile(INDICATOR_IN_VAL_PATTERN), + re.compile(HASHES_EQUALS_VAL_PATTERN), + re.compile(REGISTRY_EQUALS_VAL_PATTERN), + ] + self.cidr_regexes = [ + re.compile(CIDR_ISSUBSET_VAL_PATTERN), + re.compile(CIDR_ISUPPERSET_VAL_PATTERN), + ] + self.id_to_object: dict[str, Any] = {} + self.parsed_object_id_to_object: dict[str, Any] = {} + + @staticmethod + def get_indicator_publication(indicator: dict[str, Any]): + """ + Build publications grid field from the indicator external_references field + + Args: + indicator: The indicator with publication field + + Returns: + list. publications grid field + """ + publications = [] + for external_reference in indicator.get("external_references", []): + url = external_reference.get("url", "") + description = external_reference.get("description", "") + source_name = external_reference.get("source_name", "") + publications.append({"link": url, "title": description, "source": source_name}) + return publications + + @staticmethod + def change_ip_to_cidr(indicators): + """ + Iterates over indicators list and changes IP to CIDR type if needed. + :param indicators: list of parsed indicators. + :return: changes indicators list in-place. + """ + for indicator in indicators: + if indicator.get("indicator_type") == FeedIndicatorType.IP: + value = indicator.get("value") + if value.endswith("/32"): + pass + elif "/" in value: + indicator["indicator_type"] = FeedIndicatorType.CIDR + + """ PARSING FUNCTIONS""" + + def parse_indicator(self, indicator_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single indicator object + :param indicator_obj: indicator object + :return: indicators extracted from the indicator object in cortex format + """ + field_map: dict = {} + pattern = indicator_obj.get("pattern") + indicators = [] + if pattern: + # this is done in case the server doesn't properly space the operator, + # supported indicators have no spaces, so this action shouldn't affect extracted values + trimmed_pattern = pattern.replace(" ", "") + + indicator_groups = self.extract_indicator_groups_from_pattern(trimmed_pattern, self.indicator_regexes) + + indicators.extend( + self.get_indicators_from_indicator_groups( + indicator_groups, + indicator_obj, + STIX_2_TYPES_TO_CORTEX_TYPES, + field_map, + ) + ) + + cidr_groups = self.extract_indicator_groups_from_pattern(trimmed_pattern, self.cidr_regexes) + indicators.extend( + self.get_indicators_from_indicator_groups( + cidr_groups, + indicator_obj, + STIX_2_TYPES_TO_CORTEX_CIDR_TYPES, + field_map, + ) + ) + self.change_ip_to_cidr(indicators) + + return indicators + + @staticmethod + def parse_attack_pattern(attack_pattern_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single attack pattern object + :param attack_pattern_obj: attack pattern object + :return: attack pattern extracted from the attack pattern object in cortex format + """ + publications = STIX2Parser.get_indicator_publication(attack_pattern_obj) + + kill_chain_mitre = [chain.get("phase_name", "") for chain in attack_pattern_obj.get("kill_chain_phases", [])] + kill_chain_phases = [MITRE_CHAIN_PHASES_TO_DEMISTO_FIELDS.get(phase) for phase in kill_chain_mitre] + + attack_pattern = { + "value": attack_pattern_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.ATTACK_PATTERN, + "score": ThreatIntel.ObjectsScore.ATTACK_PATTERN, + "rawJSON": attack_pattern_obj, } - incidents.append(incident) - return incidents + fields = { + "stixid": attack_pattern_obj.get("id"), + "killchainphases": kill_chain_phases, + "firstseenbysource": attack_pattern_obj.get("created"), + "modified": attack_pattern_obj.get("modified"), + "description": attack_pattern_obj.get("description", ""), + "operatingsystemrefs": attack_pattern_obj.get("x_mitre_platforms"), + "publications": publications, + } + + attack_pattern["customFields"] = fields + + return [attack_pattern] + + @staticmethod + def parse_report(report_obj: dict[str, Any]): + """ + Parses a single report object + :param report_obj: report object + :return: report extracted from the report object in cortex format + """ + object_refs = report_obj.get("object_refs", []) + new_relationships = [] + for obj_id in object_refs: + new_relationships.append( + { + "type": "relationship", + "id": "relationship--fakeid", + "created": report_obj.get("created"), + "modified": report_obj.get("modified"), + "relationship_type": "contains", + "source_ref": report_obj.get("id"), + "target_ref": obj_id, + } + ) + + report = { + "indicator_type": "Feedly Report", + "value": report_obj.get("name"), + "score": ThreatIntel.ObjectsScore.REPORT, + "rawJSON": report_obj, + } + fields = { + "stixid": report_obj.get("id"), + "firstseenbysource": report_obj.get("created"), + "published": report_obj.get("published"), + "description": report_obj.get("description", ""), + "report_types": report_obj.get("report_types", []), + "tags": list(set(report_obj.get("labels", []))), + } + + report["customFields"] = fields + + return [report], new_relationships + + @staticmethod + def parse_threat_actor(threat_actor_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single threat actor object + :param threat_actor_obj: report object + :return: threat actor extracted from the threat actor object in cortex format + """ + + threat_actor = { + "value": threat_actor_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.THREAT_ACTOR, + "score": ThreatIntel.ObjectsScore.THREAT_ACTOR, + "rawJSON": threat_actor_obj, + } + fields = { + "stixid": threat_actor_obj.get("id"), + "firstseenbysource": threat_actor_obj.get("created"), + "modified": threat_actor_obj.get("modified"), + "description": threat_actor_obj.get("description", ""), + "aliases": threat_actor_obj.get("aliases", []), + "threat_actor_types": threat_actor_obj.get("threat_actor_types", []), + "roles": threat_actor_obj.get("roles", []), + "goals": threat_actor_obj.get("goals", []), + "sophistication": threat_actor_obj.get("sophistication", ""), + "resource_level": threat_actor_obj.get("resource_level", ""), + "primary_motivation": threat_actor_obj.get("primary_motivation", ""), + "secondary_motivations": threat_actor_obj.get("secondary_motivations", []), + "tags": list(set(threat_actor_obj.get("labels", []))), + } + + threat_actor["customFields"] = fields + + return [threat_actor] + + @staticmethod + def parse_infrastructure(infrastructure_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single infrastructure object + :param infrastructure_obj: infrastructure object + :return: infrastructure extracted from the infrastructure object in cortex format + """ + kill_chain_mitre = [chain.get("phase_name", "") for chain in infrastructure_obj.get("kill_chain_phases", [])] + kill_chain_phases = [MITRE_CHAIN_PHASES_TO_DEMISTO_FIELDS.get(phase) for phase in kill_chain_mitre] + + infrastructure = { + "value": infrastructure_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.INFRASTRUCTURE, + "score": ThreatIntel.ObjectsScore.INFRASTRUCTURE, + "rawJSON": infrastructure_obj, + } + fields = { + "stixid": infrastructure_obj.get("id"), + "description": infrastructure_obj.get("description", ""), + "infrastructure_types": infrastructure_obj.get("infrastructure_types", []), + "aliases": infrastructure_obj.get("aliases", []), + "kill_chain_phases": kill_chain_phases, + "firstseenbysource": infrastructure_obj.get("created"), + "modified": infrastructure_obj.get("modified"), + } + + infrastructure["customFields"] = fields + return [infrastructure] + + @staticmethod + def parse_malware(malware_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single malware object + :param malware_obj: malware object + :return: malware extracted from the malware object in cortex format + """ + + kill_chain_mitre = [chain.get("phase_name", "") for chain in malware_obj.get("kill_chain_phases", [])] + kill_chain_phases = [MITRE_CHAIN_PHASES_TO_DEMISTO_FIELDS.get(phase) for phase in kill_chain_mitre] + + malware = { + "value": malware_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.MALWARE, + "score": ThreatIntel.ObjectsScore.MALWARE, + "rawJSON": malware_obj, + } + fields = { + "stixid": malware_obj.get("id"), + "firstseenbysource": malware_obj.get("created"), + "modified": malware_obj.get("modified"), + "description": malware_obj.get("description", ""), + "malware_types": malware_obj.get("malware_types", []), + "is_family": malware_obj.get("is_family", False), + "aliases": malware_obj.get("aliases", []), + "kill_chain_phases": kill_chain_phases, + "os_execution_envs": malware_obj.get("os_execution_envs", []), + "architecture_execution_envs": malware_obj.get("architecture_execution_envs", []), + "capabilities": malware_obj.get("capabilities", []), + "sample_refs": malware_obj.get("sample_refs", []), + "tags": list(set(malware_obj.get("labels", []))), + } + + malware["customFields"] = fields + return [malware] + + @staticmethod + def parse_tool(tool_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single tool object + :param tool_obj: tool object + :return: tool extracted from the tool object in cortex format + """ + kill_chain_mitre = [chain.get("phase_name", "") for chain in tool_obj.get("kill_chain_phases", [])] + kill_chain_phases = [MITRE_CHAIN_PHASES_TO_DEMISTO_FIELDS.get(phase) for phase in kill_chain_mitre] + + tool = { + "value": tool_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.TOOL, + "score": ThreatIntel.ObjectsScore.TOOL, + "rawJSON": tool_obj, + } + fields = { + "stixid": tool_obj.get("id"), + "killchainphases": kill_chain_phases, + "firstseenbysource": tool_obj.get("created"), + "modified": tool_obj.get("modified"), + "tool_types": tool_obj.get("tool_types", []), + "description": tool_obj.get("description", ""), + "aliases": tool_obj.get("aliases", []), + "tool_version": tool_obj.get("tool_version", ""), + } + + tool["customFields"] = fields + return [tool] + + @staticmethod + def parse_course_of_action(coa_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single course of action object + :param coa_obj: course of action object + :return: course of action extracted from the course of action object in cortex format + """ + publications = STIX2Parser.get_indicator_publication(coa_obj) + + course_of_action = { + "value": coa_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.COURSE_OF_ACTION, + "score": ThreatIntel.ObjectsScore.COURSE_OF_ACTION, + "rawJSON": coa_obj, + } + fields = { + "stixid": coa_obj.get("id"), + "firstseenbysource": coa_obj.get("created"), + "modified": coa_obj.get("modified"), + "description": coa_obj.get("description", ""), + "action_type": coa_obj.get("action_type", ""), + "publications": publications, + } + + course_of_action["customFields"] = fields + return [course_of_action] + + @staticmethod + def parse_campaign(campaign_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single campaign object + :param campaign_obj: campaign object + :return: campaign extracted from the campaign object in cortex format + """ + campaign = { + "value": campaign_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.CAMPAIGN, + "score": ThreatIntel.ObjectsScore.CAMPAIGN, + "rawJSON": campaign_obj, + } + fields = { + "stixid": campaign_obj.get("id"), + "firstseenbysource": campaign_obj.get("created"), + "modified": campaign_obj.get("modified"), + "description": campaign_obj.get("description", ""), + "aliases": campaign_obj.get("aliases", []), + "objective": campaign_obj.get("objective", ""), + } + + campaign["customFields"] = fields + return [campaign] + + @staticmethod + def parse_intrusion_set(intrusion_set_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses a single intrusion set object + :param intrusion_set_obj: intrusion set object + :return: intrusion set extracted from the intrusion set object in cortex format + """ + publications = STIX2Parser.get_indicator_publication(intrusion_set_obj) + + intrusion_set = { + "value": intrusion_set_obj.get("name"), + "indicator_type": ThreatIntel.ObjectsNames.INTRUSION_SET, + "score": ThreatIntel.ObjectsScore.INTRUSION_SET, + "rawJSON": intrusion_set_obj, + } + fields = { + "stixid": intrusion_set_obj.get("id"), + "firstseenbysource": intrusion_set_obj.get("created"), + "modified": intrusion_set_obj.get("modified"), + "description": intrusion_set_obj.get("description", ""), + "aliases": intrusion_set_obj.get("aliases", []), + "goals": intrusion_set_obj.get("goals", []), + "resource_level": intrusion_set_obj.get("resource_level", ""), + "primary_motivation": intrusion_set_obj.get("primary_motivation", ""), + "secondary_motivations": intrusion_set_obj.get("secondary_motivations", []), + "publications": publications, + "tags": list(set(intrusion_set_obj.get("labels", []))), + } + intrusion_set["customFields"] = fields + return [intrusion_set] + + @staticmethod + def parse_general_sco_indicator(sco_object: dict[str, Any], value_mapping: str = "value") -> list[dict[str, Any]]: + """ + Parses a single SCO indicator. + + Args: + sco_object (dict): indicator as an observable object. + value_mapping (str): the key that extracts the value from the indicator response. + """ + sco_indicator = { + "value": sco_object.get(value_mapping), + "score": Common.DBotScore.NONE, + "rawJSON": sco_object, + "indicator_type": STIX_2_TYPES_TO_CORTEX_TYPES.get(sco_object.get("type")), # type: ignore[arg-type] + } + + fields = {"stixid": sco_object.get("id")} + + sco_indicator["customFields"] = fields + return [sco_indicator] + + @staticmethod + def parse_sco_autonomous_system_indicator(autonomous_system_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses autonomous_system indicator type to cortex format. + + Args: + autonomous_system_obj (dict): indicator as an observable object of type autonomous-system. + """ + autonomous_system_indicator = STIX2Parser.parse_general_sco_indicator( + autonomous_system_obj, value_mapping="number" + ) + autonomous_system_indicator[0]["customFields"]["name"] = autonomous_system_obj.get("name") + + return autonomous_system_indicator + + @staticmethod + def parse_sco_file_indicator(file_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses file indicator type to cortex format. + + Args: + file_obj (dict): indicator as an observable object of file type. + """ + file_hashes = file_obj.get("hashes", {}) + value = file_hashes.get("SHA-256") or file_hashes.get("SHA-1") or file_hashes.get("MD5") + if not value: + return [] + + file_obj["value"] = value + + file_indicator = STIX2Parser.parse_general_sco_indicator(file_obj) + file_indicator[0]["customFields"].update( + { + "associatedfilenames": file_obj.get("name"), + "size": file_obj.get("size"), + "path": file_obj.get("parent_directory_ref"), + "md5": file_hashes.get("MD5"), + "sha1": file_hashes.get("SHA-1"), + "sha256": file_hashes.get("SHA-256"), + } + ) + + return file_indicator + + @staticmethod + def parse_sco_mutex_indicator(mutex_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses mutex indicator type to cortex format. + + Args: + mutex_obj (dict): indicator as an observable object of mutex type. + """ + return STIX2Parser.parse_general_sco_indicator(sco_object=mutex_obj, value_mapping="name") + + @staticmethod + def parse_sco_account_indicator(account_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses account indicator type to cortex format. + + Args: + account_obj (dict): indicator as an observable object of account type. + """ + account_indicator = STIX2Parser.parse_general_sco_indicator(account_obj, value_mapping="user_id") + account_indicator[0]["customFields"].update( + {"displayname": account_obj.get("user_id"), "accounttype": account_obj.get("account_type")} + ) + return account_indicator + + @staticmethod + def parse_sco_windows_registry_key_indicator(registry_key_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses registry_key indicator type to cortex format. + + Args: + registry_key_obj (dict): indicator as an observable object of registry_key type. + """ + registry_key_indicator = STIX2Parser.parse_general_sco_indicator(registry_key_obj, value_mapping="key") + registry_key_indicator[0]["customFields"].update( + { + "registryvalue": registry_key_obj.get("values"), + "modified_time": registry_key_obj.get("modified_time"), + "number_of_subkeys": registry_key_obj.get("number_of_subkeys"), + } + ) + return registry_key_indicator + + @staticmethod + def parse_vulnerability(vulnerability_obj: dict[str, Any]) -> list[dict[str, Any]]: + """ + Parses vulnerability indicator type to cortex format. + + Args: + vulnerability_obj (dict): indicator as an observable object of vulnerability type. + """ + vulnerability = { + "value": vulnerability_obj.get("name"), + "indicator_type": FeedIndicatorType.CVE, + "rawJSON": vulnerability_obj, + } + fields = { + "stixid": vulnerability_obj.get("id"), + "firstseenbysource": vulnerability_obj.get("created"), + "modified": vulnerability_obj.get("modified"), + "description": vulnerability_obj.get("description", ""), + "external_references": vulnerability_obj.get("external_references", []), + "tags": list(set(vulnerability_obj.get("labels", []))), + } + + vulnerability["customFields"] = fields + return [vulnerability] + + def parse_relationships(self, relationships_lst: list[dict[str, Any]]) -> dict[str, Any]: + """Parse the Relationships objects retrieved from the feed. + + Returns: + A dict of relationship value to processed relationships as indicator object. + """ + a_value_to_relationship: dict[str, Any] = {} + for relationships_object in relationships_lst: + relationship_type: str = relationships_object.get("relationship_type", "") + if not EntityRelationship.Relationships.is_valid(relationship_type): + if relationship_type == "indicates": + relationship_type = "indicated-by" + else: + demisto.debug(f"Invalid relation type: {relationship_type}") + continue + + a_stixid = relationships_object.get("source_ref", "") + a_object = self.parsed_object_id_to_object.get(a_stixid, {}) + b_stixid = relationships_object.get("target_ref", "") + b_object = self.parsed_object_id_to_object.get(b_stixid, {}) + + if not a_object or not b_object: + demisto.debug(f"Cant find {a_object=} or {b_object=}.") + continue + + a_value, a_type = a_object.get("value"), a_object.get("indicator_type") + b_value, b_type = b_object.get("value"), b_object.get("indicator_type") + + if not (a_value and a_type and b_value and b_type): + continue + + if b_type in {ThreatIntel.ObjectsNames.THREAT_ACTOR, ThreatIntel.ObjectsNames.MALWARE}: + a_object["customFields"].setdefault("tags", []).append(b_value) + elif b_type in {ThreatIntel.ObjectsNames.ATTACK_PATTERN}: + with suppress(StopIteration): + mitre_id = next( + ref["external_id"] + for ref in b_object["rawJSON"].get("external_references", []) + if ref.get("source_name") == "mitre-attack" + ) + a_object["customFields"].setdefault("tags", []).append(mitre_id) + + mapping_fields = { + "lastseenbysource": relationships_object.get("modified"), + "firstseenbysource": relationships_object.get("created"), + } + + entity_relation = EntityRelationship( + name=relationship_type, + entity_a=a_value, + entity_a_type=a_type, + entity_b=b_value, + entity_b_type=b_type, + fields=mapping_fields, + ) + indicator_relationship = entity_relation.to_indicator() + if a_value_to_relationship.get(a_value): + a_value_to_relationship[a_value].append(indicator_relationship) + else: + a_value_to_relationship[a_value] = [indicator_relationship] + + return a_value_to_relationship + + def parse_stix2_objects(self, objects: list[dict]) -> list[dict[str, Any]]: + """ + Builds a list of cortex indicators objects from the STIX2 objects + :return: Cortex indicators list + """ + envelopes = STIX2Parser.create_envelopes_by_type(objects) + indicators = self.load_stix_objects_from_envelope(envelopes) + + return indicators + + def load_stix_objects_from_envelope(self, envelopes: dict[str, Any]): + parse_stix_2_objects = { + "indicator": self.parse_indicator, + "attack-pattern": self.parse_attack_pattern, + "malware": self.parse_malware, + "report": self.parse_report, + "course-of-action": self.parse_course_of_action, + "campaign": self.parse_campaign, + "intrusion-set": self.parse_intrusion_set, + "tool": self.parse_tool, + "threat-actor": self.parse_threat_actor, + "infrastructure": self.parse_infrastructure, + "domain-name": self.parse_general_sco_indicator, + "ipv4-addr": self.parse_general_sco_indicator, + "ipv6-addr": self.parse_general_sco_indicator, + "email-addr": self.parse_general_sco_indicator, + "url": self.parse_general_sco_indicator, + "autonomous-system": self.parse_sco_autonomous_system_indicator, + "file": self.parse_sco_file_indicator, + "mutex": self.parse_sco_mutex_indicator, + "user-account": self.parse_sco_account_indicator, + "windows-registry-key": self.parse_sco_windows_registry_key_indicator, + "vulnerability": self.parse_vulnerability, + } + indicators = self.parse_dict_envelope(envelopes, parse_stix_2_objects) + return indicators + + def parse_dict_envelope(self, envelopes: dict[str, Any], parse_objects_func): + indicators = [] + relationships_list: list[dict[str, Any]] = [] + + for obj_type, stix_objects in envelopes.items(): + if obj_type == "relationship": + relationships_list.extend(stix_objects) + else: + for obj in stix_objects: + # handled separately + if obj.get("type") == "extension-definition": + continue + self.id_to_object[obj.get("id")] = obj + if obj.get("type") == "report": + result, relationships = self.parse_report(obj) + relationships_list.extend(relationships) + else: + result = parse_objects_func[obj_type](obj) + if not result: + continue + self.parsed_object_id_to_object[obj.get("id")] = result[0] + indicators.extend(result) + + if relationships_list: + relationships_mapping = self.parse_relationships(relationships_list) + STIX2Parser.add_relationship_to_indicator(relationships_mapping, indicators) + return indicators + + @staticmethod + def create_envelopes_by_type(objects) -> dict: + """ + Creates objects envelops by type + """ + types_envelopes: dict = {} + index = 0 + for obj in objects: + obj_type = obj.get("type") + if obj_type not in STIX2Parser.OBJECTS_TO_PARSE: + demisto.debug(f"Cannot parse object of type {obj_type}, skipping.") + index += 1 + continue + if obj_type not in types_envelopes: + types_envelopes[obj_type] = [] + types_envelopes[obj_type].append(obj) + + return types_envelopes + + @staticmethod + def get_indicators_from_indicator_groups( + indicator_groups: list[tuple[str, str]], + indicator_obj: dict[str, str], + indicator_types: dict[str, str], + field_map: dict[str, str], + ) -> list[dict[str, str]]: + """ + Get indicators from indicator regex groups + :param indicator_groups: caught regex group in pattern of: [`type`, `indicator`] + :param indicator_obj: stix indicator object + :param indicator_types: supported indicator types -> cortex types + :param field_map: map used to create fields entry ({field_name: field_value}) + :return: Indicators list + """ + indicators = [] + if indicator_groups: + for term in indicator_groups: + for stix_type in indicator_types: + # term should be list with 2 argument parsed with regex - [`type`, `indicator`] + if len(term) == 2 and stix_type in term[0]: + type_ = indicator_types[stix_type] + value = term[1] + + # support added for cases as 'value1','value2','value3' for 3 different indicators + for indicator_value in value.split(","): + indicator_value = indicator_value.strip("'") + indicator = STIX2Parser.create_indicator( + indicator_obj, type_, indicator_value.strip("'"), field_map + ) + indicators.append(indicator) + break + return indicators + + @staticmethod + def create_indicator(indicator_obj, type_, value, field_map): + """ + Create a cortex indicator from a stix indicator + :param indicator_obj: rawJSON value of the indicator + :param type_: cortex type of the indicator + :param value: indicator value + :param field_map: field map used for mapping fields ({field_name: field_value}) + :return: Cortex indicator + """ + ioc_obj_copy = copy.deepcopy(indicator_obj) + ioc_obj_copy["value"] = value + ioc_obj_copy["type"] = type_ + indicator = { + "value": value, + "indicator_type": type_, + "rawJSON": ioc_obj_copy, + } + fields = {} + tags = [] + # create tags from labels: + for label in ioc_obj_copy.get("labels", []): + tags.append(label) + + # add description if able + if "description" in ioc_obj_copy: + fields["description"] = ioc_obj_copy["description"] + + # add field_map fields + for field_name, field_path in field_map.items(): + if field_path in ioc_obj_copy: + fields[field_name] = ioc_obj_copy.get(field_path) + + # union of tags and labels + if "tags" in fields: + field_tag = fields.get("tags") + if isinstance(field_tag, list): + tags.extend(field_tag) + else: + tags.append(field_tag) + + fields["tags"] = tags + + indicator["customFields"] = fields + return indicator + + @staticmethod + def extract_indicator_groups_from_pattern(pattern: str, regexes: list) -> list[tuple[str, str]]: + """ + Extracts indicator [`type`, `indicator`] groups from pattern + :param pattern: stix pattern + :param regexes: regexes to run to pattern + :return: extracted indicators list from pattern + """ + groups: list[tuple[str, str]] = [] + for regex in regexes: + find_result = regex.findall(pattern) + if find_result: + groups.extend(find_result) + return groups + + @staticmethod + def add_relationship_to_indicator(relationships_mapping, indicators): + """ + Adds relationship to right indicator + :param relationships_mapping: maps a_value to relationship object + :param indicators: all indicators that were fetched from file. + """ + for indicator in indicators: + if (a_value := indicator.get("value")) and (relationships := relationships_mapping.get(a_value)): + indicator["relationships"] = relationships + + +def create_incidents_from_indicators(indicators: list[dict]) -> list[dict]: + return [ + create_incident_from_report_indicator(indicator) + for indicator in indicators + if indicator.get("indicator_type") == "Feedly Report" + ] + + +def create_incident_from_report_indicator(indicator: dict) -> dict: + references = indicator["rawJSON"].get("external_references", []) + + feedly_url = references[0]["url"] + entry_id = feedly_url.removeprefix("https://feedly.com/i/entry/") + + indicator_type2relationships = defaultdict(list) + for relationship in indicator.get("relationships", []): + if relationship["entityBFamily"] == "Indicator": + indicator_type2relationships[relationship["entityBType"]].append(relationship["entityB"]) + + indicator_type2relationships["TTP"] = [ + tag for tag in indicator["customFields"].get("tags", []) if tag.startswith("T") and tag[1:].isdigit() + ] + + event = { + "name": indicator["value"], + "create_time": indicator["rawJSON"].get("published"), + "event_id": entry_id, + "feedly_url": feedly_url, + "tags": indicator["rawJSON"].get("labels", []), + "content": indicator["customFields"].get("description", ""), + "indicators": indicator_type2relationships, + } + + if len(references) > 1: + event["source"] = { + "name": references[1]["source_name"], + "url": references[1]["url"], + } + + return { + "name": event["name"], + "occured": event["create_time"], + "dbotMirrorId": entry_id, + "rawJSON": json.dumps(event), + } + + +def fetch_incidents(client: Client, params: dict[str, str], context: dict[str, str]) -> list[dict]: + return client.fetch_incidents_from_stream( + params["feedly_stream_id"], + newer_than=float( + context.get("last_successful_run", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600) + ), + ) def main() -> None: + params = demisto.params() + command = demisto.command() - if command == "fetch-incidents": - demisto.incidents(fetch_incidents()) + + try: + client = Client( + base_url=FEEDLY_BASE_URL, + verify=not params.get("insecure", False), + proxy=params.get("proxy", False), + headers={"Authorization": f"Bearer {params['credentials']['password']}"}, + ) + + if command == "fetch-incidents": + now = time.time() + demisto.incidents(fetch_incidents(client, params, demisto.getLastRun())) + demisto.setLastRun({"last_successful_run": str(now)}) + else: + raise NotImplementedError(f"Command {command} is not implemented.") + except Exception as e: + demisto.error(traceback.format_exc()) # Print the traceback stack + return_error(f"Failed to execute {command} command.\nError:\n{repr(e)}") + + +if __name__ in ("__main__", "__builtin__", "builtins"): + main() diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml index ec01820b65dc..d3992a5ab9d5 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml @@ -25,6 +25,12 @@ configuration: type: 8 section: Connect advanced: true +- display: Incident type + defaultvalue: Feedly Report + name: incidentType + type: 13 + required: false + section: Connect - display: Fetch incidents name: isFetch type: 8 @@ -42,6 +48,12 @@ configuration: defaultvalue: '7' additionalinfo: Number of days to fetch articles from when running the integration for the first time section: Collect +- display: Stream ID + name: feedly_stream_id + required: true + type: 0 + additionalinfo: The stream id you want to fetch articles from. You can find it in Feedly by going to the stream, clicking on `...` > `Sharing`, then `Copy ID` in the `Feedly API Stream ID` section. + section: Collect description: 'Fetch Feedly reports as incidents.' display: IncidentsFeedly name: IncidentsFeedly @@ -59,4 +71,5 @@ script: subtype: python3 type: python tests: -- No tests (auto formatted). \ No newline at end of file +- No tests (auto formatted). +defaultmapperin: Feedly - Report Mapper \ No newline at end of file diff --git a/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json b/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json new file mode 100644 index 000000000000..c247a6659b62 --- /dev/null +++ b/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json @@ -0,0 +1,723 @@ +{ + "cacheVersn": 0, + "close": null, + "definitionId": "", + "description": "", + "detached": false, + "details": null, + "detailsV2": { + "TypeName": "", + "tabs": [ + { + "id": "summary", + "name": "Legacy Summary", + "type": "summary" + }, + { + "hidden": false, + "id": "h2hjyyhld4", + "name": "Article", + "sections": [ + { + "displayType": "ROW", + "h": 11, + "hideItemTitleOnlyOne": true, + "hideName": true, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-77ff1410-8700-11ef-88e5-01f8fe79530d", + "items": [ + { + "endCol": 4, + "fieldId": "usecasedescription", + "height": 44, + "id": "b2bcc480-8700-11ef-88e5-01f8fe79530d", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Article", + "static": false, + "w": 2, + "x": 0, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", + "items": [ + { + "endCol": 2, + "fieldId": "feedlycrawleddate", + "height": 22, + "id": "def797e0-8701-11ef-88e5-01f8fe79530d", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "feedlyurl", + "height": 22, + "id": "bc06e420-8701-11ef-88e5-01f8fe79530d", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourcename", + "height": 22, + "id": "b4bf55d0-8701-11ef-88e5-01f8fe79530d", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourceurl", + "height": 22, + "id": "b8e44760-8701-11ef-88e5-01f8fe79530d", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "tags", + "height": 22, + "id": "e64b9ec0-8700-11ef-88e5-01f8fe79530d", + "index": 4, + "listId": "h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Article metadata", + "static": false, + "w": 1, + "x": 2, + "y": 0 + }, + { + "columns": [ + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 300 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "relatedIncCount", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "h": 4, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-e33dd7a0-8702-11ef-88e5-01f8fe79530d", + "items": [], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Indicators of compromise", + "query": "-type:\"Attack Pattern\"", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 1, + "x": 2, + "y": 2 + }, + { + "columns": [ + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 300 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "relatedIncCount", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "h": 5, + "i": "h2hjyyhld4-b282caf0-870f-11ef-88e5-01f8fe79530d", + "items": [], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Mitre ATT\u0026CK", + "query": "type:\"Attack Pattern\"", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 1, + "x": 2, + "y": 6 + } + ], + "type": "custom" + }, + { + "hidden": false, + "id": "zfhf0tdhhj", + "name": "Indicators", + "sections": [ + { + "columns": [ + { + "displayed": true, + "key": "Tags", + "width": 200 + }, + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 123 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "investigationIDs", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "description": "The list of indicators related to the incident.", + "h": 5, + "i": "zfhf0tdhhj-h2hjyyhld4-caseinfoid-indeooemoh-1840e830-6dd5-11ea-9e64-73fcd6758f5c", + "items": [], + "maxH": null, + "maxW": 3, + "minH": 1, + "minW": 3, + "moved": false, + "name": "Indicators related to incident", + "query": "", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 3, + "x": 0, + "y": 0 + } + ], + "type": "custom" + }, + { + "id": "caseinfoid", + "name": "Incident Info", + "sections": [ + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "type", + "height": 22, + "id": "incident-type-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "severity", + "height": 22, + "id": "incident-severity-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "owner", + "height": 22, + "id": "incident-owner-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourcebrand", + "height": 22, + "id": "incident-sourceBrand-field", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourceinstance", + "height": 22, + "id": "incident-sourceInstance-field", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "playbookid", + "height": 22, + "id": "incident-playbookId-field", + "index": 5, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "moved": false, + "name": "Case Details", + "static": false, + "w": 1, + "x": 0, + "y": 0 + }, + { + "h": 2, + "i": "caseinfoid-61263cc0-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "moved": false, + "name": "Notes", + "static": false, + "type": "notes", + "w": 1, + "x": 2, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-6aabad20-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "moved": false, + "name": "Work Plan", + "static": false, + "type": "workplan", + "w": 1, + "x": 1, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-770ec200-98b1-11e9-97d7-ed26ef9e46c8", + "isVisible": true, + "maxW": 3, + "moved": false, + "name": "Linked Incidents", + "static": false, + "type": "linkedIncidents", + "w": 1, + "x": 1, + "y": 6 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-842632c0-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "moved": false, + "name": "Child Incidents", + "static": false, + "type": "childInv", + "w": 1, + "x": 2, + "y": 4 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-4a31afa0-98ba-11e9-a519-93a53c759fe0", + "maxW": 3, + "moved": false, + "name": "Evidence", + "static": false, + "type": "evidence", + "w": 1, + "x": 2, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "caseinfoid-7717e580-9bed-11e9-9a3f-8b4b2158e260", + "maxW": 3, + "moved": false, + "name": "Team Members", + "static": false, + "type": "team", + "w": 1, + "x": 2, + "y": 6 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-7ce69dd0-a07f-11e9-936c-5395a1acf11e", + "maxW": 3, + "moved": false, + "name": "Indicators", + "query": "", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 2, + "x": 0, + "y": 4 + }, + { + "displayType": "CARD", + "h": 2, + "i": "caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", + "items": [ + { + "endCol": 1, + "fieldId": "occurred", + "height": 53, + "id": "incident-occurred-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 1, + "fieldId": "dbotmodified", + "height": 53, + "id": "incident-modified-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "dbotduedate", + "height": 53, + "id": "incident-dueDate-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "dbotcreated", + "height": 53, + "id": "incident-created-field", + "index": 0, + "sectionItemType": "field", + "startCol": 1 + }, + { + "endCol": 2, + "fieldId": "dbotclosed", + "height": 53, + "id": "incident-closed-field", + "index": 1, + "sectionItemType": "field", + "startCol": 1 + } + ], + "maxW": 3, + "moved": false, + "name": "Timeline Information", + "static": false, + "w": 1, + "x": 0, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-88e6bf70-a0b1-11e9-b27f-13ae1773d289", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "dbotclosed", + "height": 22, + "id": "incident-dbotClosed-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "closereason", + "height": 22, + "id": "incident-closeReason-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "closenotes", + "height": 22, + "id": "incident-closeNotes-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "moved": false, + "name": "Closing Information", + "static": false, + "w": 1, + "x": 0, + "y": 6 + }, + { + "displayType": "CARD", + "h": 2, + "i": "caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "details", + "height": 106, + "id": "incident-details-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "moved": false, + "name": "Investigation Data", + "static": false, + "w": 1, + "x": 1, + "y": 2 + } + ], + "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" + } + ] + }, + "edit": null, + "fromServerVersion": "", + "group": "incident", + "id": "e53027fa-56c1-4521-8c38-822af5c0f6de", + "indicatorsDetails": null, + "indicatorsQuickView": null, + "itemVersion": "", + "locked": false, + "mobile": null, + "name": "Feedly Report ", + "packID": "", + "packName": "", + "propagationLabels": [ + "all" + ], + "quickView": null, + "quickViewV2": null, + "system": false, + "toServerVersion": "", + "version": -1 +} \ No newline at end of file From 8d8eab7b2d8ff4701412e74b520e7c094f9ddee9 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 14 Nov 2024 12:54:53 +0100 Subject: [PATCH 07/27] [feedly] wip --- .../Integrations/FeedFeedly/FeedFeedly.py | 54 ++++++++++++++----- .../Integrations/FeedFeedly/FeedFeedly.yml | 8 ++- .../FeedFeedly/FeedFeedly_description.md | 2 + .../Integrations/FeedFeedly/README.md | 1 + .../IncidentsFeedly/IncidentsFeedly.py | 46 +++++++++++++--- .../IncidentsFeedly_description.md | 11 ++++ .../Integrations/IncidentsFeedly/README.md | 25 +++++++++ 7 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md create mode 100644 Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index 8955e3b135e0..901adfb87c55 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -1,5 +1,6 @@ import copy from contextlib import suppress +from typing import Any from urllib.parse import parse_qs from CommonServerPython import * # noqa: F401 @@ -115,7 +116,9 @@ class Client(BaseClient): - def fetch_indicators_from_stream(self, stream_id: str, newer_than: float, *, limit: Optional[int] = None) -> list: + def fetch_indicators_from_stream( + self, stream_id: str, newer_than: float, *, limit: int | None = None, ingest_reports: bool = True + ) -> list: params = { "streamId": stream_id, "count": 20, @@ -137,7 +140,7 @@ def fetch_indicators_from_stream(self, stream_id: str, newer_than: float, *, lim demisto.debug(f"Fetched {len(objects)} objects from stream {stream_id}") - indicators = STIX2Parser().parse_stix2_objects(objects) + indicators = STIX2Parser(ingest_reports=ingest_reports).parse_stix2_objects(objects) if limit: indicators = indicators[:limit] @@ -180,7 +183,7 @@ class STIX2Parser: "vulnerability", ] - def __init__(self): + def __init__(self, ingest_reports: bool): self.indicator_regexes = [ re.compile(INDICATOR_EQUALS_VAL_PATTERN), re.compile(INDICATOR_IN_VAL_PATTERN), @@ -194,6 +197,8 @@ def __init__(self): self.id_to_object: dict[str, Any] = {} self.parsed_object_id_to_object: dict[str, Any] = {} + self.ingest_reports = ingest_reports + @staticmethod def get_indicator_publication(indicator: dict[str, Any]): """ @@ -300,13 +305,14 @@ def parse_attack_pattern(attack_pattern_obj: dict[str, Any]) -> list[dict[str, A return [attack_pattern] - @staticmethod - def parse_report(report_obj: dict[str, Any]): + def parse_report(self, report_obj: dict[str, Any]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: """ Parses a single report object :param report_obj: report object :return: report extracted from the report object in cortex format """ + if not self.ingest_reports: + return [], [] object_refs = report_obj.get("object_refs", []) new_relationships = [] for obj_id in object_refs: @@ -331,7 +337,7 @@ def parse_report(report_obj: dict[str, Any]): fields = { "stixid": report_obj.get("id"), "firstseenbysource": report_obj.get("created"), - "published": report_obj.get("published"), + "published": report_obj.get("created"), # todo "description": report_obj.get("description", ""), "report_types": report_obj.get("report_types", []), "tags": list(set(report_obj.get("labels", []))), @@ -957,7 +963,7 @@ def test_module(client: Client, params: dict) -> str: # pragma: no cover def get_indicators_command( - client: Client, params: dict[str, str], args: dict[str, str] + client: Client, params: dict[str, Any], args: dict[str, Any] ) -> CommandResults: # pragma: no cover """Wrapper for retrieving indicators from the feed to the war-room. Args: @@ -968,7 +974,10 @@ def get_indicators_command( Outputs. """ indicators = client.fetch_indicators_from_stream( - params["feedly_stream_id"], newer_than=time.time() - 24 * 3600, limit=int(args.get("limit", "10")) + params["feedly_stream_id"], + newer_than=time.time() - 24 * 3600, + limit=int(args.get("limit", "10")), + ingest_reports=args.get("ingest_articles_as_indicators", True), ) demisto.createIndicators(indicators) # type: ignore return CommandResults(readable_output=f"Created {len(indicators)} indicators.") @@ -985,12 +994,32 @@ def fetch_indicators_command(client: Client, params: dict[str, str], context: di """ return client.fetch_indicators_from_stream( params["feedly_stream_id"], - newer_than=float( - context.get("last_successful_run", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600) - ), + newer_than=get_newer_than_timestamp(params, context), + ingest_reports=params.get("ingest_articles_as_indicators", True), # type: ignore + ) + + +def get_newer_than_timestamp(params: dict[str, str], context: dict[str, str]) -> float: + return float( + context.get( + "last_fetched_article_crawled_time", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600 + ) ) +def set_next_newer_than(indicators: list[dict[str, str]]) -> None: + if not indicators: + return + newer_than = datetime.fromisoformat( + max( + indicator["fields"]["published"] # type: ignore + for indicator in indicators + if indicator["type"] == "Feedly Report" + ) + ).timestamp() + demisto.setLastRun({"last_fetched_article_crawled_time": newer_than}) + + def main(): # pragma: no cover params = demisto.params() @@ -1014,11 +1043,10 @@ def main(): # pragma: no cover return_results(get_indicators_command(client, params, args)) elif command == "fetch-indicators": - now = time.time() indicators = fetch_indicators_command(client, params, demisto.getLastRun()) for indicators_batch in batch(indicators, batch_size=2000): demisto.createIndicators(indicators_batch) # type: ignore - demisto.setLastRun({"last_successful_run": str(now)}) + set_next_newer_than(indicators) else: raise NotImplementedError(f"Command {command} is not implemented.") diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml index 8b4b6a214bd6..9f9491264d12 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.yml @@ -82,6 +82,12 @@ configuration: type: 0 defaultvalue: '7' additionalinfo: Number of days to fetch articles from when running the integration for the first time +- display: Ingest Articles as Indicators + name: ingest_articles_as_indicators + required: false + type: 8 + defaultvalue: 'true' + additionalinfo: When selected, the integration will ingest articles as indicators. If not selected, you may want to use the IncidentsFeedly integration to ingest articles as incidents. The current FeedFeedly integration will still be needed to ingest entities as indicators, and to create relationships between indicators. - additionalinfo: Incremental feeds pull only new or modified indicators that have been sent from the integration. The determination if the indicator is new or modified happens on the 3rd-party vendor's side, so only indicators that are new or modified are sent to Cortex XSOAR. Therefore, all indicators coming from these feeds are labeled new or modified. defaultvalue: 'true' display: Incremental feed @@ -117,7 +123,7 @@ script: description: Gets indicators from the feed. execution: false name: feedly-get-indicators - dockerimage: demisto/python3:3.10.14.94490 + dockerimage: demisto/python3:3.11.9.105369 feed: true isfetch: false longRunning: false diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md index bb12d64cdb50..cb7238c5e65d 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md @@ -2,6 +2,8 @@ Use the Feedly integration to import articles with entities, indicators, and relationships from your Feedly boards and folders. +**Note** There is a second integration `IncidentsFeedly` that can be used to ingest articles as incidents instead of indicators. This `FeedFeedly` integration is still needed, to ingest entities (intrusion sets, malware, TTPs) as indicators, and relationships between them. + **Disclaimer** You will need the Feedly for Threat Intelligence package to enable this integration. You can learn more about our product here: https://feedly.com/i/landing/threatIntelligence ### Authentication diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/README.md b/Packs/FeedFeedly/Integrations/FeedFeedly/README.md index 28f367e16277..6de58b27cf7f 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/README.md +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/README.md @@ -21,6 +21,7 @@ Ingest articles with indicators, entities and relationships from Feedly into XSO | | | False | | Stream ID | The stream id you want to fetch articles from. You can find it in Feedly by going to the stream, clicking on \`...\` > \`Sharing\`, then \`Copy ID\` in the \`Feedly API Stream ID\` section. | True | | Days to fetch for first run | Number of days to fetch articles from when running the integration for the first time | True | + | Ingest Articles as Indicators | When selected, the integration will ingest articles as indicators. If not selected, you may want to use the IncidentsFeedly integration to ingest articles as incidents. The current FeedFeedly integration will still be needed to ingest entities as indicators, and to create relationships between indicators. | False | | Incremental feed | Incremental feeds pull only new or modified indicators that have been sent from the integration. The determination if the indicator is new or modified happens on the 3rd-party vendor's side, so only indicators that are new or modified are sent to Cortex XSOAR. Therefore, all indicators coming from these feeds are labeled new or modified. | False | 4. Click **Test** to validate the URLs, token, and connection. diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py index 64e5b53f383c..3aeba0e06a33 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py @@ -961,7 +961,7 @@ def create_incident_from_report_indicator(indicator: dict) -> dict: event = { "name": indicator["value"], - "create_time": indicator["rawJSON"].get("published"), + "create_time": indicator["rawJSON"].get("created"), # todo "event_id": entry_id, "feedly_url": feedly_url, "tags": indicator["rawJSON"].get("labels", []), @@ -986,12 +986,42 @@ def create_incident_from_report_indicator(indicator: dict) -> dict: def fetch_incidents(client: Client, params: dict[str, str], context: dict[str, str]) -> list[dict]: return client.fetch_incidents_from_stream( params["feedly_stream_id"], - newer_than=float( - context.get("last_successful_run", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600) - ), + newer_than=get_newer_than_timestamp(params, context), ) +def get_newer_than_timestamp(params: dict[str, str], context: dict[str, str]) -> float: + return float( + context.get( + "last_fetched_article_crawled_time", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600 + ) + ) + + +def set_next_newer_than(incidents: list[dict]) -> None: + if not incidents: + return + newer_than = datetime.fromisoformat(max(incident["occured"] for incident in incidents)).timestamp() + demisto.setLastRun({"last_fetched_article_crawled_time": newer_than}) + + +def test_module(client: Client, params: dict) -> str: # pragma: no cover + """Builds the iterator to check that the feed is accessible. + Args: + client: Client object. + params: demisto.params() + Returns: + Outputs. + """ + try: + client.fetch_incidents_from_stream(params["feedly_stream_id"], newer_than=time.time() - 3600) + return "ok" + except DemistoException as e: + return e.message + except Exception as e: + return str(e) + + def main() -> None: params = demisto.params() @@ -1006,9 +1036,11 @@ def main() -> None: ) if command == "fetch-incidents": - now = time.time() - demisto.incidents(fetch_incidents(client, params, demisto.getLastRun())) - demisto.setLastRun({"last_successful_run": str(now)}) + incidents = fetch_incidents(client, params, demisto.getLastRun()) + demisto.incidents(incidents) + set_next_newer_than(incidents) + if command == "test-module": + return_results(test_module(client, params)) else: raise NotImplementedError(f"Command {command} is not implemented.") except Exception as e: diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md new file mode 100644 index 000000000000..5cef866755f4 --- /dev/null +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md @@ -0,0 +1,11 @@ +## Feedly + +Use the Feedly integration to import articles as incidents from your Feedly boards and folders. + +**Note** You also need to setup the `FeedFeedly` integration with the same feeds, to ingest entities (intrusion sets, malware, TTPs) as indicators, and relationships between them. The `IncidentsFeedly` integration will work without it, but the incidents will be missing context. + +**Disclaimer** You will need the Feedly for Threat Intelligence package to enable this integration. You can learn more about our product here: https://feedly.com/i/landing/threatIntelligence + +### Authentication + +To generate an API for the application, go to [the api page on your account](https://feedly.com/i/team/api). We highly recommend that you create a separate token for this integration. diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md b/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md new file mode 100644 index 000000000000..f2b330101707 --- /dev/null +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md @@ -0,0 +1,25 @@ +Ingest articles as incidents from Feedly into XSOAR. + +## Configure Feedly on Cortex XSOAR + +1. Navigate to **Settings** > **Integrations** > **Servers & Services**. +2. Search for IncidentsFeedly. +3. Click **Add instance** to create and configure a new integration instance. + + | **Parameter** | **Description** | **Required** | + | --- | --- | --- | + | API key | | False | + | Indicator Reputation | Indicators from this integration instance will be marked with this reputation | False | + | Source Reliability | Reliability of the source providing the intelligence data | True | + | Traffic Light Protocol Color | The Traffic Light Protocol \(TLP\) designation to apply to indicators fetched from the feed | False | + | Feed Fetch Interval | | False | + | Bypass exclusion list | When selected, the exclusion list is ignored for indicators from this feed. This means that if an indicator from this feed is on the exclusion list, the indicator might still be added to the system. | False | + | Trust any certificate (not secure) | | False | + | Use system proxy settings | | False | + | | | False | + | | | False | + | Stream ID | The stream id you want to fetch articles from. You can find it in Feedly by going to the stream, clicking on \`...\` > \`Sharing\`, then \`Copy ID\` in the \`Feedly API Stream ID\` section. | True | + | Days to fetch for first run | Number of days to fetch articles from when running the integration for the first time | True | + | Incremental feed | Incremental feeds pull only new or modified indicators that have been sent from the integration. The determination if the indicator is new or modified happens on the 3rd-party vendor's side, so only indicators that are new or modified are sent to Cortex XSOAR. Therefore, all indicators coming from these feeds are labeled new or modified. | False | + +4. Click **Test** to validate the URLs, token, and connection. From ce8883f04011703b19f660d26a67a1f21c580aa7 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 14 Nov 2024 13:01:12 +0100 Subject: [PATCH 08/27] [feedly] wip --- .../classifier-Feedly_-_Report_Mapper.json | 11 +- .../IncidentFields/incident_customfields.json | 50 ++-- .../IncidentTypes/customIncidentTypes.json | 15 +- .../layoutscontainer-Feedly_Report.json | 110 +++++++- Packs/FeedFeedly/Playbooks/Feedly_threats.yml | 265 ++++++++++++++++++ 5 files changed, 403 insertions(+), 48 deletions(-) create mode 100644 Packs/FeedFeedly/Playbooks/Feedly_threats.yml diff --git a/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json b/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json index f1c0167cdfd2..32dd0c099b30 100644 --- a/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json +++ b/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json @@ -13,7 +13,7 @@ "itemVersion": "", "keyTypeMap": {}, "locked": false, - "logicalVersion": 8, + "logicalVersion": 10, "mapping": { "dbot_classification_incident_type_all": { "dontMapEventToLabels": true, @@ -33,6 +33,12 @@ "Event ID": { "simple": "event_id" }, + "Feedly Malware Names": { + "simple": "indicators.Malware" + }, + "Feedly Threat Actor Names": { + "simple": "indicators.Threat Actor" + }, "Feedly crawled date": { "simple": "create_time" }, @@ -61,6 +67,9 @@ "transformers": [] } }, + "Threat Name": { + "simple": "indicators.Malware" + }, "URLs": { "simple": "indicators.URL" }, diff --git a/Packs/FeedFeedly/IncidentFields/incident_customfields.json b/Packs/FeedFeedly/IncidentFields/incident_customfields.json index 0dbd96a9637d..7350529c5742 100644 --- a/Packs/FeedFeedly/IncidentFields/incident_customfields.json +++ b/Packs/FeedFeedly/IncidentFields/incident_customfields.json @@ -62,10 +62,10 @@ "aliasTo": "" }, { - "id": "incident_feedlyurl", - "version": 3, + "id": "incident_feedlymalwarenames", + "version": 1, "cacheVersn": 0, - "modified": "2024-10-10T14:33:09.220777761Z", + "modified": "2024-11-13T14:27:30.49621132Z", "created": "0001-01-01T00:00:00Z", "sizeInBytes": 0, "packID": "", @@ -78,15 +78,15 @@ "vcShouldKeepItemLegacyProdMachine": false, "commitMessage": "", "shouldCommit": false, - "name": "Feedly url", - "prevName": "Feedly url", + "name": "Feedly Malware Names", + "prevName": "Feedly Malware Names", "ownerOnly": false, "placeholder": "", "template": "", "description": "", - "cliName": "feedlyurl", - "type": "url", - "orgType": "shortText", + "cliName": "feedlymalwarenames", + "type": "multiSelect", + "orgType": "multiSelect", "closeForm": false, "editForm": true, "required": false, @@ -106,8 +106,8 @@ "group": 0, "mergeStrategy": "", "hidden": false, - "openEnded": false, - "associatedTypes": [], + "openEnded": true, + "associatedTypes": null, "systemAssociatedTypes": null, "associatedToAll": true, "unmapped": false, @@ -123,10 +123,10 @@ "aliasTo": "" }, { - "id": "incident_sourcename", - "version": 2, + "id": "incident_feedlythreatactornames", + "version": 1, "cacheVersn": 0, - "modified": "2024-10-10T12:23:08.304820086Z", + "modified": "2024-11-13T14:29:40.202843194Z", "created": "0001-01-01T00:00:00Z", "sizeInBytes": 0, "packID": "", @@ -139,15 +139,15 @@ "vcShouldKeepItemLegacyProdMachine": false, "commitMessage": "", "shouldCommit": false, - "name": "Source name", - "prevName": "Source name", + "name": "Feedly Threat Actor Names", + "prevName": "Feedly Threat Actor Names", "ownerOnly": false, "placeholder": "", "template": "", "description": "", - "cliName": "sourcename", - "type": "shortText", - "orgType": "shortText", + "cliName": "feedlythreatactornames", + "type": "multiSelect", + "orgType": "multiSelect", "closeForm": false, "editForm": true, "required": false, @@ -167,8 +167,8 @@ "group": 0, "mergeStrategy": "", "hidden": false, - "openEnded": false, - "associatedTypes": [], + "openEnded": true, + "associatedTypes": null, "systemAssociatedTypes": null, "associatedToAll": true, "unmapped": false, @@ -184,10 +184,10 @@ "aliasTo": "" }, { - "id": "incident_sourceurl", + "id": "incident_feedlyurl", "version": 3, "cacheVersn": 0, - "modified": "2024-10-10T14:33:25.185611243Z", + "modified": "2024-10-10T14:33:09.220777761Z", "created": "0001-01-01T00:00:00Z", "sizeInBytes": 0, "packID": "", @@ -200,13 +200,13 @@ "vcShouldKeepItemLegacyProdMachine": false, "commitMessage": "", "shouldCommit": false, - "name": "Source url", - "prevName": "Source url", + "name": "Feedly url", + "prevName": "Feedly url", "ownerOnly": false, "placeholder": "", "template": "", "description": "", - "cliName": "sourceurl", + "cliName": "feedlyurl", "type": "url", "orgType": "shortText", "closeForm": false, diff --git a/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json b/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json index f10b28d3edd2..3678788836de 100644 --- a/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json +++ b/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json @@ -1,9 +1,9 @@ [ { "id": "Feedly Report", - "version": 6, + "version": 7, "cacheVersn": 0, - "modified": "2024-10-10T13:51:44.813997902Z", + "modified": "2024-11-13T15:01:36.04775714Z", "created": "0001-01-01T00:00:00Z", "sizeInBytes": 0, "packID": "", @@ -20,6 +20,7 @@ "name": "Feedly Report", "prevName": "Feedly Report", "color": "#F8E7A5", + "playbookId": "5e043079-e3a4-44b4-863f-80774c07c1e7", "hours": 0, "days": 0, "weeks": 0, @@ -29,7 +30,7 @@ "system": false, "readonly": false, "default": false, - "autorun": false, + "autorun": true, "preProcessingScript": "", "closureScript": "", "disabled": false, @@ -92,16 +93,12 @@ "mitretechniqueid": { "extractAsIsIndicatorTypeId": "", "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "Attack Pattern" - ] + "extractIndicatorTypesIDs": [] }, "mitretechniquename": { "extractAsIsIndicatorTypeId": "", "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "Attack Pattern" - ] + "extractIndicatorTypesIDs": [] }, "selectedindicators": { "extractAsIsIndicatorTypeId": "", diff --git a/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json b/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json index c247a6659b62..9fa980845dd1 100644 --- a/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json +++ b/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json @@ -60,11 +60,13 @@ "startCol": 0 }, { + "dropEffect": "move", "endCol": 2, "fieldId": "feedlyurl", "height": 22, "id": "bc06e420-8701-11ef-88e5-01f8fe79530d", "index": 1, + "listId": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", "sectionItemType": "field", "startCol": 0 }, @@ -73,27 +75,27 @@ "fieldId": "sourcename", "height": 22, "id": "b4bf55d0-8701-11ef-88e5-01f8fe79530d", - "index": 2, + "index": 3, "sectionItemType": "field", "startCol": 0 }, { + "dropEffect": "move", "endCol": 2, "fieldId": "sourceurl", "height": 22, "id": "b8e44760-8701-11ef-88e5-01f8fe79530d", "index": 3, + "listId": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", "sectionItemType": "field", "startCol": 0 }, { - "dropEffect": "move", "endCol": 2, "fieldId": "tags", "height": 22, - "id": "e64b9ec0-8700-11ef-88e5-01f8fe79530d", + "id": "88895d10-a1de-11ef-823c-870772ed0f9a", "index": 4, - "listId": "h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", "sectionItemType": "field", "startCol": 0 } @@ -176,20 +178,20 @@ "width": 190 } ], - "h": 4, + "h": 3, "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-e33dd7a0-8702-11ef-88e5-01f8fe79530d", "items": [], "maxW": 3, "minH": 1, "moved": false, "name": "Indicators of compromise", - "query": "-type:\"Attack Pattern\"", + "query": "-type:\"Attack Pattern\" -type:Malware -type:\"Intrusion Set\"", "queryType": "input", "static": false, "type": "indicators", "w": 1, "x": 2, - "y": 2 + "y": 5 }, { "columns": [ @@ -260,7 +262,7 @@ "width": 190 } ], - "h": 5, + "h": 3, "i": "h2hjyyhld4-b282caf0-870f-11ef-88e5-01f8fe79530d", "items": [], "maxW": 3, @@ -273,7 +275,91 @@ "type": "indicators", "w": 1, "x": 2, - "y": 6 + "y": 8 + }, + { + "columns": [ + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 300 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "relatedIncCount", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "h": 3, + "i": "h2hjyyhld4-6e0a9cf0-a1d5-11ef-aeae-93c18a8c3773", + "items": [], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Threats", + "query": "type:\"Intrusion Set\" or type:Malware", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 1, + "x": 2, + "y": 2 } ], "type": "custom" @@ -358,13 +444,11 @@ } ], "description": "The list of indicators related to the incident.", - "h": 5, - "i": "zfhf0tdhhj-h2hjyyhld4-caseinfoid-indeooemoh-1840e830-6dd5-11ea-9e64-73fcd6758f5c", + "h": 7, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-indeooemoh-1840e830-6dd5-11ea-9e64-73fcd6758f5c", "items": [], - "maxH": null, "maxW": 3, "minH": 1, - "minW": 3, "moved": false, "name": "Indicators related to incident", "query": "", diff --git a/Packs/FeedFeedly/Playbooks/Feedly_threats.yml b/Packs/FeedFeedly/Playbooks/Feedly_threats.yml new file mode 100644 index 000000000000..0a6055fc0347 --- /dev/null +++ b/Packs/FeedFeedly/Playbooks/Feedly_threats.yml @@ -0,0 +1,265 @@ +id: 5e043079-e3a4-44b4-863f-80774c07c1e7 +version: 13 +vcShouldKeepItemLegacyProdMachine: false +name: Feedly threats +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: c1841fcb-b6ec-40b6-89e9-3a68f6c62b43 + type: start + task: + id: c1841fcb-b6ec-40b6-89e9-3a68f6c62b43 + version: -1 + name: "" + iscommand: false + brand: "" + nexttasks: + '#none#': + - "1" + - "3" + - "5" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 610, + "y": -160 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "1": + id: "1" + taskid: 5933c19b-36f8-4f1b-8410-e0d0b2a5631a + type: regular + task: + id: 5933c19b-36f8-4f1b-8410-e0d0b2a5631a + version: -1 + name: Search TTP Indicators + description: |- + Searches Cortex XSOAR Indicators. + + Search for XSOAR Indicators and returns the id, indicator_type, value, and score/verdict. + + You can add additional fields from the indicators using the add_field_to_context argument. + scriptName: SearchIndicator + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "4" + scriptarguments: + add_fields_to_context: + simple: mitreid + query: + complex: + root: incident + accessor: mitretechniqueid + transformers: + - operator: join + args: + separator: + value: + simple: ' or ' + - operator: concat + args: + prefix: + value: + simple: mitreid:( + suffix: + value: + simple: ) + size: + simple: "100" + separatecontext: false + continueonerror: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 140, + "y": 210 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "3": + id: "3" + taskid: 4033a0ca-5137-475a-82d4-628041ce1942 + type: regular + task: + id: 4033a0ca-5137-475a-82d4-628041ce1942 + version: -1 + name: Search Malware indicators + description: |- + Searches Cortex XSOAR Indicators. + + Search for XSOAR Indicators and returns the id, indicator_type, value, and score/verdict. + + You can add additional fields from the indicators using the add_field_to_context argument. + scriptName: SearchIndicator + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "4" + scriptarguments: + query: + complex: + root: incident + accessor: feedlymalwarenames + transformers: + - operator: join + args: + separator: + value: + simple: '" or "' + - operator: concat + args: + prefix: + value: + simple: type:Malware value:(" + suffix: + value: + simple: '")' + size: + simple: "100" + separatecontext: false + continueonerror: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 610, + "y": 210 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "4": + id: "4" + taskid: d581f385-d714-4ae1-8a8d-ca4ae527a944 + type: regular + task: + id: d581f385-d714-4ae1-8a8d-ca4ae527a944 + version: -1 + name: Associate Indicators + description: commands.local.cmd.associate.indicators + script: Builtin|||associateIndicatorsToIncident + type: regular + iscommand: true + brand: Builtin + scriptarguments: + incidentId: + simple: ${incident.id} + indicatorsIDs: + simple: ${foundIndicators.id} + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 610, + "y": 530 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "5": + id: "5" + taskid: 456dd4a5-485f-44fe-8085-e19f70c9ac3a + type: regular + task: + id: 456dd4a5-485f-44fe-8085-e19f70c9ac3a + version: -1 + name: Search Threat Actor Indicators + description: |- + Searches Cortex XSOAR Indicators. + + Search for XSOAR Indicators and returns the id, indicator_type, value, and score/verdict. + + You can add additional fields from the indicators using the add_field_to_context argument. + scriptName: SearchIndicator + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "4" + scriptarguments: + query: + complex: + root: incident + accessor: feedlythreatactornames + transformers: + - operator: join + args: + separator: + value: + simple: '" or "' + - operator: concat + args: + prefix: + value: + simple: type:"Intrusion Set" value:(" + suffix: + value: + simple: '")' + size: + simple: "100" + separatecontext: false + continueonerror: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 1100, + "y": 200 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false +view: |- + { + "linkLabelsPosition": {}, + "paper": { + "dimensions": { + "height": 785, + "width": 1340, + "x": 140, + "y": -160 + } + } + } +inputs: [] +outputs: [] +quiet: true From 02b022e695c00cec38bdeba3bbe2bab6fc947d0c Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 14 Nov 2024 13:11:11 +0100 Subject: [PATCH 09/27] [feedly] wip --- .../Integrations/FeedFeedly/FeedFeedly_description.md | 2 +- .../Integrations/IncidentsFeedly/IncidentsFeedly_description.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md index cb7238c5e65d..8daf98772bc0 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_description.md @@ -1,6 +1,6 @@ ## Feedly -Use the Feedly integration to import articles with entities, indicators, and relationships from your Feedly boards and folders. +Use the FeedFeedly integration to import articles with entities, indicators, and relationships as indicators from your Feedly boards and folders. **Note** There is a second integration `IncidentsFeedly` that can be used to ingest articles as incidents instead of indicators. This `FeedFeedly` integration is still needed, to ingest entities (intrusion sets, malware, TTPs) as indicators, and relationships between them. diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md index 5cef866755f4..30f2664793cc 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md @@ -1,6 +1,6 @@ ## Feedly -Use the Feedly integration to import articles as incidents from your Feedly boards and folders. +Use the IncidentsFeedly integration to import articles as incidents from your Feedly boards and folders. **Note** You also need to setup the `FeedFeedly` integration with the same feeds, to ingest entities (intrusion sets, malware, TTPs) as indicators, and relationships between them. The `IncidentsFeedly` integration will work without it, but the incidents will be missing context. From 7cda2f3ccfa77252e470708f685d030c02045fcf Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 14 Nov 2024 13:14:42 +0100 Subject: [PATCH 10/27] [feedly] wip --- Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md b/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md index f2b330101707..ad5364b1a051 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md @@ -9,9 +9,7 @@ Ingest articles as incidents from Feedly into XSOAR. | **Parameter** | **Description** | **Required** | | --- | --- | --- | | API key | | False | - | Indicator Reputation | Indicators from this integration instance will be marked with this reputation | False | - | Source Reliability | Reliability of the source providing the intelligence data | True | - | Traffic Light Protocol Color | The Traffic Light Protocol \(TLP\) designation to apply to indicators fetched from the feed | False | + | isFetch | Fetch incidents | False | | Feed Fetch Interval | | False | | Bypass exclusion list | When selected, the exclusion list is ignored for indicators from this feed. This means that if an indicator from this feed is on the exclusion list, the indicator might still be added to the system. | False | | Trust any certificate (not secure) | | False | From 3884bb59fd1c2f58509d0f4f7c53455783390966 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 14 Nov 2024 13:22:16 +0100 Subject: [PATCH 11/27] [feedly] wip --- .../Integrations/FeedFeedly/FeedFeedly.py | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index 901adfb87c55..633c5eb3cb8d 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -118,7 +118,7 @@ class Client(BaseClient): def fetch_indicators_from_stream( self, stream_id: str, newer_than: float, *, limit: int | None = None, ingest_reports: bool = True - ) -> list: + ) -> tuple[list, float | None]: params = { "streamId": stream_id, "count": 20, @@ -149,7 +149,7 @@ def fetch_indicators_from_stream( indicator["type"] = indicator.get("indicator_type", "") indicator["fields"] = indicator.get("customFields", {}) - return indicators + return indicators, extract_next_newer_than(objects) class STIX2Parser: @@ -973,7 +973,7 @@ def get_indicators_command( Returns: Outputs. """ - indicators = client.fetch_indicators_from_stream( + indicators, _ = client.fetch_indicators_from_stream( params["feedly_stream_id"], newer_than=time.time() - 24 * 3600, limit=int(args.get("limit", "10")), @@ -983,7 +983,9 @@ def get_indicators_command( return CommandResults(readable_output=f"Created {len(indicators)} indicators.") -def fetch_indicators_command(client: Client, params: dict[str, str], context: dict[str, str]) -> list[dict]: +def fetch_indicators_command( + client: Client, params: dict[str, str], context: dict[str, str] +) -> tuple[list, float | None]: """Wrapper for fetching indicators from the feed to the Indicators tab. Args: client: Client object with request @@ -1007,17 +1009,16 @@ def get_newer_than_timestamp(params: dict[str, str], context: dict[str, str]) -> ) -def set_next_newer_than(indicators: list[dict[str, str]]) -> None: - if not indicators: - return - newer_than = datetime.fromisoformat( - max( - indicator["fields"]["published"] # type: ignore - for indicator in indicators - if indicator["type"] == "Feedly Report" - ) +def extract_next_newer_than(stix_objects: list[dict[str, str]]) -> float | None: + if not stix_objects: + return None + return datetime.fromisoformat( + max(stix_object["created"] for stix_object in stix_objects if stix_object.get("type") == "report") ).timestamp() - demisto.setLastRun({"last_fetched_article_crawled_time": newer_than}) + + +def set_next_newer_than(next_newer_than: float) -> None: + demisto.setLastRun({"last_fetched_article_crawled_time": next_newer_than}) def main(): # pragma: no cover @@ -1043,10 +1044,11 @@ def main(): # pragma: no cover return_results(get_indicators_command(client, params, args)) elif command == "fetch-indicators": - indicators = fetch_indicators_command(client, params, demisto.getLastRun()) + indicators, next_newer_than = fetch_indicators_command(client, params, demisto.getLastRun()) for indicators_batch in batch(indicators, batch_size=2000): demisto.createIndicators(indicators_batch) # type: ignore - set_next_newer_than(indicators) + if next_newer_than: + set_next_newer_than(next_newer_than) else: raise NotImplementedError(f"Command {command} is not implemented.") From 80ff003da7dd85a0ec41585c9201db20f46b30b6 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 14 Nov 2024 13:23:43 +0100 Subject: [PATCH 12/27] WIP --- .../FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py index 3aeba0e06a33..351fbea3aa0a 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py @@ -1039,7 +1039,7 @@ def main() -> None: incidents = fetch_incidents(client, params, demisto.getLastRun()) demisto.incidents(incidents) set_next_newer_than(incidents) - if command == "test-module": + elif command == "test-module": return_results(test_module(client, params)) else: raise NotImplementedError(f"Command {command} is not implemented.") From c570e933ce727c5a7688fb3c4139b3778575c0a9 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Fri, 15 Nov 2024 10:51:59 +0100 Subject: [PATCH 13/27] WIP --- Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py | 2 +- .../FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index 146c26cba6d1..b9ceb1d19d7d 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -337,7 +337,7 @@ def parse_report(self, report_obj: dict[str, Any]) -> tuple[list[dict[str, Any]] fields = { "stixid": report_obj.get("id"), "firstseenbysource": report_obj.get("created"), - "published": report_obj.get("created"), # todo + "published": report_obj.get("published"), "description": report_obj.get("description", ""), "report_types": report_obj.get("report_types", []), "tags": list(set(report_obj.get("labels", []))), diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py index 351fbea3aa0a..ca59eacb8911 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py @@ -961,7 +961,7 @@ def create_incident_from_report_indicator(indicator: dict) -> dict: event = { "name": indicator["value"], - "create_time": indicator["rawJSON"].get("created"), # todo + "create_time": indicator["rawJSON"].get("published"), "event_id": entry_id, "feedly_url": feedly_url, "tags": indicator["rawJSON"].get("labels", []), From 720b8761bde0fbf676bf8f95cb39cd15de4dd179 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Fri, 15 Nov 2024 12:17:05 +0100 Subject: [PATCH 14/27] [feedly] fix newerThan for tags --- .../Integrations/FeedFeedly/FeedFeedly.py | 23 +++++++++++-------- .../IncidentsFeedly/IncidentsFeedly.py | 21 +++++++++-------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index b9ceb1d19d7d..bf9785c95073 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -1002,11 +1002,13 @@ def fetch_indicators_command( def get_newer_than_timestamp(params: dict[str, str], context: dict[str, str]) -> float: - return float( - context.get( - "last_fetched_article_crawled_time", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600 - ) - ) + stream_id = params["feedly_stream_id"] + if "/tag/" in stream_id: + saved_timestamp = context.get("last_run") + else: + saved_timestamp = context.get("last_fetched_article_crawled_time") + + return float(saved_timestamp or (time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600)) def extract_next_newer_than(stix_objects: list[dict[str, str]]) -> float | None: @@ -1017,8 +1019,8 @@ def extract_next_newer_than(stix_objects: list[dict[str, str]]) -> float | None: ).timestamp() -def set_next_newer_than(next_newer_than: float) -> None: - demisto.setLastRun({"last_fetched_article_crawled_time": next_newer_than}) +def set_next_newer_than(last_article_time: float, now: float) -> None: + demisto.setLastRun({"last_fetched_article_crawled_time": last_article_time, "last_run": now}) def main(): # pragma: no cover @@ -1044,11 +1046,12 @@ def main(): # pragma: no cover return_results(get_indicators_command(client, params, args)) elif command == "fetch-indicators": - indicators, next_newer_than = fetch_indicators_command(client, params, demisto.getLastRun()) + now = time.time() + indicators, last_fetched_article_time = fetch_indicators_command(client, params, demisto.getLastRun()) for indicators_batch in batch(indicators, batch_size=2000): demisto.createIndicators(indicators_batch) # type: ignore - if next_newer_than: - set_next_newer_than(next_newer_than) + if indicators: + set_next_newer_than(last_fetched_article_time, now) # type: ignore else: raise NotImplementedError(f"Command {command} is not implemented.") diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py index ca59eacb8911..f30b64a0347d 100644 --- a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py +++ b/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py @@ -991,18 +991,20 @@ def fetch_incidents(client: Client, params: dict[str, str], context: dict[str, s def get_newer_than_timestamp(params: dict[str, str], context: dict[str, str]) -> float: - return float( - context.get( - "last_fetched_article_crawled_time", time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600 - ) - ) + stream_id = params["feedly_stream_id"] + if "/tag/" in stream_id: + saved_timestamp = context.get("last_run") + else: + saved_timestamp = context.get("last_fetched_article_crawled_time") + + return float(saved_timestamp or (time.time() - int(params.get("days_to_backfill", 7)) * 24 * 3600)) -def set_next_newer_than(incidents: list[dict]) -> None: +def set_next_newer_than(incidents: list[dict], now: float) -> None: if not incidents: return - newer_than = datetime.fromisoformat(max(incident["occured"] for incident in incidents)).timestamp() - demisto.setLastRun({"last_fetched_article_crawled_time": newer_than}) + last_fetched_article_time = datetime.fromisoformat(max(incident["occured"] for incident in incidents)).timestamp() + demisto.setLastRun({"last_fetched_article_crawled_time": last_fetched_article_time, "last_run": now}) def test_module(client: Client, params: dict) -> str: # pragma: no cover @@ -1036,9 +1038,10 @@ def main() -> None: ) if command == "fetch-incidents": + now = time.time() incidents = fetch_incidents(client, params, demisto.getLastRun()) demisto.incidents(incidents) - set_next_newer_than(incidents) + set_next_newer_than(incidents, now) elif command == "test-module": return_results(test_module(client, params)) else: From b64838f7fee9e6f5fe5f0afccaeed608f4fc49b6 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 19 Nov 2024 16:21:07 +0100 Subject: [PATCH 15/27] [feedly] fix test --- .../FeedFeedly/Integrations/FeedFeedly/FeedFeedly_test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_test.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_test.py index 1722f85d15d3..b475d3393c4b 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_test.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly_test.py @@ -30,8 +30,12 @@ def test_build_iterator(requests_mock): response = file.read() requests_mock.get(URL, text=response) expected_ips = {"31.31.194.65", "95.213.205.83", "77.223.124.212"} - client = Client(base_url=URL, verify=False, proxy=False,) - indicators = client.fetch_indicators_from_stream("tag/enterpriseName/category/uuid", 0) + client = Client( + base_url=URL, + verify=False, + proxy=False, + ) + indicators = client.fetch_indicators_from_stream("tag/enterpriseName/category/uuid", 0)[0] ip_indicators = {indicator["value"] for indicator in indicators if indicator["type"] == "IP"} assert expected_ips == ip_indicators From 2c167052056d20e4da4abaaea72faaf85b075b3c Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 19 Nov 2024 16:33:26 +0100 Subject: [PATCH 16/27] [feedly] fix coverage --- Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py index bf9785c95073..4cbecc44bc93 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/FeedFeedly.py @@ -985,7 +985,7 @@ def get_indicators_command( def fetch_indicators_command( client: Client, params: dict[str, str], context: dict[str, str] -) -> tuple[list, float | None]: +) -> tuple[list, float | None]: # pragma: no cover """Wrapper for fetching indicators from the feed to the Indicators tab. Args: client: Client object with request @@ -1001,7 +1001,7 @@ def fetch_indicators_command( ) -def get_newer_than_timestamp(params: dict[str, str], context: dict[str, str]) -> float: +def get_newer_than_timestamp(params: dict[str, str], context: dict[str, str]) -> float: # pragma: no cover stream_id = params["feedly_stream_id"] if "/tag/" in stream_id: saved_timestamp = context.get("last_run") @@ -1019,7 +1019,7 @@ def extract_next_newer_than(stix_objects: list[dict[str, str]]) -> float | None: ).timestamp() -def set_next_newer_than(last_article_time: float, now: float) -> None: +def set_next_newer_than(last_article_time: float, now: float) -> None: # pragma: no cover demisto.setLastRun({"last_fetched_article_crawled_time": last_article_time, "last_run": now}) From cd613661077e97354f373527e4e76153196c16fa Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 19 Nov 2024 16:48:24 +0100 Subject: [PATCH 17/27] [feedly] fix tests --- .../Integrations/FeedFeedly/test_data/api_call_mock.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packs/FeedFeedly/Integrations/FeedFeedly/test_data/api_call_mock.txt b/Packs/FeedFeedly/Integrations/FeedFeedly/test_data/api_call_mock.txt index 21d5d2f7cd5c..337a9496c4f8 100644 --- a/Packs/FeedFeedly/Integrations/FeedFeedly/test_data/api_call_mock.txt +++ b/Packs/FeedFeedly/Integrations/FeedFeedly/test_data/api_call_mock.txt @@ -1 +1 @@ -{"type": "bundle", "id": "bundle--32cd1e04-c095-473b-baa8-11efda980da5", "objects": [{"type": "identity", "spec_version": "2.1", "id": "identity--477866fd-8784-46f9-ab40-5592ed4eddd7", "created": "2023-10-08T20:06:11.507598Z", "modified": "2023-10-08T20:06:11.507598Z", "name": "Feedly AI", "identity_class": "organization", "external_references": [{"source_name": "Feedly", "url": "https://feedly.com/i/landing/threatIntelligence"}]}, {"type": "report", "spec_version": "2.1", "id": "report--1c9014de-c4fd-5db7-b562-dd321a6f94e1", "created_by_ref": "identity--477866fd-8784-46f9-ab40-5592ed4eddd7", "created": "2023-10-09T05:29:08.986171Z", "modified": "2023-10-09T05:29:08.986171Z", "name": "Threat Actors Employ Remote Admin Tools to Gain Access over Corpora...", "description": "Recently, threat actors have adapted tactics, exploiting the appeal of banned apps in specific regions, making users more susceptible to cyberattacks through cleverly crafted campaigns.\n\n In a recent campaign, Chinese users were lured with a fake Telegram installer to illustrate this tactic.\n\n Cybersecurity researchers at CRIL (Cyble Research and Intelligence Labs) noted a campaign targeting Russian users, where threat actors created phishing sites mimicking restricted apps like-\n\n * ExpressVPN\n* WeChat\n* Skype\n\n FREE Demo [Deploy Advanced AI-Powered Email Security Solution](https://cybersecuritynews.com/threat-actors-employ-remote-admin-tools/#)\n------------------------------------------------------------------------------------------------------------------------------\n\n Implementing AI-Powered Email security solutions \u201cTrustifi\u201d can secure your business from today\u2019s most dangerous email threats, such as Email Tracking, Blocking, Modifying, Phishing, Account Take Over, Business Email Compromise, Malware & Ransomware\n\n Experts [identified](https://cyble.com/blog/rms-tools-sneaky-comeback-phishing-campaign-mirroring-banned-applications/) the following phishing domains delivering RMS, disguising as legitimate OS applications but distributing malware:-\n\n * express-vpn[.]fun\n* we-chat[.]info\n* join-skype[.]com\n\n **Threat Actors Employ Remote Admin Tools**\n-------------------------------------------\n\n The consistent use of the same RMS executable across these phishing sites strongly suggests a single or closely coordinated threat actor group was behind these attacks.\n\n The phishing sites distributed either a malicious Self-extracting archive (SFX) or an RMS binary. For instance, the ExpressVPN [phishing site](https://cybersecuritynews.com/sophisticated-phishing-campaigns/) in this campaign downloads an SFX archive that mimics a genuine installer but delivers malware upon execution.\n\n After execution, the SFX file modifies the \u2018HKCU\\Software\\WinRAR SFX\u2019 Registry key and creates a \u2018expressvpn\\_windows\\_12.58.0.4\\_release\u2019 folder in %temp% with specific files:-\n\n * **expressvpn.exe:** This file is an RMS executable.\n* **expressvpn\\_windows\\_12.58.0.4\\_release.exe:** This file is a clean ExpressVPN installer.\n\n ![SFX Archive](https://lh3.googleusercontent.com/HVMUAg3bQx5KiR5Y0-xStUaZYYjVzbDVGMbzEHhAph1cM3pqIZHjrpNlzvcrntRVhi9uZiUBCCAnBFq6skEjNFNgXZfrZEK7rLhRbrjAmay9KWj4tJKMu8TOLjesN8pzCRe3m_3Dn__Y1zDrYerzTds)SFX Archive (Source \u2013 Cyble) The SFX file quietly runs an RMS executable in the background while simultaneously using the ExpressVPN installation wizard as a decoy to divert and confuse users.\n\n ![Process Tree ](https://lh3.googleusercontent.com/SxlJyO42OJdeXBATgQk5eHRPcimuVWOBOrAFj60oL0ONat_K432fVqb-LcZg2i1lVFfyigA2er6y6eYu_skVCgV6Z797-2W8OEr5-rNt8RBJDItiGboWSWI8w-8qhLcpRjQLAdc22D5_4bqnzZjyCms)Process Tree (Source \u2013 Cyble) RMS, initially a legitimate tool, has been used in campaigns by TA505 and other threat actors. It\u2019s free for non-commercial use and supports remote administration across multiple platforms, offering features like remote control and file transfers.\n\n After execution, \u2018expressvpn.exe\u2019 creates a unique folder in %temp%, drops \u2018host.msi,\u2019 silently installs it via msiexec.exe, and places RMS files in \u2018C:\\Program Files (x86)\\Remote Manipulator System \u2013 Host\u2019.\n\n The RMS client configuration is hex-encoded in a [Registry Key](https://cybersecuritynews.com/malicious-npm-and-pypi-packages/) and includes data for functions like:-\u00a0\n\n * Data transmission\n* Email alerts\n* Remote access\n* Screen recording\n\n The configuration data is organized into distinct sections, and here below, we have mentioned those sections:-\n\n * rms\\_inet\\_id\\_notification\n* security\\_settings\n* general\\_settings\n* rms\\_internet\\_id\\_settings\n* certificte\\_settings\n* sreen\\_record\\_option\n* local\\_settings\n\n RMS includes \u2018Internet-ID\u2019 for connecting to developer servers, sending an email notification containing victim details and remote access credentials, making attacks more accessible for less sophisticated threat actors.\n\n The notification email, sent via SMTP to \u201c31.31.194.65\u201d (resolved as \u201cmail.hosting.reg.ru\u201d), initiates C&C communications over TCP to transmit victim data.\n\n ![Network Connections](https://lh6.googleusercontent.com/Yikt0caFAsnOQHjqchVxCmSs9Wp7TSuP3ihLgbqgJBKxiX2T_H17eV8morHu90Yxe-grQlhOikiH19UpahSLk85Bxo0kgwb-aBQcDO_sZVn-sUs8qxqlTywoZNoSHPbX_NoUOuo5AyMQKW3o7u5y51U)Network Connections (Source \u2013 Cyble) Victim data, in Base64-encoded XML, goes to IP addresses 77.223.124.212 and 95.213.205.83 via port 5655. It mirrors registry-stored configuration data, including country code, device name, OS details, and an admin privilege flag.\n\n **Recommendations**\n-------------------\n\n Here below we have mentioned all the recommendations:-\n\n * Enforce application whitelisting to limit unapproved app execution, including remote admin tools, on endpoints.\n* Regularly check your system\u2019s services list, especially for \u201cRManService.\u201d If unsure, consider disabling or removing it.\n* Use network traffic tools to monitor outbound traffic, especially on port 5655, and set alerts for unusual patterns that could signal C&C server communication.\n\n Protect yourself from vulnerabilities using Patch Manager Plus to patch over 850 third-party applications quickly. Take advantage of the\u00a0**[free\u00a0trial](https://www.manageengine.com/patch-management/?utm_source=GBHackers&utm_medium=Website-CPM&utm_campaign=PMP-300x600)**\u00a0to ensure 100% security.\n\n The post [Threat Actors Employ Remote Admin Tools to Gain Access over Corporate Networks](https://cybersecuritynews.com/threat-actors-employ-remote-admin-tools/) appeared first on [Cyber Security News](https://cybersecuritynews.com).", "published": "2023-10-08T22:29:04.093Z", "object_refs": ["indicator--f75e3179-a61c-59eb-8289-17f81bb3f798", "indicator--b481fd72-1711-57b3-8f34-6fd9c63c4f9c", "indicator--1b844713-a2f5-59d6-9e1c-c58eccbb35f3", "indicator--7c8def1d-5256-5d51-bc12-08f32061ee6b", "indicator--90adec07-e9c8-5e3b-b68f-22e6405ab54f", "indicator--3bd554ee-d87d-5c43-9e05-22fc467c253c", "malware--94339b04-9332-4691-b820-5021368f1d3a", "threat-actor--03c80674-35f8-4fe0-be2b-226ed0fcd69f", "attack-pattern--04fd5427-79c7-44ea-ae13-11b24778ff1c", "attack-pattern--2e34237d-8574-43f6-aace-ae2915de8597", "attack-pattern--57340c81-c025-4189-8fa0-fc7ede51bae4", "attack-pattern--6faf650d-bf31-4eb4-802d-1000cf38efaf", "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b", "relationship--a36555cb-8add-43be-a33c-f962b0bfdbdb", "relationship--2b7379c8-7c83-4376-a362-f256fabd68d7", "relationship--74245dc1-1e4b-4b06-bf17-6216972008df", "relationship--c501cf08-3247-4c65-8598-22822e855423", "relationship--a1e8a44b-d902-4ddb-bc20-571e5b161086"], "labels": ["Feedly AI", "Domains", "IPs", "TTPs"], "external_references": [{"source_name": "Feedly article", "url": "https://feedly.com/i/entry/TUUqTqS5PmAnvMYxpxsJW4lVFUYs0KVkqWEL+fdotps=_18b12e9095d:b749c:e11a9d8"}, {"source_name": "Cyber Security News", "url": "https://cybersecuritynews.com/threat-actors-employ-remote-admin-tools/"}], "object_marking_refs": ["marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"]}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--f75e3179-a61c-59eb-8289-17f81bb3f798", "created": "2023-10-09T05:29:08.914199Z", "modified": "2023-10-09T05:29:08.914199Z", "name": "Domain", "pattern": "[domain-name:value = 'express-vpn.fun']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.914199Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--b481fd72-1711-57b3-8f34-6fd9c63c4f9c", "created": "2023-10-09T05:29:08.967244Z", "modified": "2023-10-09T05:29:08.967244Z", "name": "Domain", "pattern": "[domain-name:value = 'join-skype.com']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.967244Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--1b844713-a2f5-59d6-9e1c-c58eccbb35f3", "created": "2023-10-09T05:29:08.969479Z", "modified": "2023-10-09T05:29:08.969479Z", "name": "Domain", "pattern": "[domain-name:value = 'we-chat.info']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.969479Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--7c8def1d-5256-5d51-bc12-08f32061ee6b", "created": "2023-10-09T05:29:08.972597Z", "modified": "2023-10-09T05:29:08.972597Z", "name": "IPv4", "pattern": "[ipv4-addr:value = '95.213.205.83']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.972597Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--90adec07-e9c8-5e3b-b68f-22e6405ab54f", "created": "2023-10-09T05:29:08.975362Z", "modified": "2023-10-09T05:29:08.975362Z", "name": "IPv4", "pattern": "[ipv4-addr:value = '31.31.194.65']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.975362Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--3bd554ee-d87d-5c43-9e05-22fc467c253c", "created": "2023-10-09T05:29:08.977076Z", "modified": "2023-10-09T05:29:08.977076Z", "name": "IPv4", "pattern": "[ipv4-addr:value = '77.223.124.212']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.977076Z"}, {"type": "malware", "spec_version": "2.1", "id": "malware--94339b04-9332-4691-b820-5021368f1d3a", "created": "2023-10-08T19:16:53.819646Z", "modified": "2023-10-08T19:16:53.819646Z", "name": "RMS", "description": "CyberInt states that Remote Manipulator System (RMS) is a legitimate tool developed by Russian organization TektonIT and has been observed in campaigns conducted by TA505 as well as numerous smaller campaigns likely attributable to other, disparate, threat actors. In addition to the availability of commercial licenses, the tool is free for non-commercial use and supports the remote administration of both Microsoft Windows and Android devices.", "is_family": true, "aliases": ["Gussdoor", "RemoteManipulatorSystem", "RuRAT", "Remote Manipulator System"], "external_references": [{"source_name": "Source", "url": "https://awakesecurity.com/blog/catching-the-white-stork-in-flight/"}, {"source_name": "Source", "url": "https://blog.malwarebytes.com/threat-analysis/2017/09/cve-2017-0199-used-to-deliver-modified-rms-agent-rat/"}, {"source_name": "Source", "url": "https://blog.yoroi.company/research/ta505-is-expanding-its-operations/"}, {"source_name": "Source", "url": "https://e.cyberint.com/hubfs/Report%20Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors%20Tools/CyberInt_Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors'%20Tools_Report.pdf"}, {"source_name": "Source", "url": "https://ics-cert.kaspersky.com/media/Kaspersky-Attacks-on-industrial-enterprises-using-RMS-and-TeamViewer-EN.pdf"}, {"source_name": "Source", "url": "https://ssu.gov.ua/uploads/files/DKIB/Technical%20report%20Armagedon.pdf"}, {"source_name": "Source", "url": "https://unit42.paloaltonetworks.com/unit-42-title-gamaredon-group-toolset-evolution"}, {"source_name": "Source", "url": "https://web.archive.org/web/20161223002016/https://www.symantec.com/connect/blogs/odinaff-new-trojan-used-high-level-financial-attacks"}]}, {"type": "threat-actor", "spec_version": "2.1", "id": "threat-actor--03c80674-35f8-4fe0-be2b-226ed0fcd69f", "created": "2023-10-08T19:16:55.704495Z", "modified": "2023-10-08T19:16:55.704495Z", "name": "TA505", "description": "TA505, the name given by Proofpoint, has been in the cybercrime business for at least four years. This is the group behind the infamous Dridex banking trojan and Locky ransomware, delivered through malicious email campaigns via Necurs botnet. Other malware associated with TA505 include Philadelphia and GlobeImposter ransomware families.", "aliases": ["TA 505", "GRACEFUL SPIDER", "Hive0065", "G0092", "GracefulSpider", "SectorJ04 Group", "GoldTahoe", "SectorJ04", "GOLD TAHOE", "CHIMBORAZO", "Dudear", "ATK103", "ATK 103"], "external_references": [{"source_name": "Source", "url": "https://www.bleepingcomputer.com/news/security/ta505-group-adopts-new-servhelper-backdoor-and-flawedgrace-rat/"}, {"source_name": "Source", "url": "https://www.proofpoint.com/sites/default/files/ta505_timeline_final4_0.png"}, {"source_name": "Source", "url": "https://www.proofpoint.com/us/threat-insight/post/threat-actor-profile-ta505-dridex-globeimposter"}, {"source_name": "Source", "url": "https://www.cybereason.com/blog/threat-actor-ta505-targets-financial-enterprises-using-lolbins-and-a-new-backdoor-malware"}, {"source_name": "Source", "url": "https://e.cyberint.com/hubfs/Report%20Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors%20Tools/CyberInt_Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors'%20Tools_Report.pdf"}, {"source_name": "Source", "url": "https://threatpost.com/ta505-servhelper-malware/140792/"}, {"source_name": "Source", "url": "https://blog.yoroi.company/research/the-stealthy-email-stealer-in-the-ta505-arsenal/"}, {"source_name": "Source", "url": "https://threatrecon.nshc.net/2019/08/29/sectorj04-groups-increased-activity-in-2019/"}, {"source_name": "Source", "url": "https://www.proofpoint.com/us/threat-insight/post/ta505-distributes-new-sdbbot-remote-access-trojan-get2-downloader"}, {"source_name": "Source", "url": "https://www.blueliv.com/cyber-security-and-cyber-threat-intelligence-blog-blueliv/research/servhelper-evolution-and-new-ta505-campaigns/"}, {"source_name": "Source", "url": "https://www.telekom.com/en/blog/group/article/cybersecurity-ta505-s-box-of-chocolate-597672"}, {"source_name": "Source", "url": "https://www.telekom.com/en/blog/group/article/cybersecurity-ta505-returns-with-a-new-bag-of-tricks-602104"}, {"source_name": "Source", "url": "https://www.secureworks.com/research/threat-profiles/gold-tahoe"}, {"source_name": "Source", "url": "https://www.telekom.com/en/blog/group/article/eager-beaver-a-short-overview-of-the-restless-threat-actor-ta505-609546"}, {"source_name": "Source", "url": "https://blog.fox-it.com/2020/11/16/ta505-a-brief-history-of-their-time/"}, {"source_name": "Source", "url": "https://www.secureworks.com/blog/how-cyber-adversaries-are-adapting-to-exploit-the-global-pandemic"}, {"source_name": "Source", "url": "https://cyberthreat.thalesgroup.com/attackers/ATK103"}, {"source_name": "Source", "url": "https://securityintelligence.com/posts/ta505-continues-to-infect-networks-with-sdbbot-rat/"}, {"source_name": "Source", "url": "https://www.tenable.com/blog/cve-2020-1472-advanced-persistent-threat-actors-use-zerologon-vulnerability-in-exploit-chain"}]}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--04fd5427-79c7-44ea-ae13-11b24778ff1c", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2020-03-14T23:36:52.095Z", "modified": "2023-03-03T00:31:33.071Z", "name": "Standard Encoding", "description": "Adversaries may encode data with a standard data encoding system to make the content of command and control traffic more difficult to detect. Command and control (C2) information can be encoded using a standard data encoding system that adheres to existing protocol specifications. Common data encoding schemes include ASCII, Unicode, hexadecimal, Base64, and MIME.(Citation: Wikipedia Binary-to-text Encoding)(Citation: Wikipedia Character Encoding) Some data encoding systems may also result in data compression, such as gzip.", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "command-and-control"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1132/001", "external_id": "T1132.001"}, {"source_name": "University of Birmingham C2", "description": "Gardiner, J., Cova, M., Nagaraja, S. (2014, February). Command & Control Understanding, Denying and Detecting. Retrieved April 20, 2016.", "url": "https://arxiv.org/ftp/arxiv/papers/1408/1408.1136.pdf"}, {"source_name": "Wikipedia Binary-to-text Encoding", "description": "Wikipedia. (2016, December 26). Binary-to-text encoding. Retrieved March 1, 2017.", "url": "https://en.wikipedia.org/wiki/Binary-to-text_encoding"}, {"source_name": "Wikipedia Character Encoding", "description": "Wikipedia. (2017, February 19). Character Encoding. Retrieved March 1, 2017.", "url": "https://en.wikipedia.org/wiki/Character_encoding"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_data_sources": ["Network Traffic: Network Traffic Content"], "x_mitre_deprecated": false, "x_mitre_detection": "Analyze network data for uncommon data flows (e.g., a client sending significantly more data than it receives from a server). Processes utilizing the network that do not normally have network communication or have never been seen before are suspicious. Analyze packet contents to detect communications that do not follow the expected protocol behavior for the port that is being used.(Citation: University of Birmingham C2)", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": true, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["Linux", "macOS", "Windows"], "x_mitre_version": "1.0"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--2e34237d-8574-43f6-aace-ae2915de8597", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2020-03-02T19:05:18.137Z", "modified": "2023-03-30T21:01:42.995Z", "name": "Spearphishing Attachment", "description": "Adversaries may send spearphishing emails with a malicious attachment in an attempt to gain access to victim systems. Spearphishing attachment is a specific variant of spearphishing. Spearphishing attachment is different from other forms of spearphishing in that it employs the use of malware attached to an email. All forms of spearphishing are electronically delivered social engineering targeted at a specific individual, company, or industry. In this scenario, adversaries attach a file to the spearphishing email and usually rely upon [User Execution](https://attack.mitre.org/techniques/T1204) to gain execution. Spearphishing may also involve social engineering techniques, such as posing as a trusted source.\n\nThere are many options for the attachment such as Microsoft Office documents, executables, PDFs, or archived files. Upon opening the attachment (and potentially clicking past protections), the adversary's payload exploits a vulnerability or directly executes on the user's system. The text of the spearphishing email usually tries to give a plausible reason why the file should be opened, and may explain how to bypass system protections in order to do so. The email may also contain instructions on how to decrypt an attachment, such as a zip file password, in order to evade email boundary defenses. Adversaries frequently manipulate file extensions and icons in order to make attached executables appear to be document files, or files exploiting one application appear to be a file for a different one. ", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "initial-access"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1566/001", "external_id": "T1566.001"}, {"source_name": "Microsoft Anti Spoofing", "description": "Microsoft. (2020, October 13). Anti-spoofing protection in EOP. Retrieved October 19, 2020.", "url": "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spoofing-protection?view=o365-worldwide"}, {"source_name": "ACSC Email Spoofing", "description": "Australian Cyber Security Centre. (2012, December). Mitigating Spoofed Emails Using Sender Policy Framework. Retrieved October 19, 2020.", "url": "https://www.cyber.gov.au/sites/default/files/2019-03/spoof_email_sender_policy_framework.pdf"}, {"source_name": "Elastic - Koadiac Detection with EQL", "description": "Stepanic, D.. (2020, January 13). Embracing offensive tooling: Building detections against Koadic using EQL. Retrieved November 30, 2020.", "url": "https://www.elastic.co/blog/embracing-offensive-tooling-building-detections-against-koadic-using-eql"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Philip Winther"], "x_mitre_data_sources": ["Network Traffic: Network Traffic Flow", "Application Log: Application Log Content", "File: File Creation", "Network Traffic: Network Traffic Content"], "x_mitre_detection": "Network intrusion detection systems and email gateways can be used to detect spearphishing with malicious attachments in transit. Detonation chambers may also be used to identify malicious attachments. Solutions can be signature and behavior based, but adversaries may construct attachments in a way to avoid these systems.\n\nFiltering based on DKIM+SPF or header analysis can help detect when the email sender is spoofed.(Citation: Microsoft Anti Spoofing)(Citation: ACSC Email Spoofing)\n\nAnti-virus can potentially detect malicious documents and attachments as they're scanned to be stored on the email server or on the user's computer. Endpoint sensing or network sensing can potentially detect malicious events once the attachment is opened (such as a Microsoft Word document or PDF reaching out to the internet or spawning Powershell.exe) for techniques such as [Exploitation for Client Execution](https://attack.mitre.org/techniques/T1203) or usage of malicious scripts.\n\nMonitor for suspicious descendant process spawning from Microsoft Office and other productivity software.(Citation: Elastic - Koadiac Detection with EQL)", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": true, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["macOS", "Windows", "Linux"], "x_mitre_version": "2.2"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--57340c81-c025-4189-8fa0-fc7ede51bae4", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2017-05-31T21:31:23.587Z", "modified": "2023-04-21T12:19:38.962Z", "name": "Modify Registry", "description": "Adversaries may interact with the Windows Registry to hide configuration information within Registry keys, remove information as part of cleaning up, or as part of other techniques to aid in persistence and execution.\n\nAccess to specific areas of the Registry depends on account permissions, some requiring administrator-level access. The built-in Windows command-line utility [Reg](https://attack.mitre.org/software/S0075) may be used for local or remote Registry modification. (Citation: Microsoft Reg) Other tools may also be used, such as a remote access tool, which may contain functionality to interact with the Registry through the Windows API.\n\nRegistry modifications may also include actions to hide keys, such as prepending key names with a null character, which will cause an error and/or be ignored when read via [Reg](https://attack.mitre.org/software/S0075) or other utilities using the Win32 API. (Citation: Microsoft Reghide NOV 2006) Adversaries may abuse these pseudo-hidden keys to conceal payloads/commands used to maintain persistence. (Citation: TrendMicro POWELIKS AUG 2014) (Citation: SpectorOps Hiding Reg Jul 2017)\n\nThe Registry of a remote system may be modified to aid in execution of files as part of lateral movement. It requires the remote Registry service to be running on the target system. (Citation: Microsoft Remote) Often [Valid Accounts](https://attack.mitre.org/techniques/T1078) are required, along with access to the remote system's [SMB/Windows Admin Shares](https://attack.mitre.org/techniques/T1021/002) for RPC communication.", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "defense-evasion"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1112", "external_id": "T1112"}, {"source_name": "Microsoft Reg", "description": "Microsoft. (2012, April 17). Reg. Retrieved May 1, 2015.", "url": "https://technet.microsoft.com/en-us/library/cc732643.aspx"}, {"source_name": "Microsoft Remote", "description": "Microsoft. (n.d.). Enable the Remote Registry Service. Retrieved May 1, 2015.", "url": "https://technet.microsoft.com/en-us/library/cc754820.aspx"}, {"source_name": "Microsoft 4657 APR 2017", "description": "Miroshnikov, A. & Hall, J. (2017, April 18). 4657(S): A registry value was modified. Retrieved August 9, 2018.", "url": "https://docs.microsoft.com/windows/security/threat-protection/auditing/event-4657"}, {"source_name": "SpectorOps Hiding Reg Jul 2017", "description": "Reitz, B. (2017, July 14). Hiding Registry keys with PSReflect. Retrieved August 9, 2018.", "url": "https://posts.specterops.io/hiding-registry-keys-with-psreflect-b18ec5ac8353"}, {"source_name": "Microsoft Reghide NOV 2006", "description": "Russinovich, M. & Sharkey, K. (2006, January 10). Reghide. Retrieved August 9, 2018.", "url": "https://docs.microsoft.com/sysinternals/downloads/reghide"}, {"source_name": "Microsoft RegDelNull July 2016", "description": "Russinovich, M. & Sharkey, K. (2016, July 4). RegDelNull v1.11. Retrieved August 10, 2018.", "url": "https://docs.microsoft.com/en-us/sysinternals/downloads/regdelnull"}, {"source_name": "TrendMicro POWELIKS AUG 2014", "description": "Santos, R. (2014, August 1). POWELIKS: Malware Hides In Windows Registry. Retrieved August 9, 2018.", "url": "https://blog.trendmicro.com/trendlabs-security-intelligence/poweliks-malware-hides-in-windows-registry/"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Bartosz Jerzman", "Travis Smith, Tripwire", "David Lu, Tripwire"], "x_mitre_data_sources": ["Process: OS API Execution", "Process: Process Creation", "Windows Registry: Windows Registry Key Deletion", "Windows Registry: Windows Registry Key Modification", "Command: Command Execution", "Windows Registry: Windows Registry Key Creation"], "x_mitre_defense_bypassed": ["Host forensic analysis"], "x_mitre_deprecated": false, "x_mitre_detection": "Modifications to the Registry are normal and occur throughout typical use of the Windows operating system. Consider enabling Registry Auditing on specific keys to produce an alertable event (Event ID 4657) whenever a value is changed (though this may not trigger when values are created with Reghide or other evasive methods). (Citation: Microsoft 4657 APR 2017) Changes to Registry entries that load software on Windows startup that do not correlate with known software, patch cycles, etc., are suspicious, as are additions or changes to files within the startup folder. Changes could also include new services and modification of existing binary paths to point to malicious files. If a change to a service-related entry occurs, then it will likely be followed by a local or remote service start or restart to execute the file.\n\nMonitor processes and command-line arguments for actions that could be taken to change or delete information in the Registry. Remote access tools with built-in features may interact directly with the Windows API to gather information. The Registry may also be modified through Windows system management tools such as [Windows Management Instrumentation](https://attack.mitre.org/techniques/T1047) and [PowerShell](https://attack.mitre.org/techniques/T1059/001), which may require additional logging features to be configured in the operating system to collect necessary information for analysis.\n\nMonitor for processes, command-line arguments, and API calls associated with concealing Registry keys, such as Reghide. (Citation: Microsoft Reghide NOV 2006) Inspect and cleanup malicious hidden Registry entries using Native Windows API calls and/or tools such as Autoruns (Citation: SpectorOps Hiding Reg Jul 2017) and RegDelNull (Citation: Microsoft RegDelNull July 2016).", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": false, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["Windows"], "x_mitre_version": "1.3"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--6faf650d-bf31-4eb4-802d-1000cf38efaf", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2017-05-31T21:31:37.917Z", "modified": "2023-03-30T21:01:37.205Z", "name": "Video Capture", "description": "An adversary can leverage a computer's peripheral devices (e.g., integrated cameras or webcams) or applications (e.g., video call services) to capture video recordings for the purpose of gathering information. Images may also be captured from devices or applications, potentially in specified intervals, in lieu of video files.\n\nMalware or scripts may be used to interact with the devices through an available API provided by the operating system or an application to capture video or images. Video or image files may be written to disk and exfiltrated later. This technique differs from [Screen Capture](https://attack.mitre.org/techniques/T1113) due to use of specific devices or applications for video recording rather than capturing the victim's screen.\n\nIn macOS, there are a few different malware samples that record the user's webcam such as FruitFly and Proton. (Citation: objective-see 2017 review)", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "collection"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1125", "external_id": "T1125"}, {"source_name": "objective-see 2017 review", "description": "Patrick Wardle. (n.d.). Retrieved March 20, 2018.", "url": "https://objective-see.com/blog/blog_0x25.html"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Praetorian"], "x_mitre_data_sources": ["Command: Command Execution", "Process: OS API Execution"], "x_mitre_detection": "Detection of this technique may be difficult due to the various APIs that may be used. Telemetry data regarding API use may not be useful depending on how a system is normally used, but may provide context to other potentially malicious activity occurring on a system.\n\nBehavior that could indicate technique use include an unknown or unusual process accessing APIs associated with devices or software that interact with the video camera, recording devices, or recording software, and a process periodically writing files to disk that contain video or camera image data.", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": false, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_permissions_required": ["User"], "x_mitre_platforms": ["Windows", "macOS", "Linux"], "x_mitre_version": "1.1"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2020-03-02T18:45:07.892Z", "modified": "2023-04-14T17:42:15.871Z", "name": "Phishing", "description": "Adversaries may send phishing messages to gain access to victim systems. All forms of phishing are electronically delivered social engineering. Phishing can be targeted, known as spearphishing. In spearphishing, a specific individual, company, or industry will be targeted by the adversary. More generally, adversaries can conduct non-targeted phishing, such as in mass malware spam campaigns.\n\nAdversaries may send victims emails containing malicious attachments or links, typically to execute malicious code on victim systems. Phishing may also be conducted via third-party services, like social media platforms. Phishing may also involve social engineering techniques, such as posing as a trusted source, as well as evasive techniques such as removing or manipulating emails or metadata/headers from compromised accounts being abused to send messages (e.g., [Email Hiding Rules](https://attack.mitre.org/techniques/T1564/008)).(Citation: Microsoft OAuth Spam 2022)(Citation: Palo Alto Unit 42 VBA Infostealer 2014) Another way to accomplish this is by forging or spoofing(Citation: Proofpoint-spoof) the identity of the sender which can be used to fool both the human recipient as well as automated security tools.(Citation: cyberproof-double-bounce) \n\nVictims may also receive phishing messages that instruct them to call a phone number where they are directed to visit a malicious URL, download malware,(Citation: sygnia Luna Month)(Citation: CISA Remote Monitoring and Management Software) or install adversary-accessible remote management tools onto their computer (i.e., [User Execution](https://attack.mitre.org/techniques/T1204)).(Citation: Unit42 Luna Moth)", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "initial-access"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1566", "external_id": "T1566"}, {"source_name": "ACSC Email Spoofing", "description": "Australian Cyber Security Centre. (2012, December). Mitigating Spoofed Emails Using Sender Policy Framework. Retrieved October 19, 2020.", "url": "https://www.cyber.gov.au/sites/default/files/2019-03/spoof_email_sender_policy_framework.pdf"}, {"source_name": "CISA Remote Monitoring and Management Software", "description": "CISA. (n.d.). Protecting Against Malicious Use of Remote Monitoring and Management Software. Retrieved February 2, 2023.", "url": "https://www.cisa.gov/uscert/ncas/alerts/aa23-025a"}, {"source_name": "cyberproof-double-bounce", "description": "Itkin, Liora. (2022, September 1). Double-bounced attacks with email spoofing . Retrieved February 24, 2023.", "url": "https://blog.cyberproof.com/blog/double-bounced-attacks-with-email-spoofing-2022-trends"}, {"source_name": "Unit42 Luna Moth", "description": "Kristopher Russo. (n.d.). Luna Moth Callback Phishing Campaign. Retrieved February 2, 2023.", "url": "https://unit42.paloaltonetworks.com/luna-moth-callback-phishing/"}, {"source_name": "Microsoft Anti Spoofing", "description": "Microsoft. (2020, October 13). Anti-spoofing protection in EOP. Retrieved October 19, 2020.", "url": "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spoofing-protection?view=o365-worldwide"}, {"source_name": "Microsoft OAuth Spam 2022", "description": "Microsoft. (2023, September 22). Malicious OAuth applications abuse cloud email services to spread spam. Retrieved March 13, 2023.", "url": "https://www.microsoft.com/en-us/security/blog/2022/09/22/malicious-oauth-applications-used-to-compromise-email-servers-and-spread-spam/"}, {"source_name": "sygnia Luna Month", "description": "Oren Biderman, Tomer Lahiyani, Noam Lifshitz, Ori Porag. (n.d.). LUNA MOTH: THE THREAT ACTORS BEHIND RECENT FALSE SUBSCRIPTION SCAMS. Retrieved February 2, 2023.", "url": "https://blog.sygnia.co/luna-moth-false-subscription-scams"}, {"source_name": "Proofpoint-spoof", "description": "Proofpoint. (n.d.). What Is Email Spoofing?. Retrieved February 24, 2023.", "url": "https://www.proofpoint.com/us/threat-reference/email-spoofing"}, {"source_name": "Palo Alto Unit 42 VBA Infostealer 2014", "description": "Vicky Ray and Rob Downs. (2014, October 29). Examining a VBA-Initiated Infostealer Campaign. Retrieved March 13, 2023.", "url": "https://unit42.paloaltonetworks.com/examining-vba-initiated-infostealer-campaign/"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Philip Winther", "Ohad Zaidenberg, @ohad_mz", "Liora Itkin", "Liran Ravich, CardinalOps", "Scott Cook, Capital One"], "x_mitre_data_sources": ["Application Log: Application Log Content", "File: File Creation", "Network Traffic: Network Traffic Content", "Network Traffic: Network Traffic Flow"], "x_mitre_deprecated": false, "x_mitre_detection": "Network intrusion detection systems and email gateways can be used to detect phishing with malicious attachments in transit. Detonation chambers may also be used to identify malicious attachments. Solutions can be signature and behavior based, but adversaries may construct attachments in a way to avoid these systems.\n\nFiltering based on DKIM+SPF or header analysis can help detect when the email sender is spoofed.(Citation: Microsoft Anti Spoofing)(Citation: ACSC Email Spoofing)\n\nURL inspection within email (including expanding shortened links) can help detect links leading to known malicious sites. Detonation chambers can be used to detect these links and either automatically go to these sites to determine if they're potentially malicious, or wait and capture the content if a user visits the link.\n\nBecause most common third-party services used for phishing via service leverage TLS encryption, SSL/TLS inspection is generally required to detect the initial communication/delivery. With SSL/TLS inspection intrusion detection signatures or other security gateway appliances may be able to detect malware.\n\nAnti-virus can potentially detect malicious documents and files that are downloaded on the user's computer. Many possible detections of follow-on behavior may take place once [User Execution](https://attack.mitre.org/techniques/T1204) occurs.", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": false, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["Linux", "macOS", "Windows", "SaaS", "Office 365", "Google Workspace"], "x_mitre_version": "2.3"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--a36555cb-8add-43be-a33c-f962b0bfdbdb", "created": "2023-10-09T05:29:08.978905Z", "modified": "2023-10-09T05:29:08.978905Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--2b7379c8-7c83-4376-a362-f256fabd68d7", "created": "2023-10-09T05:29:08.979259Z", "modified": "2023-10-09T05:29:08.979259Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--74245dc1-1e4b-4b06-bf17-6216972008df", "created": "2023-10-09T05:29:08.9795Z", "modified": "2023-10-09T05:29:08.9795Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--c501cf08-3247-4c65-8598-22822e855423", "created": "2023-10-09T05:29:08.979751Z", "modified": "2023-10-09T05:29:08.979751Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--57340c81-c025-4189-8fa0-fc7ede51bae4"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--a1e8a44b-d902-4ddb-bc20-571e5b161086", "created": "2023-10-09T05:29:08.980034Z", "modified": "2023-10-09T05:29:08.980034Z", "relationship_type": "uses", "source_ref": "threat-actor--03c80674-35f8-4fe0-be2b-226ed0fcd69f", "target_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a"}]} \ No newline at end of file +{"type": "bundle", "id": "bundle--32cd1e04-c095-473b-baa8-11efda980da5", "objects": [{"type": "identity", "spec_version": "2.1", "id": "identity--477866fd-8784-46f9-ab40-5592ed4eddd7", "created": "2023-10-08T20:06:11.507598Z", "modified": "2023-10-08T20:06:11.507598Z", "name": "Feedly AI", "identity_class": "organization", "external_references": [{"source_name": "Feedly", "url": "https://feedly.com/i/landing/threatIntelligence"}]}, {"type": "report", "spec_version": "2.1", "id": "report--1c9014de-c4fd-5db7-b562-dd321a6f94e1", "created_by_ref": "identity--477866fd-8784-46f9-ab40-5592ed4eddd7", "created": "2023-10-09T05:29:08.986171+00:00", "modified": "2023-10-09T05:29:08.986171+00:00", "name": "Threat Actors Employ Remote Admin Tools to Gain Access over Corpora...", "description": "Recently, threat actors have adapted tactics, exploiting the appeal of banned apps in specific regions, making users more susceptible to cyberattacks through cleverly crafted campaigns.\n\n In a recent campaign, Chinese users were lured with a fake Telegram installer to illustrate this tactic.\n\n Cybersecurity researchers at CRIL (Cyble Research and Intelligence Labs) noted a campaign targeting Russian users, where threat actors created phishing sites mimicking restricted apps like-\n\n * ExpressVPN\n* WeChat\n* Skype\n\n FREE Demo [Deploy Advanced AI-Powered Email Security Solution](https://cybersecuritynews.com/threat-actors-employ-remote-admin-tools/#)\n------------------------------------------------------------------------------------------------------------------------------\n\n Implementing AI-Powered Email security solutions \u201cTrustifi\u201d can secure your business from today\u2019s most dangerous email threats, such as Email Tracking, Blocking, Modifying, Phishing, Account Take Over, Business Email Compromise, Malware & Ransomware\n\n Experts [identified](https://cyble.com/blog/rms-tools-sneaky-comeback-phishing-campaign-mirroring-banned-applications/) the following phishing domains delivering RMS, disguising as legitimate OS applications but distributing malware:-\n\n * express-vpn[.]fun\n* we-chat[.]info\n* join-skype[.]com\n\n **Threat Actors Employ Remote Admin Tools**\n-------------------------------------------\n\n The consistent use of the same RMS executable across these phishing sites strongly suggests a single or closely coordinated threat actor group was behind these attacks.\n\n The phishing sites distributed either a malicious Self-extracting archive (SFX) or an RMS binary. For instance, the ExpressVPN [phishing site](https://cybersecuritynews.com/sophisticated-phishing-campaigns/) in this campaign downloads an SFX archive that mimics a genuine installer but delivers malware upon execution.\n\n After execution, the SFX file modifies the \u2018HKCU\\Software\\WinRAR SFX\u2019 Registry key and creates a \u2018expressvpn\\_windows\\_12.58.0.4\\_release\u2019 folder in %temp% with specific files:-\n\n * **expressvpn.exe:** This file is an RMS executable.\n* **expressvpn\\_windows\\_12.58.0.4\\_release.exe:** This file is a clean ExpressVPN installer.\n\n ![SFX Archive](https://lh3.googleusercontent.com/HVMUAg3bQx5KiR5Y0-xStUaZYYjVzbDVGMbzEHhAph1cM3pqIZHjrpNlzvcrntRVhi9uZiUBCCAnBFq6skEjNFNgXZfrZEK7rLhRbrjAmay9KWj4tJKMu8TOLjesN8pzCRe3m_3Dn__Y1zDrYerzTds)SFX Archive (Source \u2013 Cyble) The SFX file quietly runs an RMS executable in the background while simultaneously using the ExpressVPN installation wizard as a decoy to divert and confuse users.\n\n ![Process Tree ](https://lh3.googleusercontent.com/SxlJyO42OJdeXBATgQk5eHRPcimuVWOBOrAFj60oL0ONat_K432fVqb-LcZg2i1lVFfyigA2er6y6eYu_skVCgV6Z797-2W8OEr5-rNt8RBJDItiGboWSWI8w-8qhLcpRjQLAdc22D5_4bqnzZjyCms)Process Tree (Source \u2013 Cyble) RMS, initially a legitimate tool, has been used in campaigns by TA505 and other threat actors. It\u2019s free for non-commercial use and supports remote administration across multiple platforms, offering features like remote control and file transfers.\n\n After execution, \u2018expressvpn.exe\u2019 creates a unique folder in %temp%, drops \u2018host.msi,\u2019 silently installs it via msiexec.exe, and places RMS files in \u2018C:\\Program Files (x86)\\Remote Manipulator System \u2013 Host\u2019.\n\n The RMS client configuration is hex-encoded in a [Registry Key](https://cybersecuritynews.com/malicious-npm-and-pypi-packages/) and includes data for functions like:-\u00a0\n\n * Data transmission\n* Email alerts\n* Remote access\n* Screen recording\n\n The configuration data is organized into distinct sections, and here below, we have mentioned those sections:-\n\n * rms\\_inet\\_id\\_notification\n* security\\_settings\n* general\\_settings\n* rms\\_internet\\_id\\_settings\n* certificte\\_settings\n* sreen\\_record\\_option\n* local\\_settings\n\n RMS includes \u2018Internet-ID\u2019 for connecting to developer servers, sending an email notification containing victim details and remote access credentials, making attacks more accessible for less sophisticated threat actors.\n\n The notification email, sent via SMTP to \u201c31.31.194.65\u201d (resolved as \u201cmail.hosting.reg.ru\u201d), initiates C&C communications over TCP to transmit victim data.\n\n ![Network Connections](https://lh6.googleusercontent.com/Yikt0caFAsnOQHjqchVxCmSs9Wp7TSuP3ihLgbqgJBKxiX2T_H17eV8morHu90Yxe-grQlhOikiH19UpahSLk85Bxo0kgwb-aBQcDO_sZVn-sUs8qxqlTywoZNoSHPbX_NoUOuo5AyMQKW3o7u5y51U)Network Connections (Source \u2013 Cyble) Victim data, in Base64-encoded XML, goes to IP addresses 77.223.124.212 and 95.213.205.83 via port 5655. It mirrors registry-stored configuration data, including country code, device name, OS details, and an admin privilege flag.\n\n **Recommendations**\n-------------------\n\n Here below we have mentioned all the recommendations:-\n\n * Enforce application whitelisting to limit unapproved app execution, including remote admin tools, on endpoints.\n* Regularly check your system\u2019s services list, especially for \u201cRManService.\u201d If unsure, consider disabling or removing it.\n* Use network traffic tools to monitor outbound traffic, especially on port 5655, and set alerts for unusual patterns that could signal C&C server communication.\n\n Protect yourself from vulnerabilities using Patch Manager Plus to patch over 850 third-party applications quickly. Take advantage of the\u00a0**[free\u00a0trial](https://www.manageengine.com/patch-management/?utm_source=GBHackers&utm_medium=Website-CPM&utm_campaign=PMP-300x600)**\u00a0to ensure 100% security.\n\n The post [Threat Actors Employ Remote Admin Tools to Gain Access over Corporate Networks](https://cybersecuritynews.com/threat-actors-employ-remote-admin-tools/) appeared first on [Cyber Security News](https://cybersecuritynews.com).", "published": "2023-10-08T22:29:04.093Z", "object_refs": ["indicator--f75e3179-a61c-59eb-8289-17f81bb3f798", "indicator--b481fd72-1711-57b3-8f34-6fd9c63c4f9c", "indicator--1b844713-a2f5-59d6-9e1c-c58eccbb35f3", "indicator--7c8def1d-5256-5d51-bc12-08f32061ee6b", "indicator--90adec07-e9c8-5e3b-b68f-22e6405ab54f", "indicator--3bd554ee-d87d-5c43-9e05-22fc467c253c", "malware--94339b04-9332-4691-b820-5021368f1d3a", "threat-actor--03c80674-35f8-4fe0-be2b-226ed0fcd69f", "attack-pattern--04fd5427-79c7-44ea-ae13-11b24778ff1c", "attack-pattern--2e34237d-8574-43f6-aace-ae2915de8597", "attack-pattern--57340c81-c025-4189-8fa0-fc7ede51bae4", "attack-pattern--6faf650d-bf31-4eb4-802d-1000cf38efaf", "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b", "relationship--a36555cb-8add-43be-a33c-f962b0bfdbdb", "relationship--2b7379c8-7c83-4376-a362-f256fabd68d7", "relationship--74245dc1-1e4b-4b06-bf17-6216972008df", "relationship--c501cf08-3247-4c65-8598-22822e855423", "relationship--a1e8a44b-d902-4ddb-bc20-571e5b161086"], "labels": ["Feedly AI", "Domains", "IPs", "TTPs"], "external_references": [{"source_name": "Feedly article", "url": "https://feedly.com/i/entry/TUUqTqS5PmAnvMYxpxsJW4lVFUYs0KVkqWEL+fdotps=_18b12e9095d:b749c:e11a9d8"}, {"source_name": "Cyber Security News", "url": "https://cybersecuritynews.com/threat-actors-employ-remote-admin-tools/"}], "object_marking_refs": ["marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"]}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--f75e3179-a61c-59eb-8289-17f81bb3f798", "created": "2023-10-09T05:29:08.914199Z", "modified": "2023-10-09T05:29:08.914199Z", "name": "Domain", "pattern": "[domain-name:value = 'express-vpn.fun']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.914199Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--b481fd72-1711-57b3-8f34-6fd9c63c4f9c", "created": "2023-10-09T05:29:08.967244Z", "modified": "2023-10-09T05:29:08.967244Z", "name": "Domain", "pattern": "[domain-name:value = 'join-skype.com']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.967244Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--1b844713-a2f5-59d6-9e1c-c58eccbb35f3", "created": "2023-10-09T05:29:08.969479Z", "modified": "2023-10-09T05:29:08.969479Z", "name": "Domain", "pattern": "[domain-name:value = 'we-chat.info']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.969479Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--7c8def1d-5256-5d51-bc12-08f32061ee6b", "created": "2023-10-09T05:29:08.972597Z", "modified": "2023-10-09T05:29:08.972597Z", "name": "IPv4", "pattern": "[ipv4-addr:value = '95.213.205.83']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.972597Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--90adec07-e9c8-5e3b-b68f-22e6405ab54f", "created": "2023-10-09T05:29:08.975362Z", "modified": "2023-10-09T05:29:08.975362Z", "name": "IPv4", "pattern": "[ipv4-addr:value = '31.31.194.65']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.975362Z"}, {"type": "indicator", "spec_version": "2.1", "id": "indicator--3bd554ee-d87d-5c43-9e05-22fc467c253c", "created": "2023-10-09T05:29:08.977076Z", "modified": "2023-10-09T05:29:08.977076Z", "name": "IPv4", "pattern": "[ipv4-addr:value = '77.223.124.212']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2023-10-09T05:29:08.977076Z"}, {"type": "malware", "spec_version": "2.1", "id": "malware--94339b04-9332-4691-b820-5021368f1d3a", "created": "2023-10-08T19:16:53.819646Z", "modified": "2023-10-08T19:16:53.819646Z", "name": "RMS", "description": "CyberInt states that Remote Manipulator System (RMS) is a legitimate tool developed by Russian organization TektonIT and has been observed in campaigns conducted by TA505 as well as numerous smaller campaigns likely attributable to other, disparate, threat actors. In addition to the availability of commercial licenses, the tool is free for non-commercial use and supports the remote administration of both Microsoft Windows and Android devices.", "is_family": true, "aliases": ["Gussdoor", "RemoteManipulatorSystem", "RuRAT", "Remote Manipulator System"], "external_references": [{"source_name": "Source", "url": "https://awakesecurity.com/blog/catching-the-white-stork-in-flight/"}, {"source_name": "Source", "url": "https://blog.malwarebytes.com/threat-analysis/2017/09/cve-2017-0199-used-to-deliver-modified-rms-agent-rat/"}, {"source_name": "Source", "url": "https://blog.yoroi.company/research/ta505-is-expanding-its-operations/"}, {"source_name": "Source", "url": "https://e.cyberint.com/hubfs/Report%20Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors%20Tools/CyberInt_Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors'%20Tools_Report.pdf"}, {"source_name": "Source", "url": "https://ics-cert.kaspersky.com/media/Kaspersky-Attacks-on-industrial-enterprises-using-RMS-and-TeamViewer-EN.pdf"}, {"source_name": "Source", "url": "https://ssu.gov.ua/uploads/files/DKIB/Technical%20report%20Armagedon.pdf"}, {"source_name": "Source", "url": "https://unit42.paloaltonetworks.com/unit-42-title-gamaredon-group-toolset-evolution"}, {"source_name": "Source", "url": "https://web.archive.org/web/20161223002016/https://www.symantec.com/connect/blogs/odinaff-new-trojan-used-high-level-financial-attacks"}]}, {"type": "threat-actor", "spec_version": "2.1", "id": "threat-actor--03c80674-35f8-4fe0-be2b-226ed0fcd69f", "created": "2023-10-08T19:16:55.704495Z", "modified": "2023-10-08T19:16:55.704495Z", "name": "TA505", "description": "TA505, the name given by Proofpoint, has been in the cybercrime business for at least four years. This is the group behind the infamous Dridex banking trojan and Locky ransomware, delivered through malicious email campaigns via Necurs botnet. Other malware associated with TA505 include Philadelphia and GlobeImposter ransomware families.", "aliases": ["TA 505", "GRACEFUL SPIDER", "Hive0065", "G0092", "GracefulSpider", "SectorJ04 Group", "GoldTahoe", "SectorJ04", "GOLD TAHOE", "CHIMBORAZO", "Dudear", "ATK103", "ATK 103"], "external_references": [{"source_name": "Source", "url": "https://www.bleepingcomputer.com/news/security/ta505-group-adopts-new-servhelper-backdoor-and-flawedgrace-rat/"}, {"source_name": "Source", "url": "https://www.proofpoint.com/sites/default/files/ta505_timeline_final4_0.png"}, {"source_name": "Source", "url": "https://www.proofpoint.com/us/threat-insight/post/threat-actor-profile-ta505-dridex-globeimposter"}, {"source_name": "Source", "url": "https://www.cybereason.com/blog/threat-actor-ta505-targets-financial-enterprises-using-lolbins-and-a-new-backdoor-malware"}, {"source_name": "Source", "url": "https://e.cyberint.com/hubfs/Report%20Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors%20Tools/CyberInt_Legit%20Remote%20Access%20Tools%20Turn%20Into%20Threat%20Actors'%20Tools_Report.pdf"}, {"source_name": "Source", "url": "https://threatpost.com/ta505-servhelper-malware/140792/"}, {"source_name": "Source", "url": "https://blog.yoroi.company/research/the-stealthy-email-stealer-in-the-ta505-arsenal/"}, {"source_name": "Source", "url": "https://threatrecon.nshc.net/2019/08/29/sectorj04-groups-increased-activity-in-2019/"}, {"source_name": "Source", "url": "https://www.proofpoint.com/us/threat-insight/post/ta505-distributes-new-sdbbot-remote-access-trojan-get2-downloader"}, {"source_name": "Source", "url": "https://www.blueliv.com/cyber-security-and-cyber-threat-intelligence-blog-blueliv/research/servhelper-evolution-and-new-ta505-campaigns/"}, {"source_name": "Source", "url": "https://www.telekom.com/en/blog/group/article/cybersecurity-ta505-s-box-of-chocolate-597672"}, {"source_name": "Source", "url": "https://www.telekom.com/en/blog/group/article/cybersecurity-ta505-returns-with-a-new-bag-of-tricks-602104"}, {"source_name": "Source", "url": "https://www.secureworks.com/research/threat-profiles/gold-tahoe"}, {"source_name": "Source", "url": "https://www.telekom.com/en/blog/group/article/eager-beaver-a-short-overview-of-the-restless-threat-actor-ta505-609546"}, {"source_name": "Source", "url": "https://blog.fox-it.com/2020/11/16/ta505-a-brief-history-of-their-time/"}, {"source_name": "Source", "url": "https://www.secureworks.com/blog/how-cyber-adversaries-are-adapting-to-exploit-the-global-pandemic"}, {"source_name": "Source", "url": "https://cyberthreat.thalesgroup.com/attackers/ATK103"}, {"source_name": "Source", "url": "https://securityintelligence.com/posts/ta505-continues-to-infect-networks-with-sdbbot-rat/"}, {"source_name": "Source", "url": "https://www.tenable.com/blog/cve-2020-1472-advanced-persistent-threat-actors-use-zerologon-vulnerability-in-exploit-chain"}]}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--04fd5427-79c7-44ea-ae13-11b24778ff1c", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2020-03-14T23:36:52.095Z", "modified": "2023-03-03T00:31:33.071Z", "name": "Standard Encoding", "description": "Adversaries may encode data with a standard data encoding system to make the content of command and control traffic more difficult to detect. Command and control (C2) information can be encoded using a standard data encoding system that adheres to existing protocol specifications. Common data encoding schemes include ASCII, Unicode, hexadecimal, Base64, and MIME.(Citation: Wikipedia Binary-to-text Encoding)(Citation: Wikipedia Character Encoding) Some data encoding systems may also result in data compression, such as gzip.", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "command-and-control"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1132/001", "external_id": "T1132.001"}, {"source_name": "University of Birmingham C2", "description": "Gardiner, J., Cova, M., Nagaraja, S. (2014, February). Command & Control Understanding, Denying and Detecting. Retrieved April 20, 2016.", "url": "https://arxiv.org/ftp/arxiv/papers/1408/1408.1136.pdf"}, {"source_name": "Wikipedia Binary-to-text Encoding", "description": "Wikipedia. (2016, December 26). Binary-to-text encoding. Retrieved March 1, 2017.", "url": "https://en.wikipedia.org/wiki/Binary-to-text_encoding"}, {"source_name": "Wikipedia Character Encoding", "description": "Wikipedia. (2017, February 19). Character Encoding. Retrieved March 1, 2017.", "url": "https://en.wikipedia.org/wiki/Character_encoding"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_data_sources": ["Network Traffic: Network Traffic Content"], "x_mitre_deprecated": false, "x_mitre_detection": "Analyze network data for uncommon data flows (e.g., a client sending significantly more data than it receives from a server). Processes utilizing the network that do not normally have network communication or have never been seen before are suspicious. Analyze packet contents to detect communications that do not follow the expected protocol behavior for the port that is being used.(Citation: University of Birmingham C2)", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": true, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["Linux", "macOS", "Windows"], "x_mitre_version": "1.0"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--2e34237d-8574-43f6-aace-ae2915de8597", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2020-03-02T19:05:18.137Z", "modified": "2023-03-30T21:01:42.995Z", "name": "Spearphishing Attachment", "description": "Adversaries may send spearphishing emails with a malicious attachment in an attempt to gain access to victim systems. Spearphishing attachment is a specific variant of spearphishing. Spearphishing attachment is different from other forms of spearphishing in that it employs the use of malware attached to an email. All forms of spearphishing are electronically delivered social engineering targeted at a specific individual, company, or industry. In this scenario, adversaries attach a file to the spearphishing email and usually rely upon [User Execution](https://attack.mitre.org/techniques/T1204) to gain execution. Spearphishing may also involve social engineering techniques, such as posing as a trusted source.\n\nThere are many options for the attachment such as Microsoft Office documents, executables, PDFs, or archived files. Upon opening the attachment (and potentially clicking past protections), the adversary's payload exploits a vulnerability or directly executes on the user's system. The text of the spearphishing email usually tries to give a plausible reason why the file should be opened, and may explain how to bypass system protections in order to do so. The email may also contain instructions on how to decrypt an attachment, such as a zip file password, in order to evade email boundary defenses. Adversaries frequently manipulate file extensions and icons in order to make attached executables appear to be document files, or files exploiting one application appear to be a file for a different one. ", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "initial-access"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1566/001", "external_id": "T1566.001"}, {"source_name": "Microsoft Anti Spoofing", "description": "Microsoft. (2020, October 13). Anti-spoofing protection in EOP. Retrieved October 19, 2020.", "url": "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spoofing-protection?view=o365-worldwide"}, {"source_name": "ACSC Email Spoofing", "description": "Australian Cyber Security Centre. (2012, December). Mitigating Spoofed Emails Using Sender Policy Framework. Retrieved October 19, 2020.", "url": "https://www.cyber.gov.au/sites/default/files/2019-03/spoof_email_sender_policy_framework.pdf"}, {"source_name": "Elastic - Koadiac Detection with EQL", "description": "Stepanic, D.. (2020, January 13). Embracing offensive tooling: Building detections against Koadic using EQL. Retrieved November 30, 2020.", "url": "https://www.elastic.co/blog/embracing-offensive-tooling-building-detections-against-koadic-using-eql"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Philip Winther"], "x_mitre_data_sources": ["Network Traffic: Network Traffic Flow", "Application Log: Application Log Content", "File: File Creation", "Network Traffic: Network Traffic Content"], "x_mitre_detection": "Network intrusion detection systems and email gateways can be used to detect spearphishing with malicious attachments in transit. Detonation chambers may also be used to identify malicious attachments. Solutions can be signature and behavior based, but adversaries may construct attachments in a way to avoid these systems.\n\nFiltering based on DKIM+SPF or header analysis can help detect when the email sender is spoofed.(Citation: Microsoft Anti Spoofing)(Citation: ACSC Email Spoofing)\n\nAnti-virus can potentially detect malicious documents and attachments as they're scanned to be stored on the email server or on the user's computer. Endpoint sensing or network sensing can potentially detect malicious events once the attachment is opened (such as a Microsoft Word document or PDF reaching out to the internet or spawning Powershell.exe) for techniques such as [Exploitation for Client Execution](https://attack.mitre.org/techniques/T1203) or usage of malicious scripts.\n\nMonitor for suspicious descendant process spawning from Microsoft Office and other productivity software.(Citation: Elastic - Koadiac Detection with EQL)", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": true, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["macOS", "Windows", "Linux"], "x_mitre_version": "2.2"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--57340c81-c025-4189-8fa0-fc7ede51bae4", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2017-05-31T21:31:23.587Z", "modified": "2023-04-21T12:19:38.962Z", "name": "Modify Registry", "description": "Adversaries may interact with the Windows Registry to hide configuration information within Registry keys, remove information as part of cleaning up, or as part of other techniques to aid in persistence and execution.\n\nAccess to specific areas of the Registry depends on account permissions, some requiring administrator-level access. The built-in Windows command-line utility [Reg](https://attack.mitre.org/software/S0075) may be used for local or remote Registry modification. (Citation: Microsoft Reg) Other tools may also be used, such as a remote access tool, which may contain functionality to interact with the Registry through the Windows API.\n\nRegistry modifications may also include actions to hide keys, such as prepending key names with a null character, which will cause an error and/or be ignored when read via [Reg](https://attack.mitre.org/software/S0075) or other utilities using the Win32 API. (Citation: Microsoft Reghide NOV 2006) Adversaries may abuse these pseudo-hidden keys to conceal payloads/commands used to maintain persistence. (Citation: TrendMicro POWELIKS AUG 2014) (Citation: SpectorOps Hiding Reg Jul 2017)\n\nThe Registry of a remote system may be modified to aid in execution of files as part of lateral movement. It requires the remote Registry service to be running on the target system. (Citation: Microsoft Remote) Often [Valid Accounts](https://attack.mitre.org/techniques/T1078) are required, along with access to the remote system's [SMB/Windows Admin Shares](https://attack.mitre.org/techniques/T1021/002) for RPC communication.", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "defense-evasion"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1112", "external_id": "T1112"}, {"source_name": "Microsoft Reg", "description": "Microsoft. (2012, April 17). Reg. Retrieved May 1, 2015.", "url": "https://technet.microsoft.com/en-us/library/cc732643.aspx"}, {"source_name": "Microsoft Remote", "description": "Microsoft. (n.d.). Enable the Remote Registry Service. Retrieved May 1, 2015.", "url": "https://technet.microsoft.com/en-us/library/cc754820.aspx"}, {"source_name": "Microsoft 4657 APR 2017", "description": "Miroshnikov, A. & Hall, J. (2017, April 18). 4657(S): A registry value was modified. Retrieved August 9, 2018.", "url": "https://docs.microsoft.com/windows/security/threat-protection/auditing/event-4657"}, {"source_name": "SpectorOps Hiding Reg Jul 2017", "description": "Reitz, B. (2017, July 14). Hiding Registry keys with PSReflect. Retrieved August 9, 2018.", "url": "https://posts.specterops.io/hiding-registry-keys-with-psreflect-b18ec5ac8353"}, {"source_name": "Microsoft Reghide NOV 2006", "description": "Russinovich, M. & Sharkey, K. (2006, January 10). Reghide. Retrieved August 9, 2018.", "url": "https://docs.microsoft.com/sysinternals/downloads/reghide"}, {"source_name": "Microsoft RegDelNull July 2016", "description": "Russinovich, M. & Sharkey, K. (2016, July 4). RegDelNull v1.11. Retrieved August 10, 2018.", "url": "https://docs.microsoft.com/en-us/sysinternals/downloads/regdelnull"}, {"source_name": "TrendMicro POWELIKS AUG 2014", "description": "Santos, R. (2014, August 1). POWELIKS: Malware Hides In Windows Registry. Retrieved August 9, 2018.", "url": "https://blog.trendmicro.com/trendlabs-security-intelligence/poweliks-malware-hides-in-windows-registry/"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Bartosz Jerzman", "Travis Smith, Tripwire", "David Lu, Tripwire"], "x_mitre_data_sources": ["Process: OS API Execution", "Process: Process Creation", "Windows Registry: Windows Registry Key Deletion", "Windows Registry: Windows Registry Key Modification", "Command: Command Execution", "Windows Registry: Windows Registry Key Creation"], "x_mitre_defense_bypassed": ["Host forensic analysis"], "x_mitre_deprecated": false, "x_mitre_detection": "Modifications to the Registry are normal and occur throughout typical use of the Windows operating system. Consider enabling Registry Auditing on specific keys to produce an alertable event (Event ID 4657) whenever a value is changed (though this may not trigger when values are created with Reghide or other evasive methods). (Citation: Microsoft 4657 APR 2017) Changes to Registry entries that load software on Windows startup that do not correlate with known software, patch cycles, etc., are suspicious, as are additions or changes to files within the startup folder. Changes could also include new services and modification of existing binary paths to point to malicious files. If a change to a service-related entry occurs, then it will likely be followed by a local or remote service start or restart to execute the file.\n\nMonitor processes and command-line arguments for actions that could be taken to change or delete information in the Registry. Remote access tools with built-in features may interact directly with the Windows API to gather information. The Registry may also be modified through Windows system management tools such as [Windows Management Instrumentation](https://attack.mitre.org/techniques/T1047) and [PowerShell](https://attack.mitre.org/techniques/T1059/001), which may require additional logging features to be configured in the operating system to collect necessary information for analysis.\n\nMonitor for processes, command-line arguments, and API calls associated with concealing Registry keys, such as Reghide. (Citation: Microsoft Reghide NOV 2006) Inspect and cleanup malicious hidden Registry entries using Native Windows API calls and/or tools such as Autoruns (Citation: SpectorOps Hiding Reg Jul 2017) and RegDelNull (Citation: Microsoft RegDelNull July 2016).", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": false, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["Windows"], "x_mitre_version": "1.3"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--6faf650d-bf31-4eb4-802d-1000cf38efaf", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2017-05-31T21:31:37.917Z", "modified": "2023-03-30T21:01:37.205Z", "name": "Video Capture", "description": "An adversary can leverage a computer's peripheral devices (e.g., integrated cameras or webcams) or applications (e.g., video call services) to capture video recordings for the purpose of gathering information. Images may also be captured from devices or applications, potentially in specified intervals, in lieu of video files.\n\nMalware or scripts may be used to interact with the devices through an available API provided by the operating system or an application to capture video or images. Video or image files may be written to disk and exfiltrated later. This technique differs from [Screen Capture](https://attack.mitre.org/techniques/T1113) due to use of specific devices or applications for video recording rather than capturing the victim's screen.\n\nIn macOS, there are a few different malware samples that record the user's webcam such as FruitFly and Proton. (Citation: objective-see 2017 review)", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "collection"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1125", "external_id": "T1125"}, {"source_name": "objective-see 2017 review", "description": "Patrick Wardle. (n.d.). Retrieved March 20, 2018.", "url": "https://objective-see.com/blog/blog_0x25.html"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Praetorian"], "x_mitre_data_sources": ["Command: Command Execution", "Process: OS API Execution"], "x_mitre_detection": "Detection of this technique may be difficult due to the various APIs that may be used. Telemetry data regarding API use may not be useful depending on how a system is normally used, but may provide context to other potentially malicious activity occurring on a system.\n\nBehavior that could indicate technique use include an unknown or unusual process accessing APIs associated with devices or software that interact with the video camera, recording devices, or recording software, and a process periodically writing files to disk that contain video or camera image data.", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": false, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_permissions_required": ["User"], "x_mitre_platforms": ["Windows", "macOS", "Linux"], "x_mitre_version": "1.1"}, {"type": "attack-pattern", "spec_version": "2.1", "id": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "created": "2020-03-02T18:45:07.892Z", "modified": "2023-04-14T17:42:15.871Z", "name": "Phishing", "description": "Adversaries may send phishing messages to gain access to victim systems. All forms of phishing are electronically delivered social engineering. Phishing can be targeted, known as spearphishing. In spearphishing, a specific individual, company, or industry will be targeted by the adversary. More generally, adversaries can conduct non-targeted phishing, such as in mass malware spam campaigns.\n\nAdversaries may send victims emails containing malicious attachments or links, typically to execute malicious code on victim systems. Phishing may also be conducted via third-party services, like social media platforms. Phishing may also involve social engineering techniques, such as posing as a trusted source, as well as evasive techniques such as removing or manipulating emails or metadata/headers from compromised accounts being abused to send messages (e.g., [Email Hiding Rules](https://attack.mitre.org/techniques/T1564/008)).(Citation: Microsoft OAuth Spam 2022)(Citation: Palo Alto Unit 42 VBA Infostealer 2014) Another way to accomplish this is by forging or spoofing(Citation: Proofpoint-spoof) the identity of the sender which can be used to fool both the human recipient as well as automated security tools.(Citation: cyberproof-double-bounce) \n\nVictims may also receive phishing messages that instruct them to call a phone number where they are directed to visit a malicious URL, download malware,(Citation: sygnia Luna Month)(Citation: CISA Remote Monitoring and Management Software) or install adversary-accessible remote management tools onto their computer (i.e., [User Execution](https://attack.mitre.org/techniques/T1204)).(Citation: Unit42 Luna Moth)", "kill_chain_phases": [{"kill_chain_name": "mitre-attack", "phase_name": "initial-access"}], "external_references": [{"source_name": "mitre-attack", "url": "https://attack.mitre.org/techniques/T1566", "external_id": "T1566"}, {"source_name": "ACSC Email Spoofing", "description": "Australian Cyber Security Centre. (2012, December). Mitigating Spoofed Emails Using Sender Policy Framework. Retrieved October 19, 2020.", "url": "https://www.cyber.gov.au/sites/default/files/2019-03/spoof_email_sender_policy_framework.pdf"}, {"source_name": "CISA Remote Monitoring and Management Software", "description": "CISA. (n.d.). Protecting Against Malicious Use of Remote Monitoring and Management Software. Retrieved February 2, 2023.", "url": "https://www.cisa.gov/uscert/ncas/alerts/aa23-025a"}, {"source_name": "cyberproof-double-bounce", "description": "Itkin, Liora. (2022, September 1). Double-bounced attacks with email spoofing . Retrieved February 24, 2023.", "url": "https://blog.cyberproof.com/blog/double-bounced-attacks-with-email-spoofing-2022-trends"}, {"source_name": "Unit42 Luna Moth", "description": "Kristopher Russo. (n.d.). Luna Moth Callback Phishing Campaign. Retrieved February 2, 2023.", "url": "https://unit42.paloaltonetworks.com/luna-moth-callback-phishing/"}, {"source_name": "Microsoft Anti Spoofing", "description": "Microsoft. (2020, October 13). Anti-spoofing protection in EOP. Retrieved October 19, 2020.", "url": "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/anti-spoofing-protection?view=o365-worldwide"}, {"source_name": "Microsoft OAuth Spam 2022", "description": "Microsoft. (2023, September 22). Malicious OAuth applications abuse cloud email services to spread spam. Retrieved March 13, 2023.", "url": "https://www.microsoft.com/en-us/security/blog/2022/09/22/malicious-oauth-applications-used-to-compromise-email-servers-and-spread-spam/"}, {"source_name": "sygnia Luna Month", "description": "Oren Biderman, Tomer Lahiyani, Noam Lifshitz, Ori Porag. (n.d.). LUNA MOTH: THE THREAT ACTORS BEHIND RECENT FALSE SUBSCRIPTION SCAMS. Retrieved February 2, 2023.", "url": "https://blog.sygnia.co/luna-moth-false-subscription-scams"}, {"source_name": "Proofpoint-spoof", "description": "Proofpoint. (n.d.). What Is Email Spoofing?. Retrieved February 24, 2023.", "url": "https://www.proofpoint.com/us/threat-reference/email-spoofing"}, {"source_name": "Palo Alto Unit 42 VBA Infostealer 2014", "description": "Vicky Ray and Rob Downs. (2014, October 29). Examining a VBA-Initiated Infostealer Campaign. Retrieved March 13, 2023.", "url": "https://unit42.paloaltonetworks.com/examining-vba-initiated-infostealer-campaign/"}], "object_marking_refs": ["marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168"], "x_mitre_attack_spec_version": "3.1.0", "x_mitre_contributors": ["Philip Winther", "Ohad Zaidenberg, @ohad_mz", "Liora Itkin", "Liran Ravich, CardinalOps", "Scott Cook, Capital One"], "x_mitre_data_sources": ["Application Log: Application Log Content", "File: File Creation", "Network Traffic: Network Traffic Content", "Network Traffic: Network Traffic Flow"], "x_mitre_deprecated": false, "x_mitre_detection": "Network intrusion detection systems and email gateways can be used to detect phishing with malicious attachments in transit. Detonation chambers may also be used to identify malicious attachments. Solutions can be signature and behavior based, but adversaries may construct attachments in a way to avoid these systems.\n\nFiltering based on DKIM+SPF or header analysis can help detect when the email sender is spoofed.(Citation: Microsoft Anti Spoofing)(Citation: ACSC Email Spoofing)\n\nURL inspection within email (including expanding shortened links) can help detect links leading to known malicious sites. Detonation chambers can be used to detect these links and either automatically go to these sites to determine if they're potentially malicious, or wait and capture the content if a user visits the link.\n\nBecause most common third-party services used for phishing via service leverage TLS encryption, SSL/TLS inspection is generally required to detect the initial communication/delivery. With SSL/TLS inspection intrusion detection signatures or other security gateway appliances may be able to detect malware.\n\nAnti-virus can potentially detect malicious documents and files that are downloaded on the user's computer. Many possible detections of follow-on behavior may take place once [User Execution](https://attack.mitre.org/techniques/T1204) occurs.", "x_mitre_domains": ["enterprise-attack"], "x_mitre_is_subtechnique": false, "x_mitre_modified_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "x_mitre_platforms": ["Linux", "macOS", "Windows", "SaaS", "Office 365", "Google Workspace"], "x_mitre_version": "2.3"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--a36555cb-8add-43be-a33c-f962b0bfdbdb", "created": "2023-10-09T05:29:08.978905Z", "modified": "2023-10-09T05:29:08.978905Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--2b7379c8-7c83-4376-a362-f256fabd68d7", "created": "2023-10-09T05:29:08.979259Z", "modified": "2023-10-09T05:29:08.979259Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--74245dc1-1e4b-4b06-bf17-6216972008df", "created": "2023-10-09T05:29:08.9795Z", "modified": "2023-10-09T05:29:08.9795Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--a62a8db3-f23a-4d8f-afd6-9dbc77e7813b"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--c501cf08-3247-4c65-8598-22822e855423", "created": "2023-10-09T05:29:08.979751Z", "modified": "2023-10-09T05:29:08.979751Z", "relationship_type": "uses", "source_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a", "target_ref": "attack-pattern--57340c81-c025-4189-8fa0-fc7ede51bae4"}, {"type": "relationship", "spec_version": "2.1", "id": "relationship--a1e8a44b-d902-4ddb-bc20-571e5b161086", "created": "2023-10-09T05:29:08.980034Z", "modified": "2023-10-09T05:29:08.980034Z", "relationship_type": "uses", "source_ref": "threat-actor--03c80674-35f8-4fe0-be2b-226ed0fcd69f", "target_ref": "malware--94339b04-9332-4691-b820-5021368f1d3a"}]} \ No newline at end of file From 2ca569ad62bcd923733e5a247ac852ac5d1562e1 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 24 Dec 2024 12:33:18 +0100 Subject: [PATCH 18/27] [feedly] Add separate pack for articles as incidents --- .../IncidentFields/incident_customfields.json | 248 ------------------ Packs/FeedFeedly/README.md | 2 + Packs/FeedlyArticles/.secrets-ignore | 2 + .../Author_image.png} | Bin .../classifier-Feedly_-_Report_Mapper.json | 0 .../incident_feedlycrawleddate.json | 61 +++++ .../incident_feedlymalwarenames.json | 61 +++++ .../incident_feedlythreatactornames.json | 61 +++++ .../IncidentFields/incident_feedlyurl.json | 61 +++++ .../IncidentTypes/customIncidentTypes.json | 0 .../IncidentsFeedly/IncidentsFeedly.py | 0 .../IncidentsFeedly/IncidentsFeedly.yml | 0 .../IncidentsFeedly_description.md | 0 .../IncidentsFeedly/IncidentsFeedly_image.png | Bin 0 -> 6623 bytes .../Integrations/IncidentsFeedly/README.md | 0 .../layoutscontainer-Feedly_Report.json | 0 .../Playbooks/Feedly_threats.yml | 0 Packs/FeedlyArticles/README.md | 5 + Packs/FeedlyArticles/pack_metadata.json | 23 ++ 19 files changed, 276 insertions(+), 248 deletions(-) delete mode 100644 Packs/FeedFeedly/IncidentFields/incident_customfields.json create mode 100644 Packs/FeedlyArticles/.secrets-ignore rename Packs/{FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_image.png => FeedlyArticles/Author_image.png} (100%) rename Packs/{FeedFeedly => FeedlyArticles}/Classifiers/classifier-Feedly_-_Report_Mapper.json (100%) create mode 100644 Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json create mode 100644 Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json create mode 100644 Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json create mode 100644 Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json rename Packs/{FeedFeedly => FeedlyArticles}/IncidentTypes/customIncidentTypes.json (100%) rename Packs/{FeedFeedly => FeedlyArticles}/Integrations/IncidentsFeedly/IncidentsFeedly.py (100%) rename Packs/{FeedFeedly => FeedlyArticles}/Integrations/IncidentsFeedly/IncidentsFeedly.yml (100%) rename Packs/{FeedFeedly => FeedlyArticles}/Integrations/IncidentsFeedly/IncidentsFeedly_description.md (100%) create mode 100644 Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_image.png rename Packs/{FeedFeedly => FeedlyArticles}/Integrations/IncidentsFeedly/README.md (100%) rename Packs/{FeedFeedly => FeedlyArticles}/Layouts/layoutscontainer-Feedly_Report.json (100%) rename Packs/{FeedFeedly => FeedlyArticles}/Playbooks/Feedly_threats.yml (100%) create mode 100644 Packs/FeedlyArticles/README.md create mode 100644 Packs/FeedlyArticles/pack_metadata.json diff --git a/Packs/FeedFeedly/IncidentFields/incident_customfields.json b/Packs/FeedFeedly/IncidentFields/incident_customfields.json deleted file mode 100644 index 7350529c5742..000000000000 --- a/Packs/FeedFeedly/IncidentFields/incident_customfields.json +++ /dev/null @@ -1,248 +0,0 @@ -{ - "incidentFields": [ - { - "id": "incident_feedlycrawleddate", - "version": 1, - "cacheVersn": 0, - "modified": "2024-10-10T12:19:12.752862283Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, - "name": "Feedly crawled date", - "prevName": "Feedly crawled date", - "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", - "cliName": "feedlycrawleddate", - "type": "shortText", - "orgType": "shortText", - "closeForm": false, - "editForm": true, - "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", - "neverSetAsRequired": false, - "isReadOnly": false, - "selectValues": null, - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", - "useAsKpi": false, - "locked": false, - "system": false, - "content": false, - "group": 0, - "mergeStrategy": "", - "hidden": false, - "openEnded": false, - "associatedTypes": null, - "systemAssociatedTypes": null, - "associatedToAll": true, - "unmapped": false, - "unsearchable": false, - "caseInsensitive": true, - "columns": null, - "defaultRows": null, - "sla": 0, - "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" - }, - { - "id": "incident_feedlymalwarenames", - "version": 1, - "cacheVersn": 0, - "modified": "2024-11-13T14:27:30.49621132Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, - "name": "Feedly Malware Names", - "prevName": "Feedly Malware Names", - "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", - "cliName": "feedlymalwarenames", - "type": "multiSelect", - "orgType": "multiSelect", - "closeForm": false, - "editForm": true, - "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", - "neverSetAsRequired": false, - "isReadOnly": false, - "selectValues": [], - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", - "useAsKpi": false, - "locked": false, - "system": false, - "content": false, - "group": 0, - "mergeStrategy": "", - "hidden": false, - "openEnded": true, - "associatedTypes": null, - "systemAssociatedTypes": null, - "associatedToAll": true, - "unmapped": false, - "unsearchable": false, - "caseInsensitive": true, - "columns": null, - "defaultRows": null, - "sla": 0, - "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" - }, - { - "id": "incident_feedlythreatactornames", - "version": 1, - "cacheVersn": 0, - "modified": "2024-11-13T14:29:40.202843194Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, - "name": "Feedly Threat Actor Names", - "prevName": "Feedly Threat Actor Names", - "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", - "cliName": "feedlythreatactornames", - "type": "multiSelect", - "orgType": "multiSelect", - "closeForm": false, - "editForm": true, - "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", - "neverSetAsRequired": false, - "isReadOnly": false, - "selectValues": [], - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", - "useAsKpi": false, - "locked": false, - "system": false, - "content": false, - "group": 0, - "mergeStrategy": "", - "hidden": false, - "openEnded": true, - "associatedTypes": null, - "systemAssociatedTypes": null, - "associatedToAll": true, - "unmapped": false, - "unsearchable": false, - "caseInsensitive": true, - "columns": null, - "defaultRows": null, - "sla": 0, - "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" - }, - { - "id": "incident_feedlyurl", - "version": 3, - "cacheVersn": 0, - "modified": "2024-10-10T14:33:09.220777761Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, - "name": "Feedly url", - "prevName": "Feedly url", - "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", - "cliName": "feedlyurl", - "type": "url", - "orgType": "shortText", - "closeForm": false, - "editForm": true, - "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", - "neverSetAsRequired": false, - "isReadOnly": false, - "selectValues": [], - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", - "useAsKpi": false, - "locked": false, - "system": false, - "content": false, - "group": 0, - "mergeStrategy": "", - "hidden": false, - "openEnded": false, - "associatedTypes": [], - "systemAssociatedTypes": null, - "associatedToAll": true, - "unmapped": false, - "unsearchable": false, - "caseInsensitive": true, - "columns": null, - "defaultRows": null, - "sla": 0, - "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" - } - ] -} \ No newline at end of file diff --git a/Packs/FeedFeedly/README.md b/Packs/FeedFeedly/README.md index 5be56d6f7c0a..22268722f0c2 100644 --- a/Packs/FeedFeedly/README.md +++ b/Packs/FeedFeedly/README.md @@ -1,3 +1,5 @@ The Feedly feed provides access to articles with entities, IoCs, and relationships from your Feedly account. +You can ingest the articles as indicators using this pack. If you prefer to ingest them as incidents, you need to also install the FeedlyArticles pack. + In order to access the Feedly feed, you'll need to generate an access token. You can do it from [here](https://feedly.com/i/team/api). \ No newline at end of file diff --git a/Packs/FeedlyArticles/.secrets-ignore b/Packs/FeedlyArticles/.secrets-ignore new file mode 100644 index 000000000000..9de26dfd6f54 --- /dev/null +++ b/Packs/FeedlyArticles/.secrets-ignore @@ -0,0 +1,2 @@ +https://api.feedly.com +https://feedly.com diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_image.png b/Packs/FeedlyArticles/Author_image.png similarity index 100% rename from Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_image.png rename to Packs/FeedlyArticles/Author_image.png diff --git a/Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json b/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json similarity index 100% rename from Packs/FeedFeedly/Classifiers/classifier-Feedly_-_Report_Mapper.json rename to Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json new file mode 100644 index 000000000000..3cf57206dcef --- /dev/null +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json @@ -0,0 +1,61 @@ +{ + "id": "incident_feedlycrawleddate", + "version": 1, + "cacheVersn": 0, + "modified": "2024-10-10T12:19:12.752862283Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Feedly crawled date", + "prevName": "Feedly crawled date", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "feedlycrawleddate", + "type": "shortText", + "orgType": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": null, + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": false, + "associatedTypes": null, + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" +} \ No newline at end of file diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json new file mode 100644 index 000000000000..f1003747c0a9 --- /dev/null +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json @@ -0,0 +1,61 @@ +{ + "id": "incident_feedlymalwarenames", + "version": 1, + "cacheVersn": 0, + "modified": "2024-11-13T14:27:30.49621132Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Feedly Malware Names", + "prevName": "Feedly Malware Names", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "feedlymalwarenames", + "type": "multiSelect", + "orgType": "multiSelect", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": [], + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": true, + "associatedTypes": null, + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" +} \ No newline at end of file diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json new file mode 100644 index 000000000000..6f5238399a15 --- /dev/null +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json @@ -0,0 +1,61 @@ +{ + "id": "incident_feedlythreatactornames", + "version": 1, + "cacheVersn": 0, + "modified": "2024-11-13T14:29:40.202843194Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Feedly Threat Actor Names", + "prevName": "Feedly Threat Actor Names", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "feedlythreatactornames", + "type": "multiSelect", + "orgType": "multiSelect", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": [], + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": true, + "associatedTypes": null, + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" +} \ No newline at end of file diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json new file mode 100644 index 000000000000..054936cf6c7a --- /dev/null +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json @@ -0,0 +1,61 @@ +{ + "id": "incident_feedlyurl", + "version": 3, + "cacheVersn": 0, + "modified": "2024-10-10T14:33:09.220777761Z", + "created": "0001-01-01T00:00:00Z", + "sizeInBytes": 0, + "packID": "", + "packName": "", + "itemVersion": "", + "fromServerVersion": "", + "toServerVersion": "", + "definitionId": "", + "vcShouldIgnore": false, + "vcShouldKeepItemLegacyProdMachine": false, + "commitMessage": "", + "shouldCommit": false, + "name": "Feedly url", + "prevName": "Feedly url", + "ownerOnly": false, + "placeholder": "", + "template": "", + "description": "", + "cliName": "feedlyurl", + "type": "url", + "orgType": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "script": "", + "runScriptAfterUpdate": false, + "fieldCalcScript": "", + "neverSetAsRequired": false, + "isReadOnly": false, + "selectValues": [], + "autoCompleteTags": null, + "validationRegex": "", + "x2_fields": "", + "useAsKpi": false, + "locked": false, + "system": false, + "content": false, + "group": 0, + "mergeStrategy": "", + "hidden": false, + "openEnded": false, + "associatedTypes": [], + "systemAssociatedTypes": null, + "associatedToAll": true, + "unmapped": false, + "unsearchable": false, + "caseInsensitive": true, + "columns": null, + "defaultRows": null, + "sla": 0, + "threshold": 72, + "breachScript": "", + "validatedError": "", + "aliases": null, + "aliasTo": "" +} \ No newline at end of file diff --git a/Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json b/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json similarity index 100% rename from Packs/FeedFeedly/IncidentTypes/customIncidentTypes.json rename to Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.py similarity index 100% rename from Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.py rename to Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.py diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.yml similarity index 100% rename from Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly.yml rename to Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.yml diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_description.md similarity index 100% rename from Packs/FeedFeedly/Integrations/IncidentsFeedly/IncidentsFeedly_description.md rename to Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_description.md diff --git a/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_image.png b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_image.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e4955a727c6c809bdac45bd248bae29ab3574d GIT binary patch literal 6623 zcmY*;1yo#3v+WETAV84d!QCymYj7v%0D(b*O@Kjy6C}7>a1RnJxRV5z!9BP;gA5Yj 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 HV;=NBMK_#I literal 0 HcmV?d00001 diff --git a/Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/README.md similarity index 100% rename from Packs/FeedFeedly/Integrations/IncidentsFeedly/README.md rename to Packs/FeedlyArticles/Integrations/IncidentsFeedly/README.md diff --git a/Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json b/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json similarity index 100% rename from Packs/FeedFeedly/Layouts/layoutscontainer-Feedly_Report.json rename to Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json diff --git a/Packs/FeedFeedly/Playbooks/Feedly_threats.yml b/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml similarity index 100% rename from Packs/FeedFeedly/Playbooks/Feedly_threats.yml rename to Packs/FeedlyArticles/Playbooks/Feedly_threats.yml diff --git a/Packs/FeedlyArticles/README.md b/Packs/FeedlyArticles/README.md new file mode 100644 index 000000000000..0ab2afd66759 --- /dev/null +++ b/Packs/FeedlyArticles/README.md @@ -0,0 +1,5 @@ +The FeedlyArticles pack allows you to ingest articles from Feedly as incidents in Cortex XSOAR. + +You will need to also install the FeedFeedly pack to ingest the threat indicators. Both packs work in tandem, so you will need to install both packs to ingest articles as incidents with all the entities ingested as indicators. + +In order to access the Feedly feed, you'll need to generate an access token. You can do it from [here](https://feedly.com/i/team/api). \ No newline at end of file diff --git a/Packs/FeedlyArticles/pack_metadata.json b/Packs/FeedlyArticles/pack_metadata.json new file mode 100644 index 000000000000..3594a9cc57a2 --- /dev/null +++ b/Packs/FeedlyArticles/pack_metadata.json @@ -0,0 +1,23 @@ +{ + "name": "Feedly", + "description": "Import Articles from Feedly as incidents", + "support": "partner", + "currentVersion": "1.1.0", + "author": "Feedly", + "url": "https://feedly.com/i/landing/threatIntelligence", + "email": "support@feedly.com", + "categories": [ + "Data Enrichment & Threat Intelligence" + ], + "tags": [ + "Threat Intelligence Management", + "Free Feed" + ], + "useCases": [], + "keywords": [], + "marketplaces": [ + "xsoar", + "marketplacev2" + ], + "githubUser": [] +} \ No newline at end of file From c5fcaa4a910661b5ad13a42c53b53df30c27f47c Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Fri, 10 Jan 2025 15:29:52 +0100 Subject: [PATCH 19/27] [feedly] Fix version & add release notes --- Packs/FeedFeedly/ReleaseNotes/1_1_0.md | 7 +++++++ Packs/FeedlyArticles/pack_metadata.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 Packs/FeedFeedly/ReleaseNotes/1_1_0.md diff --git a/Packs/FeedFeedly/ReleaseNotes/1_1_0.md b/Packs/FeedFeedly/ReleaseNotes/1_1_0.md new file mode 100644 index 000000000000..39f0c34d311f --- /dev/null +++ b/Packs/FeedFeedly/ReleaseNotes/1_1_0.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Feedly Feed + +- Added reference to the new incident feed integration. +- Fixed an issue with newerThan param diff --git a/Packs/FeedlyArticles/pack_metadata.json b/Packs/FeedlyArticles/pack_metadata.json index 3594a9cc57a2..537ce414a408 100644 --- a/Packs/FeedlyArticles/pack_metadata.json +++ b/Packs/FeedlyArticles/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Feedly", "description": "Import Articles from Feedly as incidents", "support": "partner", - "currentVersion": "1.1.0", + "currentVersion": "1.0.0", "author": "Feedly", "url": "https://feedly.com/i/landing/threatIntelligence", "email": "support@feedly.com", From 0cb26987bc9ce0381988f16b36b1790980cdb2e0 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 16 Jan 2025 15:02:13 +0100 Subject: [PATCH 20/27] [feedly] PR review --- Packs/FeedlyArticles/.pack-ignore | 0 .../IncidentTypes/customIncidentTypes.json | 220 ++++++++---------- 2 files changed, 102 insertions(+), 118 deletions(-) create mode 100644 Packs/FeedlyArticles/.pack-ignore diff --git a/Packs/FeedlyArticles/.pack-ignore b/Packs/FeedlyArticles/.pack-ignore new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json b/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json index 3678788836de..44aad7dedd05 100644 --- a/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json +++ b/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json @@ -1,118 +1,102 @@ -[ - { - "id": "Feedly Report", - "version": 7, - "cacheVersn": 0, - "modified": "2024-11-13T15:01:36.04775714Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, - "locked": false, - "name": "Feedly Report", - "prevName": "Feedly Report", - "color": "#F8E7A5", - "playbookId": "5e043079-e3a4-44b4-863f-80774c07c1e7", - "hours": 0, - "days": 0, - "weeks": 0, - "hoursR": 0, - "daysR": 0, - "weeksR": 0, - "system": false, - "readonly": false, - "default": false, - "autorun": true, - "preProcessingScript": "", - "closureScript": "", - "disabled": false, - "reputationCalc": 0, - "onChangeRepAlg": 0, - "layout": "e53027fa-56c1-4521-8c38-822af5c0f6de", - "detached": false, - "extractSettings": { - "mode": "Specific", - "fieldCliNameToExtractSettings": { - "additionalemailaddresses": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "emailRep" - ] - }, - "cvelist": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "cveRep" - ] - }, - "detectedips": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "ipRep" - ] - }, - "domainname": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "domainRepUnified" - ] - }, - "filemd5": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "unifiedFileRep" - ] - }, - "filesha1": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "unifiedFileRep" - ] - }, - "filesha256": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "unifiedFileRep" - ] - }, - "mitretechniqueid": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [] - }, - "mitretechniquename": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [] - }, - "selectedindicators": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": true, - "extractIndicatorTypesIDs": [] - }, - "urls": { - "extractAsIsIndicatorTypeId": "", - "isExtractingAllIndicatorTypes": false, - "extractIndicatorTypesIDs": [ - "urlRep" - ] - } - } - } - } -] \ No newline at end of file +{ + "id": "Feedly Report", + "version": -1, + "vcShouldIgnore": false, + "locked": false, + "name": "Feedly Report", + "prevName": "Feedly Report", + "color": "#F8E7A5", + "playbookId": "5e043079-e3a4-44b4-863f-80774c07c1e7", + "hours": 0, + "days": 0, + "weeks": 0, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": true, + "disabled": false, + "reputationCalc": 0, + "onChangeRepAlg": 0, + "layout": "e53027fa-56c1-4521-8c38-822af5c0f6de", + "detached": false, + "extractSettings": { + "mode": "Specific", + "fieldCliNameToExtractSettings": { + "additionalemailaddresses": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "emailRep" + ] + }, + "cvelist": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "cveRep" + ] + }, + "detectedips": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "ipRep" + ] + }, + "domainname": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "domainRepUnified" + ] + }, + "filemd5": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "unifiedFileRep" + ] + }, + "filesha1": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "unifiedFileRep" + ] + }, + "filesha256": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "unifiedFileRep" + ] + }, + "mitretechniqueid": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [] + }, + "mitretechniquename": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [] + }, + "selectedindicators": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": true, + "extractIndicatorTypesIDs": [] + }, + "urls": { + "extractAsIsIndicatorTypeId": "", + "isExtractingAllIndicatorTypes": false, + "extractIndicatorTypesIDs": [ + "urlRep" + ] + } + } + }, + "fromVersion": "6.10.0" +} \ No newline at end of file From f6a289e8ea69cd4a27f12cbe36dce1e44b281141 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 16 Jan 2025 16:43:09 +0100 Subject: [PATCH 21/27] [feedly] format files --- .../classifier-Feedly_-_Report_Mapper.json | 2 +- .../incident_feedlycrawleddate.json | 39 ++----------------- .../incident_feedlymalwarenames.json | 39 ++----------------- .../incident_feedlythreatactornames.json | 39 ++----------------- .../IncidentFields/incident_feedlyurl.json | 39 ++----------------- .../IncidentTypes/customIncidentTypes.json | 4 +- .../IncidentsFeedly/IncidentsFeedly.yml | 2 +- .../IncidentsFeedly_description.md | 2 +- .../layoutscontainer-Feedly_Report.json | 2 +- .../Playbooks/Feedly_threats.yml | 10 +++-- 10 files changed, 25 insertions(+), 153 deletions(-) diff --git a/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json b/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json index 32dd0c099b30..cf5749b29ddb 100644 --- a/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json +++ b/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json @@ -6,7 +6,7 @@ "description": "", "feed": false, "fromServerVersion": "", - "id": "610827cc-e32a-4caf-84b3-8c91fbee7fd0", + "id": "Feedly - Report Mapper", "incidentSamples": null, "indicatorSamples": null, "instanceIds": null, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json index 3cf57206dcef..cca6f2ec076b 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json @@ -1,61 +1,28 @@ { "id": "incident_feedlycrawleddate", - "version": 1, - "cacheVersn": 0, + "version": -1, "modified": "2024-10-10T12:19:12.752862283Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, "name": "Feedly crawled date", - "prevName": "Feedly crawled date", "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", "cliName": "feedlycrawleddate", "type": "shortText", - "orgType": "shortText", "closeForm": false, "editForm": true, "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", "neverSetAsRequired": false, "isReadOnly": false, - "selectValues": null, - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", "useAsKpi": false, "locked": false, "system": false, - "content": false, + "content": true, "group": 0, - "mergeStrategy": "", "hidden": false, "openEnded": false, - "associatedTypes": null, - "systemAssociatedTypes": null, "associatedToAll": true, "unmapped": false, "unsearchable": false, "caseInsensitive": true, - "columns": null, - "defaultRows": null, "sla": 0, "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" + "fromVersion": "6.10.0" } \ No newline at end of file diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json index f1003747c0a9..2b39fe212652 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json @@ -1,61 +1,28 @@ { "id": "incident_feedlymalwarenames", - "version": 1, - "cacheVersn": 0, + "version": -1, "modified": "2024-11-13T14:27:30.49621132Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, "name": "Feedly Malware Names", - "prevName": "Feedly Malware Names", "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", "cliName": "feedlymalwarenames", "type": "multiSelect", - "orgType": "multiSelect", "closeForm": false, "editForm": true, "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", "neverSetAsRequired": false, "isReadOnly": false, - "selectValues": [], - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", "useAsKpi": false, "locked": false, "system": false, - "content": false, + "content": true, "group": 0, - "mergeStrategy": "", "hidden": false, "openEnded": true, - "associatedTypes": null, - "systemAssociatedTypes": null, "associatedToAll": true, "unmapped": false, "unsearchable": false, "caseInsensitive": true, - "columns": null, - "defaultRows": null, "sla": 0, "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" + "fromVersion": "6.10.0" } \ No newline at end of file diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json index 6f5238399a15..473bafbe690e 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json @@ -1,61 +1,28 @@ { "id": "incident_feedlythreatactornames", - "version": 1, - "cacheVersn": 0, + "version": -1, "modified": "2024-11-13T14:29:40.202843194Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, "name": "Feedly Threat Actor Names", - "prevName": "Feedly Threat Actor Names", "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", "cliName": "feedlythreatactornames", "type": "multiSelect", - "orgType": "multiSelect", "closeForm": false, "editForm": true, "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", "neverSetAsRequired": false, "isReadOnly": false, - "selectValues": [], - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", "useAsKpi": false, "locked": false, "system": false, - "content": false, + "content": true, "group": 0, - "mergeStrategy": "", "hidden": false, "openEnded": true, - "associatedTypes": null, - "systemAssociatedTypes": null, "associatedToAll": true, "unmapped": false, "unsearchable": false, "caseInsensitive": true, - "columns": null, - "defaultRows": null, "sla": 0, "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" + "fromVersion": "6.10.0" } \ No newline at end of file diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json index 054936cf6c7a..a1c1ec996164 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json @@ -1,61 +1,28 @@ { "id": "incident_feedlyurl", - "version": 3, - "cacheVersn": 0, + "version": -1, "modified": "2024-10-10T14:33:09.220777761Z", - "created": "0001-01-01T00:00:00Z", - "sizeInBytes": 0, - "packID": "", - "packName": "", - "itemVersion": "", - "fromServerVersion": "", - "toServerVersion": "", - "definitionId": "", - "vcShouldIgnore": false, - "vcShouldKeepItemLegacyProdMachine": false, - "commitMessage": "", - "shouldCommit": false, "name": "Feedly url", - "prevName": "Feedly url", "ownerOnly": false, - "placeholder": "", - "template": "", - "description": "", "cliName": "feedlyurl", "type": "url", - "orgType": "shortText", "closeForm": false, "editForm": true, "required": false, - "script": "", - "runScriptAfterUpdate": false, - "fieldCalcScript": "", "neverSetAsRequired": false, "isReadOnly": false, - "selectValues": [], - "autoCompleteTags": null, - "validationRegex": "", - "x2_fields": "", "useAsKpi": false, "locked": false, "system": false, - "content": false, + "content": true, "group": 0, - "mergeStrategy": "", "hidden": false, "openEnded": false, - "associatedTypes": [], - "systemAssociatedTypes": null, "associatedToAll": true, "unmapped": false, "unsearchable": false, "caseInsensitive": true, - "columns": null, - "defaultRows": null, "sla": 0, "threshold": 72, - "breachScript": "", - "validatedError": "", - "aliases": null, - "aliasTo": "" + "fromVersion": "6.10.0" } \ No newline at end of file diff --git a/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json b/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json index 44aad7dedd05..efddf603bfde 100644 --- a/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json +++ b/Packs/FeedlyArticles/IncidentTypes/customIncidentTypes.json @@ -6,7 +6,7 @@ "name": "Feedly Report", "prevName": "Feedly Report", "color": "#F8E7A5", - "playbookId": "5e043079-e3a4-44b4-863f-80774c07c1e7", + "playbookId": "Feedly threats", "hours": 0, "days": 0, "weeks": 0, @@ -20,7 +20,7 @@ "disabled": false, "reputationCalc": 0, "onChangeRepAlg": 0, - "layout": "e53027fa-56c1-4521-8c38-822af5c0f6de", + "layout": "Feedly Report", "detached": false, "extractSettings": { "mode": "Specific", diff --git a/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.yml b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.yml index d3992a5ab9d5..18b6f22ac5e6 100644 --- a/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.yml +++ b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly.yml @@ -72,4 +72,4 @@ script: type: python tests: - No tests (auto formatted). -defaultmapperin: Feedly - Report Mapper \ No newline at end of file +defaultmapperin: Feedly - Report Mapper diff --git a/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_description.md b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_description.md index 30f2664793cc..e0fd2215aa1e 100644 --- a/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_description.md +++ b/Packs/FeedlyArticles/Integrations/IncidentsFeedly/IncidentsFeedly_description.md @@ -8,4 +8,4 @@ Use the IncidentsFeedly integration to import articles as incidents from your Fe ### Authentication -To generate an API for the application, go to [the api page on your account](https://feedly.com/i/team/api). We highly recommend that you create a separate token for this integration. +To generate an API for the application, go to [the api page on your account](https://feedly.com/i/team/api). We highly recommend that you create a separate token for this integration. \ No newline at end of file diff --git a/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json b/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json index 9fa980845dd1..7b6a87d6405a 100644 --- a/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json +++ b/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json @@ -787,7 +787,7 @@ "edit": null, "fromServerVersion": "", "group": "incident", - "id": "e53027fa-56c1-4521-8c38-822af5c0f6de", + "id": "Feedly Report", "indicatorsDetails": null, "indicatorsQuickView": null, "itemVersion": "", diff --git a/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml b/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml index 0a6055fc0347..e50e2ca69cc4 100644 --- a/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml +++ b/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml @@ -1,6 +1,5 @@ -id: 5e043079-e3a4-44b4-863f-80774c07c1e7 -version: 13 -vcShouldKeepItemLegacyProdMachine: false +id: Feedly threats +version: -1 name: Feedly threats starttaskid: "0" tasks: @@ -14,6 +13,7 @@ tasks: name: "" iscommand: false brand: "" + description: '' nexttasks: '#none#': - "1" @@ -263,3 +263,7 @@ view: |- inputs: [] outputs: [] quiet: true +tests: +- No tests (auto formatted) +fromversion: 6.10.0 +description: Links threat indicators to the report incident From ecea6d531ac625230c52af206b8b90ef8554b04b Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Mon, 20 Jan 2025 12:27:48 +0100 Subject: [PATCH 22/27] [feedly] pr.review: 4. unsearchable --- .../IncidentFields/incident_feedlycrawleddate.json | 2 +- .../IncidentFields/incident_feedlymalwarenames.json | 2 +- .../IncidentFields/incident_feedlythreatactornames.json | 2 +- Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json index cca6f2ec076b..f729cbd795b5 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json @@ -20,7 +20,7 @@ "openEnded": false, "associatedToAll": true, "unmapped": false, - "unsearchable": false, + "unsearchable": true, "caseInsensitive": true, "sla": 0, "threshold": 72, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json index 2b39fe212652..83ac0d2f69be 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json @@ -20,7 +20,7 @@ "openEnded": true, "associatedToAll": true, "unmapped": false, - "unsearchable": false, + "unsearchable": true, "caseInsensitive": true, "sla": 0, "threshold": 72, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json index 473bafbe690e..4864a6a23d53 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json @@ -20,7 +20,7 @@ "openEnded": true, "associatedToAll": true, "unmapped": false, - "unsearchable": false, + "unsearchable": true, "caseInsensitive": true, "sla": 0, "threshold": 72, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json index a1c1ec996164..56086f36a31a 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json @@ -20,7 +20,7 @@ "openEnded": false, "associatedToAll": true, "unmapped": false, - "unsearchable": false, + "unsearchable": true, "caseInsensitive": true, "sla": 0, "threshold": 72, From 1ac30a5ee043e442a5818e7535323101a8c99588 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Mon, 20 Jan 2025 12:44:00 +0100 Subject: [PATCH 23/27] [feedly] pr.review: 3. 5. Associate fields with Feedly Report --- .../classifier-Feedly_-_Report_Mapper.json | 29 +++++++++++-------- .../incident_feedlycrawleddate.json | 5 +++- .../incident_feedlymalwarenames.json | 5 +++- .../incident_feedlythreatactornames.json | 5 +++- .../IncidentFields/incident_feedlyurl.json | 5 +++- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json b/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json index cf5749b29ddb..abf923647f8d 100644 --- a/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json +++ b/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json @@ -15,6 +15,23 @@ "locked": false, "logicalVersion": 10, "mapping": { + "Feedly Report": { + "dontMapEventToLabels": false, + "internalMapping": { + "Feedly Malware Names": { + "simple": "indicators.Malware" + }, + "Feedly Threat Actor Names": { + "simple": "indicators.Threat Actor" + }, + "Feedly crawled date": { + "simple": "create_time" + }, + "Feedly url": { + "simple": "feedly_url" + } + } + }, "dbot_classification_incident_type_all": { "dontMapEventToLabels": true, "internalMapping": { @@ -33,18 +50,6 @@ "Event ID": { "simple": "event_id" }, - "Feedly Malware Names": { - "simple": "indicators.Malware" - }, - "Feedly Threat Actor Names": { - "simple": "indicators.Threat Actor" - }, - "Feedly crawled date": { - "simple": "create_time" - }, - "Feedly url": { - "simple": "feedly_url" - }, "File MD5": { "simple": "indicators.File" }, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json index f729cbd795b5..11b384b56b21 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlycrawleddate.json @@ -18,7 +18,10 @@ "group": 0, "hidden": false, "openEnded": false, - "associatedToAll": true, + "associatedTypes": [ + "Feedly Report" + ], + "associatedToAll": false, "unmapped": false, "unsearchable": true, "caseInsensitive": true, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json index 83ac0d2f69be..7bffb9d8eefc 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlymalwarenames.json @@ -18,7 +18,10 @@ "group": 0, "hidden": false, "openEnded": true, - "associatedToAll": true, + "associatedTypes": [ + "Feedly Report" + ], + "associatedToAll": false, "unmapped": false, "unsearchable": true, "caseInsensitive": true, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json index 4864a6a23d53..945936d4d240 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlythreatactornames.json @@ -18,7 +18,10 @@ "group": 0, "hidden": false, "openEnded": true, - "associatedToAll": true, + "associatedTypes": [ + "Feedly Report" + ], + "associatedToAll": false, "unmapped": false, "unsearchable": true, "caseInsensitive": true, diff --git a/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json index 56086f36a31a..c3b6522432c8 100644 --- a/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json +++ b/Packs/FeedlyArticles/IncidentFields/incident_feedlyurl.json @@ -18,7 +18,10 @@ "group": 0, "hidden": false, "openEnded": false, - "associatedToAll": true, + "associatedTypes": [ + "Feedly Report" + ], + "associatedToAll": false, "unmapped": false, "unsearchable": true, "caseInsensitive": true, From 6695291728b61f74a9e4f57b11f34a02f0af8ef0 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Thu, 30 Jan 2025 14:31:56 +0100 Subject: [PATCH 24/27] [feedly] pr.review: 1. & 2. Add conditional tasks to check if indicators are in the article --- .../Playbooks/Feedly_threats.yml | 219 +++++++++++++++++- 1 file changed, 207 insertions(+), 12 deletions(-) diff --git a/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml b/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml index e50e2ca69cc4..ba11b36cecde 100644 --- a/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml +++ b/Packs/FeedlyArticles/Playbooks/Feedly_threats.yml @@ -16,16 +16,16 @@ tasks: description: '' nexttasks: '#none#': - - "1" - - "3" - - "5" + - "6" + - "7" + - "8" separatecontext: false continueonerrortype: "" view: |- { "position": { "x": 610, - "y": -160 + "y": -410 } } note: false @@ -55,7 +55,7 @@ tasks: brand: "" nexttasks: '#none#': - - "4" + - "9" scriptarguments: add_fields_to_context: simple: mitreid @@ -116,7 +116,7 @@ tasks: brand: "" nexttasks: '#none#': - - "4" + - "9" scriptarguments: query: complex: @@ -168,6 +168,9 @@ tasks: type: regular iscommand: true brand: Builtin + nexttasks: + '#none#': + - "10" scriptarguments: incidentId: simple: ${incident.id} @@ -178,8 +181,8 @@ tasks: view: |- { "position": { - "x": 610, - "y": 530 + "x": 830, + "y": 680 } } note: false @@ -209,7 +212,7 @@ tasks: brand: "" nexttasks: '#none#': - - "4" + - "9" scriptarguments: query: complex: @@ -238,7 +241,199 @@ tasks: { "position": { "x": 1100, - "y": 200 + "y": 210 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "6": + id: "6" + taskid: 01655832-29fb-49c9-8a70-ec842e7a70b8 + type: condition + task: + id: 01655832-29fb-49c9-8a70-ec842e7a70b8 + version: -1 + name: Has Threat Actor + description: Check that there is any Threat Actor in the report + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "9" + "yes": + - "5" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: incident.feedlythreatactornames + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 1100, + "y": -50 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "7": + id: "7" + taskid: b7da2121-66c7-4e88-810a-07c72ddbe66c + type: condition + task: + id: b7da2121-66c7-4e88-810a-07c72ddbe66c + version: -1 + name: Has Malware + description: Check that there is any Malware in the report + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "9" + "yes": + - "3" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: incident.feedlymalwarenames + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 610, + "y": -50 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "8": + id: "8" + taskid: 3d8f39e0-5b3c-4061-8177-0581cc817866 + type: condition + task: + id: 3d8f39e0-5b3c-4061-8177-0581cc817866 + version: -1 + name: Has TTP + description: Check that there is any TTP in the report + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "9" + "yes": + - "1" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: incident.mitretechniqueid + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 140, + "y": -50 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "9": + id: "9" + taskid: 25a65fcd-958c-45bc-8abb-da56870f1082 + type: condition + task: + id: 25a65fcd-958c-45bc-8abb-da56870f1082 + version: -1 + name: Found indicatiors + description: Check if any indicators was found + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "10" + "yes": + - "4" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: ${foundIndicators.id} + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 610, + "y": 450 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "10": + id: "10" + taskid: 519bf625-0d92-4e67-822b-054207b6b233 + type: title + task: + id: 519bf625-0d92-4e67-822b-054207b6b233 + version: -1 + name: DONE + type: title + iscommand: false + brand: "" + description: '' + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 610, + "y": 920 } } note: false @@ -253,10 +448,10 @@ view: |- "linkLabelsPosition": {}, "paper": { "dimensions": { - "height": 785, + "height": 1395, "width": 1340, "x": 140, - "y": -160 + "y": -410 } } } From 4bd5197165d1beb7ec160a81bbded80fa1f71950 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Mon, 10 Feb 2025 14:59:51 +0100 Subject: [PATCH 25/27] [feedly] pr.review: Add playbook png --- .../Feedly_threats_Mon_Feb_10_2025.png | Bin 0 -> 118082 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Packs/FeedlyArticles/doc_files/Feedly_threats_Mon_Feb_10_2025.png diff --git a/Packs/FeedlyArticles/doc_files/Feedly_threats_Mon_Feb_10_2025.png b/Packs/FeedlyArticles/doc_files/Feedly_threats_Mon_Feb_10_2025.png new file mode 100644 index 0000000000000000000000000000000000000000..0619608dce885de446d8453520efed8834e6b4d1 GIT binary patch literal 118082 zcmZ^Lc|26@-#-%(6=f@XE0UzLZ*xmj_G}rU5;FFE-zq6t+E8Ms>}z&ei%`mv8Dw9> zU@S4VVdi(8S^D1J=XrjA+^@Sc&biL#`Yi9ydY#Amx|;h~cvkRwUIs^sJ%@3_8&si+KvP1bz zypZJd7NL^6hBDO4qM1;kf^n%xR@`gR;5Yb@K5z$F}xnoI)LkKO@ zJA{lR<~oE^HY)lql&3Yg|qqS+yROjJxaT%wf!*6_)xCWTkn@0K@iNGZnEMDTnYYt&&ynUgw)cnnYKJVIya#2iLvH2*mK;=RjMlw8o7y_DS)=8&xO zjUTV1juC>kRK zb>WZF6dK^%#aG@kq38T0h`_dQGm1|(c&5X;MU^n!O3!;1Y@$xwb+Ys4`q##Yl%T>S zCHuf6DIeR_6shyvlJif(Ju+K1mM7j*N}v3nyGwn6xNr^U?|)iXigx9f4GX z^LlD^vQ`h4Gue7T`=CsU>EU(MH7zCQGwDQYWnA$@jyDRwsbtebmOKC3RPQlNzh zJQO~_xLR_`Y5*QBEcP%={CN_#aPB*!_5XzWo&!$4Tw44VcoS(mOef*;wCP zg8|EOc>?yql^50x559FXoI`>eOU;DywRLi@ zp@*}@U(AbkQuMZ|!0IKQ+eaqF6Q0VQ)}Hi}BjL2wp@bX0w%qSB ztgt=Aey5$XS_8$-6A4t{P&h3N$DOVGegL`-d$9)-k@-f(DRLiQc~kE~uxQ<8a@Zk7 z+q@ke9U(xt=arkJVGFm(*T>v`{$X5hSRuTx53&4#QdVR&aL6?X&$2ib^Zg)sDH&E~ z{eiuCe&8u!j9G9AB^^RiMqFmBN}ZT<4W3xJK880*mWiB^gBW6vTF#3fZ1R|h)QZ<2 z9rh?@$CsjYIo_53v_O;5EOh`NinHk_Jedn{b^iK4tDiMfq9jMk6$E*IITjk8e*kzT ze=sXNON+ZblE*60JB>+4;`#^Sle$Tw>TL$eo)o(;y#^2MzpCRz+3`t+n2{CFw#L{d z9_NoDta>7Pueq&TqFvq@XF}|TS2N6B#Nq;QB9^sm<>>)Wb}^^gkh=0 zkVw8hJJ#3uuBTv#T{aLmJYT-E=f%mE2YX(KJ6Ml`XTFwvde#_mdt}(+ne%l06yx{X z-=1&&?Cq5;J?I6%u9UcP#cilLpX zrPAMByuh;IbBsuFgOvKfTQ&2==~6xmgRg)Fd8lD}tjwN}2@QpdFfwE%W4tBEa?lsi zCv|2;^T{^%*6-*C663q2f*aJu_1ZYWpE=cO!d>ptif=x_bGmiyVzNq*Kli&BKH2tD zn0pulS&9;VV_?XdVuEy@edZo~C!b*d8=FHAd^}h0Yr1z~kmp5)_MBSmjpvY!BywFo zGP{a;yqqK65e>{XHk_5GIqk}e+YJx)jF}K^jgvLW8~t-k7~ZBQu?mTi;nZ>0?R-MY z_IR>e?`+HM+0tPau|uc8A6k#-53u34ZC1vOB^4C8B@mqFZGX6mhsd`&a8g9Wkad!t zLfHqn6COL(7*WEcITScByRlIpGLTOYD7X)4dukl4%zV=-sL9W5Ir5U(BLzQq|3jk; z6@MxYBFxDvrLqD!oJp-d4y|Tno*InDa_BiejtyBhU+(PJF-b8AKpax0hn-;mRpM}V zi>E!t)Y98B$)o+<3=Y@k{98yhc)K%y`^2G)BakXV&W%}L+|+#+BhJ)s+f zpEA+YBL#C(*`N#k!(sii=+B=&|0;Jf-(Hz^jtvk*xZv$=Y(v8i3hR4^m9pTI&J)I^ zO_N^?HLH3|{cz-(t#q5nQ5n8xp? zZ29xYxS6C(6l1mC(lgEruF4zdSpMV z7jU}i{1yLDu%sA@WDsT(WNHWZ@XNa&A0T;7G)FJDRSU+%4!H(szq%m5PCxrRJjiWk z>6!2LHzy}40aa(mB(JH#Un-S~mqdhMWrj{#Qv3ZA~d>b5(q2t;51 z^}3B(5(({uoy$9{yxda1xoi1j;jn-Zsluh~H*Y4gv?rn?5Zhi!99fj>9=k|FwJUaC zE#Ae%W)m#ppDq(TpD+1XanXX$st#ZGu+ZYmF49&#>8{eo%!}m~p~|<9hI;K_#|~bu zShn*2+~6pQvH2c<3HVp-#0%e4vW{Kzgu)Jhn-QUO(n4OHtk8w%N4NxB*>gre&!SpJ zCAcwpIhjdt@oH#)y{qo_LWjjV|FVD{E~YSu@Ofi9I=9&PUReSi{>zJ%!r_(nSLgi3 zuh=chnkpX*!H-F%EWP5glYC^g`FQbhH=FW-kPTu-!j||yp@`W(yn}8qF}QMOh;z;C zC9Mb;=GzMqyNcyZp_-)G2uU~@1L?xHnVI!h3|W;y;6N94kd>cAm%Sb`?obpwVJKza zS{f5u#hn_w$(K99=cB?o(G`iYH=MZV!PDHGfZ|(Mu2CV*ED|MR`29}Ky#Yj?PzdR} zcSv@vuXb<9m}>1wD1cD0sEG7h!q#RE5=W!ZcFpAidM(6V5eh0o3V#34BSp$AatC1c zLYR*wna%5UlQq|CeBH{~kP>hKMejVivH?c-AhH6Sh0)W`GJoK|N(S0Qt}Mo^YHu8H z@-kmY#L)!n>4jYu`}9eh9wSj9)%M*|7yVaqC8K+-0t{-VJ5&XL%Qg#DXt+ljB5f>J zPJb2|4{;{AR6LqiuWE8XoK`-rQZ0UALr zUGYbPN-|o$Jf5&d_hhn2p-k*E=*sL`H+)-iCBMQjeI<5wz?_(jL;FwJ;3#0(4!Em0 zF@K7TAZ}rZP{;%RDz?$u{!FN6kFdUBDkyAh9;R?3v?>sLc-cX9vucB&H+)bw*rRRF zE+Da!U%p$G9&I;QP~~n*5eQgYh*ey$;7cKnS45Z;5I4-N4l=O`M6y|u%BGD}cLrjT zt0!K_4hrH4u_~p`hBf1@Ty9e!5c%+1ykdxFq=xWpIw_=iaCl?b)bgO6MB*EZiO*$x z6CB_XMIT&Hdr^l~ux-tF6VI0hzmnSo!)oj9#FlZZdUw;cn|b|n>H(>B^O0Q7+DTvQ zhq?K9eV2YdhGEeDCtIqAgPj8ZJalRLvOF>2)oaQ5WU3=_o!D(x3>VuOs8|R-?)-5g z?5#?AKK<~ithtH^phJs~9}Ul4VErF8zE z8}@nw{c{(4N1lh9W8+M!>NbrNzC6F=QIZ%mO>8Mqwwhb7-zloFNs|MG(JeBLT&Xfk!LNc}Eq|@jaa&Jp;g$3EjQBB|%snlsc&yI5<-U&e>RPXb zV9Iubz_T?%eu%^?+4GhGZLPnmNjK+5Le5ULqXa94@veg({Zq&0ZfxEwnF!OAEuW|N zm_GAb$htY^F+r%W(^V)@`79&wJ{sGZvMQ)FEj8;2T50rg8$uT-3_4hD@_ zFHgpQmUF=#HtRGc31{^qd#nORG_BF)$rqbcg4&~eM+)mCh|6fJSjix3ygpD-SJU#V zIP+Y=Ho+=S>`Hqi=S$*<-Y~yx&`MvZb5kGdM19>#T#@xOsuJHGaeMs1vRilhv@I?Z z{^wiU{foW+jo;72%vpL}QCgaLVRl{4r+u|@_PK}k(8K&?LdfRpx1+9=ba=mMiAbxB zpQbH#^?|01Z1D;Pp$G?(Rh_3@&2}W$@>lCO#Y@X6Dgh3wC>gvw+fQCuZ^!Lsz4{|l zZLbg5=Y~rtqT1WdYi{bUjeHXc@5bWG7e6XldUb~{mnjN9>SoK2-=Oauek{i&cKMhS(`w3^dL&ua|bNo*TPfwXs_1_`B=J6x#^t;2#c_5`dZbU^ zOX!NZ)dYo7GoG&d1g`~H;~Vw9SP>@@ikC0^Q7{fo?B5uO9rFEgwZ6Y>u5p@km^dEd zufu&ey}mGdnJr|85W7cQL@$Xw1Rt;%6(EEV3R$ht6oO0JYJU+TZVdpePrmqh29P{n zTfZIus|JVNunHk;9(lr9N*s)>ITzq-jBrEb`XIz!35u>&kOC(?jVqUb+#~_iD&2f@)A{oS%*-6f)y(aEw%zp7;=M)(4i*>35PQKpg z$>(7BQ1Z1R4vUQ`n;NIh1O0D!^!fGm4j5LiHQ$d_IXqJ5 zBW&r{&Db~lr!?n6e!t4koS)N@R{WYM`R6;K?}%P~!0=1jllX*odIw^52yt2yd6$AN zhLF~J>qS|O(5=|js;ThlrgDMm;<`-ZDf{%b0%bx;QPB3vNYrLftxl|TzHRN&;Q5lx zdb^RZ%HQVecDe8Q1m?1l-rMz=ba*H!D407V$fEBcuFsfttlLwGtei6iprBPvEYOAA zJlBD*)}dRYpPCQ(25PObXAffyOP-!!e7Q)P=9?(5PO(Vt{(3R3%V|<|HAB3_{2OU* zac4q*V@pew*zd^oyRdHY*u^7vSWd3b52&tw*&Ks?=`Zy~i(9f|d#g#?hGue!CLf90 zv2_Y6zB>}j-2*YsQu+bu!i#Z|b;7~;AfYxBpJ3A5nOIY+oth22>h|^WgC)c`lg>5m zWd8aMf>1lLN(H`C@ur@GgsZO++s`leGXJhJv3&A{PM;xTmKf(%dfOd`%H>Q6rr^m0w zp~)H5^X57PRpM4jUu0LmL)Vw(WuC=gJMOL?wFRR^&J5C)5Yc14FW~0PuhK5*{0rOI zkc*e>2pC_5 zQrwPD|9$zkWyJ+EK4rs`O>A}8){R-G^`?hy_lp8Lh;lyPYBE|9r|{xdfw$I(tGMo6 zMJ^+sue-J1d)U(Ni;odBW7Q8CuNK!wpE9DKz04(`N6FNWfJ|LeVD%n3Z9Ma|g-$wu zHEq@-#_*rwy0J9oGhf16> zu8!!{)MVFET}Mh^&I}=iJ9-UE?)-8XPdc$OArdmTtK+qW>RP-*@c=Powt}RxwxD>H zGc{wNlczm}3#8E-uefrebvuBH;d8Yeoc7BSp;F?=Mz-u1tKbc-zWCkPxP}zf%{HO0 z_a;; zoh#-eeyeHpNCjep2akv7@g0^{zVza zxA?+U!KW}HV1{uz;4#_{>!6@KU*OG3y4#Ytc1LH?r_6kVPrzX!E@18J7!2ddO8WAc zW2j+dZ zLP1IcFG`5U1NC?pl|ON(`8V52Bko$cY|mG#t|r||?=HsD8`LiW_$c3-g+JmX_VivW zK@cG%-fniN9 zL`LvBVe$h#atoowCZI)NN^xXFBIh>fq<1X(hsVZQx2&hp0VP7-m_>;jbH6{@wRNm5 z<+mko{Y>X7vLBhAFpbO%3PiUqt$HO|<}>SSp6i*|h0y@U`5UEtEwn!>kt!J#Aeqg) zCzenl0{)Gm6$n{mgtXRCC&oIjLWr{y;y0=us#AftHB^HrUozll)2TCJN>4x zRc)wL#9=3Y26%Pia<2xj=2pdO4*m!ZRMIi*gT>r|~RxAookmvK_|&-K8?nLH(a^)j^yQMK!_H%lSmG8XsZ>=R?Ex8K<; zr;G$UZ8v7t$&|89J#O}RM~BxO3G^yg{p~vD6=ZJT@r9*jjlVmr5|tSizCN>)J)o;vdAVXLv-TNUyzP6(kncKmv3l8JnAdS@ zfirNYJ9*Kj3w_5Jv)Z!cBgkc@Nkh;a=%||Eg1qxf?Nk-`P^rCP&AN;8qau!zzh{qJ z6FI7?qOV0r0(+MXZVyf@`}7CsMz}O~Ow-<_+jC%fByd&yVnuqULr=qZK4)UPR0S+^ z;6A$X>9x_swF&JbKYoDPOr2Gbxl*O~gjB%ejG!A3-xHmVJY55ol8wulayB`YndDyC zW5Wb3mo{e!-HNZh>ql^98=vQ5hgnikwj{$v-#)2&fGXi`W<2U4Ck|{=T#9YG-87A+qmyiGcIo~ z3=+P0CpOoSi+a9~Fxe-sanR2`k(8Gm=s%MGPItf|P3Uf#lR%e@0QT)oY{UWkH{qp> zaR0m4{C$m_B!^0E)cv1gMuO)v90$VBgMe8NH~2!C^K^K!DzQA_3qf_Od;YUlnQ8y} zhCpHcQR1>yoyz>(u6okadY#-r<9hQz&mF55fO!d4MMsI79u@n-3+xMf@)f$3>@mi?=zQ&p|!&-{hu1L*j;0OPCUcNiye~`o6#26Mmsf3w8Sb-aTEJTyBa}E zHe_G_BPC#6m4D@C1|l>O)&X<$jmbmetl) zZQuRE;U!QX$c*iE#uwHvMB1>98(P&ITc}$sk_&2Iy{xyR`?k|%yD+wCEz{dBqDNKz zl(Jmr+E$rQ?U{BZYj2s13u}h82(DC=RE6v?;k!$lTDr^NrtAE0wPXOZssAJ0e)rL( zXU8sDY?h1=-=2=T8rE6<`Mo&(`hwys0aFrPUcX8f)_acgp5VTITTK=X!w=pYOFw1w z);d3wvLXF{T}SvO!3r?3rNvU=llEuQOmj4m$8ZC$VYQszB8`gy_;e|!*-1y6d7+Te zhlU0w#1YLZ7`~M!i36(MTmcmw%r}k+@rq%d^^olJO>fFRkOm~q-9m9W(-pnpN!)pRYIrfMD`GY^+0L{m$~Xvvv_gPKP0G7 zD1P1F^@ocbA?ZR*t5a-$I&#@{y1PJwjHYd|!t>>(0;{t?TKWqA-C*@^9axnV~SkIW{i<7#KmM2R3zUzAOpE&qGge(@klJN_y!5L4tytYFf1}&7wtL)jJ?(X}@s3eP4cRC1q zwR?tbpwdAq0)~CFdQ3A$-HCCQv@_W|@wiRT=LFnILnU8LYfNj0_y)^81QNbJr!lrK z-TS45gd1?{xHxAG8h`g<^NJQoTOq+gKVHjA45XA2!_Gw~ThzV}{w-qpCj14SZ6HT1 zEkeF_X56OFaKXx>t#!V)V|!slRpd*avK+E9Lf%-fbnuwU+>eiLpZi!N1b<)_er5=v zek>%*%s0O855nojdR>_415Lbk6%Sp|N+rq>=1Z*mOYJX0`Str}US}xzbq%0*WvbvZ zIltxvRrHAc0zLKyDqPJy!<*_Ci64dh zY?KxUFD*l-mCbvX_QDy1zn+Yg)9$tPZUaYL`@^L5Z?L=2R1Gdt0 zVAW;kn@A$UM&aFl#aDD-$|sEu&nV9Qh1K-*Ar^fRJrqCiA02CfWw7ovs2f2KYdQc1 zJ~B=G$rXP_ZqTgSii2T*zPb#R$f)==3P}02mL5`c4h+-u9xvz>Tze^a$8(2g;VX)B zvHKOgKXEi6WLvtgv0BDu;4q&Io2|I-G#=k9Q86MUL`-nGLomuvwhUQ|usXnlsut}U z&f2Bt_-!rRqWFVkk5cgwRuB1BO%_r^AtO;$=L?Uqp zi+v1yTZ17;EY$@l!y^CNsell(+v1MH#Eww4*nXkIhOdJ3H4!ffFWi05FDM<&aD8X85ymfmf;_!Q833i5Ki==&!*r@%j$rUNp0(I%pRju;rn! z_L;K!DaNcarYk!Wb}q4+LL=8^2R6Es0n?2+FIOx|CiU_a){f_0FTHC31|tH%QlJC) z-Fa-CIBVal6)Z}djo%B#M=?jP6mxQ`tm%!g|*y6Wji1!k-*8z;2 zy&ZNef~~2pwtBpnmAjcWz9TkWE1}swGdW%vehL?o2s6sn)BG{ZK<@N(8iS^=>83>z zw0O>OeUflC)aAJ!n-|L#valxSJM+40xY;Uwi&q@n@El$h6!PQQ#bsqvl)&^EbJrg@ zf}pTX45b5e8?-Z@n90_X+tn}@%;Np6RW!hf7h7NIM+6)M{kojC8S^sFfDq`WT$m?; z*mbF7qF<{$%5P=LranVAnU_OEx0IAEc9C2)U^xZ$eRs_B4MZ9kiUR%1(a-nILbvi4 zl@6v5yK-KgwRhKkb@t<{`&|yuX1+3X&7$uU)|<*CZ}3i|F z6^m~~pym)fH5K&f?{Vu^kU{qqtZZNdZJDL$vj7I0f-V%0{vg?2oU)b2L(^0(%ossI zeAkmHJGR)Xxq1Qq{fSQ;z;LZhdI_&HtuMn&Pg=K@L7%i#43P$a>SmRq@Zejy>EE@eD@0M zqH{RY9-kedY3!kUh`h*4O|T*g!MlgNqWaBBUYGlcvQ-(4zm~sCybr*4VZs#tl`ex{a&n>gAs2iXyA@RWMN`;pVn4 z8sg<2aeeb}e=t;cIpD4HK)HmB%P>DFcy5>5^lXcDL)z+>sc)MCp(t|NifKTvB%lNn z3gwh_Rd;3z!N8R*Tg=sflpaBT8+`U2iW)^iV+zi=RkDV&oY4;vCxz`|x(ymTQcD|K z8(sNqO}iXq``F4x@!g>N*(#yWs@H*#Q#=zge7MNfazx)Z(RoNOSFa_Sk4H?73l$%5 z=8yoy$^RNun*>rfA#%RUFy9mkcC;RJCmdUz;V{ovZ*#+WM$?7Ovhd3Ximu^?xSr^y z97wRNJll@=m7pw_lbI=k9Lr|XH1-KTBu`!zQl`2@-UDQ5U51vu7_t8ni$QOpl~C+n z#~AYke>u?X)p>+S^`8YJF28xQ@|7&)3T4m8uSZ??Y>v8K>3Yk1fapp#hK~{jPsKS;hpaBQfr$gA@i4D9;aT#9Zx;>->+cKO3GitG zaC#eiudm2`v*voItn${@*1L*|^;b)nd_wmtHVyK`Q8#cMCYe1NWY;0jEvKTcBW_UP z*mp2Cf8Ck>-- zf4;|P=8CBQW8{lym%nL5Cfo@SUN+~l3SB%s7B;4aDLp97nC+vwac3}y^bm|e3?MQ5 z-P)$0-(L@R>c;-S8d`6fd5qVb53p`elJ6_zOzK(mJEbH+3OuU@0Yz2@@XLu_ve0N9 z``7GG%SUEE-)FKOD0k{BY?0k>D{j!MR4g{PLmk4C7kKOp6fX4_tgKcSE!u9Wq}XnC zPIjsd#S7;AS{u-uNx%n)oz#BCjtw(tK;P~)UnIAJKK*O#>FaBF&?Enir75fM>Pi$MBZ)P@? z+M{o;&G$)xsm;@J$#QPD!T8`P;8mW&95fdLrhu|T>Accz$4~|V1=zuGn`R9EW1yE2 zTIs@Ggf(0dn0WnF>1LfbP^l>B@2IsmZ{z^zYlHbkv{0Tl4*u-MJut+=%rBIvdq@_f zdGBSnraPj}+v+`fecsNtK88)#Ay>C0Mt~30%f1Esk#iHEgJ9$^zNA3o5`^3*px0v8 zIny%O%Tz88fk~OP2py;XVsXKN((|ZaN{8N*<05yM_V15YQT9Dm+ZG=)>N20a=8 zfy7_6c2-KY)9`s!U(x;iN;jOe-vjvi1LF{hdh&RprD+v)Maru+?Uhu}wI2#j$R7*1 z$5_J_TS8)nYiUJ=tiQj1vH7Z@D}q(Wp<=GL0nKnqDSx{ZMvknw*nxSZetk#|0-Jc` zf~AqT9wOpZVgp(^VC_!*+QQJAovWnym|Rj^9kwvMxXD!No-=dW=E`#6@W4;4dVD{t zqQ5eacqZImQu~&jzmRr)m-r59?YvIKbmmjfSxolDTUgh(*~Xc_llUkSV9-4w3|EeO z8bZ+n`2$&2(FpTriNS@8>1Ey7Wg~{yKe&w4orddFY-Nt1wL%kL+~Y3g(=4XLqkh#c z_T?Y#mw$=+#xd^Ht5TSp(CHn{(1q;U8ZG6{$QW_R)tWPX-6Oc)Yg;ALB-!L{7kSW* znfjd@lK0nozjk- zD=_={%;Do@X$It&os%?jCkKPjN00)pWvgcLUZo%m12YCBzimvAOojFJ!?sewdPc@o zZ+!9(^qrl~WR&pNtqNMnDO<)d_4uU8O3L~CbEDS%ie|y@qrbW2f}8FJ2`3Vj219yN ztefoprXN0|WYij9C^1@8p5ntNZ;Wo7E$bQL*a>Qncpo6oP9f;I$ZbRR?Gk-N#uL6?sh7b-)70)Mw_ zY6K2n)~#F{Pj~y~$Ex8TX-&ozGJi|KByqp{wSDC2S@3A9LJ|V5Fvuqs#Z3 z2`DLXOSe9N7PD#PrG*A$?vaU%27wx1oIC&D7fQimoqq{hRZWZ?8Z0YJKUa%B+45b| zjN2|*DmNX6Bv1H}DTSX0p_45piQ-xzK;Dz*zwxcorW-!r7xLl6Q9}`(N4X|zEv+^y z=3OWa@Kb%$(l0FPPsyS_^X)GKdXPZ?3!2N+jA?k#%T92 zPhJ59(M;qFE0t0Zxv{AhNtj3X&!e*JJJ6-Go_!5{j9i`M5lCp|uz%0gK~H&JzX=V= z`{SmrmpFSUeZ*lO7N~@**%t*a4_+_2Gj6@&XL*p&qGDHY~>=-r?-xiFHXk9_MOkruyWB$Tk>4Sp0{pITjtW2Qm1h`>>U&l zBjk5zM;JiPGAbXJoy*nU-tDM7lu1= ze7EGH3f+BIF6 z3>g0#V8}K5`+yy|!*&<#2DkyZyp*35Op^@@ph!Z$$TN<{x6woN^f`O}q4BZP8@TO( z#}>3}c&ZNItITI){ND%6zyp00Z2%k9Hv$hBh-Z#aHx+h|*->CnK(>(gtA7B#mG}xh zVE7a@calaCT^KWcj@jSGJ59o*=gPk%hPA;k<)<9T(H_LUR15H0?{CNi+G~Y5ve@(! z);pqqKOuZ2hqdGtMWX=6&Zc+K%mgmQ=xipcE_rbd_ZTQOkB6{7jlshDR{*&u zzB_l)$Zg+)0Rv{$?}GFd?G~^8mCSn}%9vq&*1tc9uxHf=)q6iO&dQ*vbtwE9kj|x? z_&SvFf)RGPmXw{%(VT7eu8p?jBn$cz>mB{%k5I2ejL4d;3{m6N3K7aCoYLg~6+QkMtkm=LMYmM%yK=g=8H>i67} zL}RdUr!83TO_(&LR}MJ-9`1kB$e$Slz~<*yVtO<~mKx?5)N?5{ZEnqe1^%{&?s=-1i4YxA`Bd`2asZhP}MY=m@g$ zx2rJiHaHW|M*+C^9-2fCGbHZQd$UJBJj>>lR5R^yQ7~&;#_x53g?5`cqXq{`hA)-H zU;uF~ng$ij7r^l*C-&A`G=}A{M9C-#=!Bk9&!5dZ?@W6-7`${dI~+w5iMvQ=zTq&t;4*-GjYs-ukxtNRT@+k6MYS~b%#-!pGL!Z7;dlL02kovo9t3b2Nxnm15`)^ zvR_TmXgI-f*T=WN9Vi&0_}g7M8oT*{!FgQgw4mva=hakV_S$#Cbn~C4Ag7P3ARue+ zhg_1AeZAqtU9D+p8e4>)Isk$TzQ6aNt+lqt^PH!nPiW#x1$oq(@ulz7KhVSc0L)C~ zAKjwq|4b-6v$0thQr`XA{Iugk%trb^c|X77J4ewqeWx(ph|DY1h7dpdJqBiId%*!5 zD!*v_hW6ql7SCf!I8UH6ZP-aP<#Y-V_&-28j1o!CG+om;)tSFk$_G~SN-Jqx{!5(* zsIw>X(H3K2_B^kIGl3NF(-#?M4BOjd>Z1(RI#T(8M{&pe6s2KD zBg^CwC7d@{4d3+F|D6TqIeT|Ci6;B6MR3aov=YP)emx@#>H$UO|2hu_R5| zlon8PJ_dIHnQaDA)MHZM5JePxxDla)&jjoB(}o<}v$WXt8f~ zqI+p{b>0T=eDaSpPHU%8c@+v&45ao^4{>Haga>`~p+MscLKx2pxXx2^CZCqJ+}-EUzjr*W zH^=J+3A6u!LIOY~TuC=oU*W00VVCymai~3mfen1m%->B@*l+*<+*N@JQ~)r#lA1MU ze*oHMTwQS#ElhF+ZY<|8&6kJ*&)JEQH!r|0vFSbG2cpzG?~zPX zss91LscA49X1ynZ;4ZDLCY$RtW#0`54=a9*Szf&ZnoJByxA({yw@eUteh1C*@E=qmx@gwDM_-RExEq8(pXbPDkb;m1}CT zn$t99Fz8Bv1hnkgF`A7CaEY4xCN8xeOwB05L}UfkD!X;J5@Xug$Y*NE`<}@Is8=#v zKtn;fZ1~|ubTMO=nvvBP+Gda-OwBcRc~8l<7~D_m_bio00dtpbvHA~y-Yo)4HKiuf z6!^k1{i&tWJP2c6zh3wYtII&NO}VcHso-&fLo~n_F-3+?NsUID%IyX9cWDXQMl3k9 z!ZWeA)Ul5j086TVy;-xU(q?<6@a$TUg!1*AAdf3FNDR{jNvop7f7@dqE1o*gh4t<#B1GE6K61OnSG#zmZ%L&iC zl5rK<)N&!CCM|S~6bAaP7PtBg@({qYMZ>uo(Wf94>k9nFOM6`S@2NLn?iXRk`}A^o zA*5Ih|9y@|?|+@hgolO-=lfSI^>%EXVw$eoqDk5Y;B@@kNLoxVX>t?j1xU5D91jl) zP{lmBR+cP~+b@{aVh$n$`RdZY(Q6@)Q*9lBQl?-yb^2)o`i<$nJ22z@dgzT@!PJxY z5&wx~495!hU!>m3%&7^umW04kl5k;tVfry_QPaUxK|K3A?wKdoO=$#W})zCFR;^FwqaH&`#$+Oi>;S1A3+xQCLBTzs_?6SvJfQMNL~o%K^o| z@aO=FScElU4QLLYi=kUL_y9Q8`Fc@dM%eWrFmx=<9o!8IU0R)d1jCF4_2dogHuzvm zn*})Nuv^BCH1qkI#D*H?FLv*Pa-~!x`8*`3W5vURe5-0goKIT~no5N3))0p)OFd^V z3)?fvPE(J6kJ;@1sMxPUVE|`ws3ai(|)Q zG-7Dss^>*eUD)T<3!R+2zLqoYgST{N$ld3q)V1E^q>hUS(AMczG4> z+aD+oCYCEW-o*_5I82kGH}Ho8Z*ypy@Py%S^-!ZeZ1b;n`aSw@(9(;E9v**__&C5& z6C{$>NKOxBcUZLn$4^}D5~W?HwQ1ZD2i(cm$52Z#`Uv_lV~4BaaDn9aesT(`c7LM` z00{!oC=aT#Tw`UG3q^i3YpoGjQKac})K>{g_d}RSCFL zey(3XLNA}D$+{;2Ua8U^0_uOY%;glbzPXD-UHPyP^_VYR*cjOA6eE=c;iC@>aLK!2 zn6-_>3Y=RvbaED2Ar<-tgbFnZiQ{2cD+>X^u;Zq%G*~p-1{`w-FX9tEv3bKLc+2IBS1_viPU7FtxM=Jyv?;I`Ssb zr(-ydN{l;@wqSsXRP3+YUp2QlOC_!d5Z6?YGECJwkpo$5(FGJ| z?CS+;WBn&Ks=hl@t0Y8QKhog!y2?UAau?+sCy0;ffs`3VpP!+6hhseKsF=aLWIG_l z>;c~awf~$O2Qq?AfHG3q=LvveJI*LHF(r}NfOcvTh%yq)a!Y6=uTr7uu0AkPVWS8( zj#TeM+nfm;@1}AE{i!*?q&X|D3bl(l#NBwlqFVYnC zz!A9gKB^L31Ng9Fp+S#SnLDQ5W@oWV`FH~R*8~uxSm8VQs6_6eAG7DUE1+^IwEx!9 z0kEI~>~sWmt8t(uVNyK5n}Q{+$6UYXg#9{KsmRyaEl#l3bOV1%Jc5*(O-rCI4VBcA@!rx@>KVb(+``_KK#d|kYr4rF`Bz5z z5`1(3(OS$)0b0?*(52E>Wn8J;xd1S4cWb#&6=@B!#<^T7v8mzEinqNh#h?|e|bY&J(B=gb@<{zFH?zlk3_7T< zm;yw%4amQs*zpV~EM{KpbgGG>D~qlaxZB@*lj*4id9WWeU-E%?D$;*SQ8oxp6g#&{ zu>ln>d|%i!-rLDc74H;K%C?X4R4|?i4gHj{>#IQ31G+M>a$Qv6HU%HK>8~1ps+YKfW1I`OL(~a6#b9LT5TCV%%Hkv1R4MSQwQdZxZlNItVvrLzKkMJ$IF@a}#_SgFk~Okq$NGC&W1V1T-; z?o;g2<#*^0Pl1M@BMy-btILpZ0Uq!AKim2iT4&d5# z2dH{TS<2lovcX$D6!ELet9D{Iq{5?9v(QnlM0nUOUmeMZ z%3^9oRZhM_InKCfN}FTyAK+&rPR&rdHD9wsJCA0Di`}dMuKzTmy=s0()Q*unQvk|8 zkZOfTI%Saw2a#t(B#1oMi~#+Hdp6fK7-}S?|5nXYyTQ*UPmtu#eK5a-!!H}$J38ga z48tUGrF|M&CK`>7lV^}Xnh8lTH5^T8#C4vbA5*WslRH!Z1${2~nOeOvgi!!hSYDUh z@*Qb4`^S?~K6(kh&w=P_;H8B7haSU&nB6EPp7YPq0$QUlq3s=%PrVYBf4_PHYI^ih z%bz;slNZSH1wq{su&eWwkD3|X04{uaPv_e)R-i2wKff~@h$DO(DJi=EG_y-{C~!dl zrha)>5t5cJ?5vD)Bnpb zQfI)u?@T}V?f|qaw7rBYVlT^zL%UEc!wM`A?C{=>%+OQ`aBKMoZ*#B3$$!&QLUxcES?LUHx{zbaIU0Je@az)^fo63bvQQn-BYLc2e$ zRE9>)nj8iIW|M~`wj5V)3yEHRN)8D)f$||9oWdR>8_l8gP%w=Vsw)I4^In(-ymzmq zs;J{A{WICV=QOy^0dY$%!fyg%Xjm)c;S6VQuz_fE?$66Q@I9iggkN+Ndoc&^bo$*b zM_wHqSY0Xw2UdxoRMhP_Qy$7*Ho)ad`DTUw4ZsvPhs>>=ZM1li8=PLaY|I`BM<^9m1{mQR<# zjDo%Y^;S?em&&ZLJD#Z+PjiGbq71Vm;>y>NoKJNrwWj%I|e_ zUw?vF)%IyB&s6YqT*>$hrO1ExJs>2yGLZs9Z7ks1Yg8C(lliR#`v`o))VsY3KVkI$ z3jA3>Y%Fp8vnRO$-U{kC5+TvKa%yC@4+FM;H#a{h2B2X6D4P=MgWAbbDX5)r>VO4GBe9E@ z86IRE`{{m~ED})^;DoO<+8Qzo(P!XR^`;9iUw{R4o))t*8+^CCH34nv|8e)$e^GVa z|1gZ8gdiv-2o53$Qi{}&qY_Hj&|%Q2bTg=6AP6WRF@S^&Lns0wjX_8ZNJ^u`z>w0- zv(IpO-}m)-y}tjz^CO4Z`>egz+AH2`?R~&yO~BBY2i=7fE3}ZNJEXY!5J&6l+5aRR z>J8;jxq0(dRK8a2>b$FmM3;bGmH!|rq2UyPFNYakKKxrqn9PEWjA|YNZ#oJVL% zJd8`hiYJ8|4>wjIpnJvQY&B^SC#g4WE1(53f~Tq)Q;$wk`HqTSWu!X=sLcO*uJj66jb9;f0K23<3>_Qtv?Hj(nj(_s zo(5`cgUz@M2^i^08Q7IF*g0+d7%YJEs89J2^`=~t#ZAw{bXOcgPG2{N9;&r9tj2^Z zF(I=B6aawIM;2ZtPos@QApW`j5J)qr?Ai1QNQ$qn)k%HN=FhxZ0&0Q-*EBSlP3s8P z-?ZeAdKYw{B9t<%+fQiT4h8bjGi3mBs)rg~%DnwY{K?Z!6-f0Q;xqO+Kpij@1BdQ} zdh_ikcV4Nne+nP@VlV~Ki~5d7AiErT5?D2L9i{6ejSHmOw3P;zMMVSxJy5RTf6QiMc^rCe+FsLVc2t=`%)FU{lq`f!UQPDCmpcQkglwp zFt3xUMTkZ(OoD_vDMD;oNsBTt>c0Va4P@7u52xg(2<(!jk;^eu14^Fj&f$Ctrl6gK z^f*KYpm)Q~^3+nBE2L@jP&)_U#3bWVx!&Kd?pNwyg1;$_=Z!k4a?S_di2!ER zQP)>H;!uokPxwzx{l9UBjtlwd5M;7PL9;?BLdp)MUq{f8n04(YDfIuw8PV56x7{57 zDFwOzRJS-6tq3Hv@0g*w#qv|;ldP+yM6{RtAqFKn%GoPRa#=c1UGHgxlRZg{08n*s zk}owB1`kV#E+qww;F81!UBN@$DFI6RgGMF|iYqR1!{rK;66roff`^j79V@y)T%(uJ zHwJMo9S$BoU{aHUd{TM37Xjzk9uIRhc|l6X$okAiDJFKA69G5AC@gT&t;8VkX? zV%d^9&;r?>f`A8V|GNirSYmGEnXBoH!2I&4MIEM11&{&l)pvqcr~?Z%GoH;sZHfHm&+-8ey7<3q4U`a6{d*;e38s9%Oj`iGZHF#;E`$O44J$ zfd{4*A^2p0wEG3Xrq342BVAbsA|L=^03#gw7s5gE0FqT+ojFAOl0e2H`461V4@w>- z6w2a{t^qBi)#bwoy$9^BtM4L#RZZ0Z*V*9hybAHqK7j;AjRNoz0;5W1^#*u#`~XiT zbI8#2)ZHN;{oWfq?l{bc)qvL)4th#Qiax_nEz!O8yP94Mc!l?`G%ckJY(V{uKnegg ze-UrUHXBa?+iau;<`rmh)IqQ;nIw$=CbgqeF=>INe~O(UW%}ZR(d&=R{wZP2d<-g+ zloXtig8}R`om7NS5xkX`^jA-*&Or4gYLa-VLzz+v0rU}x@-=-L%VCWN!h-l{ppw3S z`zdhMwgJHbBwq*Jh74wFZTUeOhz#9c>Xv#zDU>df0IUWC(-^isSop4EznjXag{V$9M%|e_jQoI zeQjB1cOUW@WYoR)R%^^*Yk9g(JS%=Ch3p(8T;+d#Ch{1Co=%dbS?a*cg16uIcZWy2 z(h8*Kk&NaK>ZpJ^@lbe3htg9WXU%%s-mz`Avtz5_l^1f%@fQhqiFN}Lf&f{{Q&>vG zOo+-X=<(M29G+E4LBk7|7B(pN{CEef>KXIUJz8F!osd3>BgwQqZWvzV7#6u5GB%L6 zeuTly<25IRDNu8lf}Gxq{5ofoXw(Fy$&Z%{!b%TrY8*U#ZP<{NaO}2cHj{{2`fc#a zuLktzJ5Zsk2OnqXUknKDELK#?RSY0lFCcFz!AhAYzjQMeAzs(L2lnLDL*z@?*ZI=d zNw@-Zo}1zOuJa#AsZF{##O_y}NQirIJ6Nf*e6CsPS@fCO47qs^XZ5HQW-TAE3M8}& zNl{qiBJ1SGUsVPwq2jx7|b;fJrIPo_qZ;op!{?VoK$2JO4) z58zBf(n3a+qfJOcz{E1eGmtYtN6kuFV5KKG%4U7a8AM3Id>DZ5SUxz*kd%@46gDLO zF+-_!y+q1KD1d6t`}2XS`ygwf!pZQJjd8=FF_Hm+=R8{}?O|~Dk|v8`4a&SPFXW4x zQ2j-0nOU$WwEuA`7xQmVA1W;Zh{MAbe;9CsY#;;b1Ofn5dVG0BL+{DZ0ja=XvA&a9 zkt7SH3{;9)xau}3a&e_3mgN?ob#!gXx{H8zO%_8%j5hgM{{P%|@xN7nTu`4}8hXL6Z6E;Z2EG(&gdm5zx%)u7+q2+{59kJ^Si*f=<%s`*Izr<@b zlFa-BbQo>e&t&-;#|ReuJoC4Qdm>n#O<`dX$yVopKQJslq~i_nj@RhHO;C+BC?%M!qo?W!$=b6}-upD?%p{R`Sp>Q`)`ez6>x?pjhgDzuqq)4afW zhVJlS6_~YxOu4gu2m)e_PI40C>k?}BZpf87jouVp{QhVd7c~oMDe?zJU?EGvoo!MV z3+m(&!Xn#|!|9*GtBL?cr}i&bi#^{na^PywKi#f&@3%{sCMBszegecXJ^zVgo?ojY ztb!gs)4!d#7fwp|YyZkukZ^+-i>_+|Z~ALup-Qzvj%@C{sWLF*EY%OTNA*Ha?J?nr zUGZX0q~4f|=f*rr&xJ{nioyI@==Paw@tQf6P^ts^LZ^&weM+=YfjBCy3zC4;Kh~I;QF=e;9=P&1Ybl&`O3DRf= zi2Bwj*$TK1DO(3p zb$R!$mz3?-*@H1JRNBi?Ahk4n)7;>z7JB3{ePi8A**kmjm?FQ%!k^3C3v8$E-dXB1O`11Ye!fd5FgHP%JblGUF!pFs-E4cmEBn1f(dAF^U|by`l*;q z039)TIg2DZya63H@819M0(1;e+w?WXA-9)4{V6O37xcf0Uv=ty^yg1(L_C$QSw=1+ ziG(CTLIz4Bgv1UtKti5@%Uzd$QW-o3S>f_4&qrQ{7?;y{La0C~Xhzwt9HZ#N+{Xoxfa+A)4M5}hZTDR6}Zdmy{$nmXaDvt{j1sXx>f;O2reP7i~I*9 z5G_mvJn zM_(YN2G?0{n$N$jaXS3#CGBR4#DS%5%b0p9dhddxo2L1)Vy`Xp+zZRT0#ti3*zHUZk-2jq{PlV z%-sK)xnJ9I+`)O0adXpX;i*^hFuZ1CFf*YO#WBHy8-0BoR5*4ddBMQLsUq?kq{WPu%D}kWo-7 zy|~t0e_v^XV!z$4hB;vU?A(oGZ?%#b7X824aF)kMFt8OM_q2yP)4-v&X=wJ|ZS~$D|<_~mlRDXhHZlx$VpiK{c-JkAw zBYkfS`SGOJVolHixLz7voKXR;%X?U`%G|F^F|4e^jmEy<)g|9qG1mK5SX6I$r}5j# z$m)%eOqKeP$cB@Yn%!(!cXJ+gniE9^HxJsQO%_Bd0|>1ccYG_M#o{}n`iCDYB~;x~;!U645pEj1m_xmY9STOKl`OfZQZwpY?JQMiC2RywP-%*|TRU z*KijzaCdP2_hmyCzUH#nPB<<^0jmL{`UyuC4qQ^x+_|AOC}q3K28J&QrYCn5u;>hH zj~e_jsJ6u?@g{F9E|yu%Jq82dw>}|JsJPZdStGRyFOO&0_4W07#>Uf3y5%$y8=rZM zJfyNHAsYAq{cnGqB+#p`JzjffF|Ojqh$JJgg;gMiZOKvcX$2oY8pexQiBS6ab%G1d zYxnLbf?;Ijv=j#95{jbjq2j|C?7Nc=29YjB0;(Cym`UOgZ%tj2J8>|#TD`fIPDgK=?w-Y;i zmU@B+{;pX!3cHY?J{gE+k{TOfxl#Dm_vAey6+Bu7VmSNN|v5**LdV6UDyH4o7^MJ-MK!8x(Jr&q17 z&;kR)ZC?{WAtw>o{YF8L+bV_IKGxdMLL~uxQH(q}^K2LVpF;Er1Ns0>y*cvGzweMs zAsw9@Q(%tZP6>hZqnA>JT4Bg6YUqF0prKd)&rlOuY)?7F^Ov z_d|cOI$zI>EvGY_`tsbotu3}15@9k$6G~PkBIV=Vlxbd|5DX<~EiHW{ooU)SB)yV;(AHFm|03k>PX7d~kBu8y$bR{_iR@J^JKj4-z&hYDfQ6dm5;6Md zmk^70si!HP)beC`h_cwuobkc4gP8!+Umuw$;T%^I1!RY&Q+m25!5llbOCU8i7D_(_ zXGyc2u&}$$fU}@1efJ(hZCp8Jw-Gl_RPvHssHpow`^UM$k)biUg3O*dHm{_%hdoNb21n^Oolw;hci(s(jSQO zZE!O=co+_bhaXppca84yetxPNqT&Hd$M>0^v{=WOgz}EeC+w@9=_ILEqP5VzZgIky z=C5P&TBRUio&my4DYDPI@b6X1^uipc&b2G+P#QeLUe%@^xDKYRf;d#h(yvCXRC>(tVgpL*mvnG}y9bW<=&$7}$cnXLfdE7oTkV z$;@?JZzHl*UnL8@LD|%Eqde&B^OSW>yKhl1;E%-ycAlOirIUIMN)-kBG)sPK&WGk&2d!78}_lgnfJ`VYUt<*lbX3Q|G{VPvqG zQytXNt23L5ntQ3BCIt-jLXt zuACNq?R}J!qNEC0s5Lc^?DGqVYS$EJvjbe}V%dSH&9^6v?w_$M^RMr<`6GN5%uma% z^9YEFCRpwMCK#q3!Kl<30*#5PLKAIb?DQDdy0jJJ6fJ#Y%zcJSKaA7M=1X0mXY)%x zep*ba@Y8Plo3?~L%K(d1F8PY0Ac?xt($daiyY`0KL5CcxrqelTB8^-=Dc#-OG9m9i znv~ebc+U1}%6QNH{50PtHGIC>-{t(q=mGk9@YLyRTz)oTHu@wTaqPX{}Sh6pudIev(+&k#j0w~2+3J&r_J3^c(LF0;>JX9|&*kvR!z}xIr z!dNYYMuRpmayzXR8II~#_VeD=#OiCwYpP&EYUU~z6=q$2v*?U&4<_pw7)6bAQ4OV{X_k<`PVaV{bow#kNUmG+2;sjZVzE>DCPR*w@R`J-gt3 zo7yyywY9YmTT^=+W%`RpYPP00`hCYEF?m`;2^B%^Go9IDx9ZRhwPx>cg|5`x`L3;= z6;d0#Tx=VWS0BL|v0YrxV%GG*re(tFU|XqKu-T?A-b}^?OF2C8{iRJqYa;$nxNB(~ z6BCotrheTUh8sC#<&KS?UUrqU>WrHo;9$gs%6UEl#;33~1)Q zT{}r2AQI*6@aCr#_i6iYKjzHN&+qQH?!lqN!1XHx5iPHTsk+c3eaUq$n4Im7wVlP< zgcbbRNx36IV8+@K|3Y#9(es_(wB_44L5xLDt;_q*M^6(J^xtYF^VKWYi`jRiH+XnU zHLWXriAuBfe~PXF{!Ud7*=7?%NDVeO${@1n^uQpc@Gdmft<49Q*~|&qA3eb(R5t3J zSK>B0g5WKc)=OB=qm1?M{hosG$SNr@Sg4uRni(i{O3vi+CPz^|_80%mRk^re9`}`& zoT8Hl?A00F?|T{#ErGQ!C*YD76D+nblur%JrVMVPZ1eiMbM+_li`!#X@bX55wZFpo zD7&A&*ASbK1yd>NN# z4Q{Mi-nr5%9FIRMp~lYM+axSCdLEdMS7xr&nhM~PGYy27dG&+89-rmAfbqREJ`uRE zMVOq)QI)05DQ-vffg8;OS}(g##HdQUnBSj7Wh`j)+h;~vgWEnjYePcHr-*qe8(dYu zU(11LO>Piw#+TFQFz{&~McIA(t9J~M=m_*Q-$OUnKLv9!9jE%ITr{ptSvgG1w*y|j zQdo(ZcdcAw$w`-X=(H~X-7JWa>>gk2K9*3qSd(n-`6~=xG14M)P_wh(Q+Tc|FgL|z z7O&d_-RAQ>^M#xc(J**zWUSmS&B2``#KHn2w^a9Vd6yR4v=D`>v@_uR^}I{_WzfcO zU-@S4R!cQ43Nhr@XOY20izOZ>-Vx{-d3qrQ{`idh`uy2wG_6p)(Y2k_9`}it6L|#d~|T1Y(8>Afq&4sy41OH{v%%0Y)vlKsj#|N zAgaRX`Ov+uk;}hcUtXTDN{fz-JxS;))K=Wn@CH^Pe??#p#C)C42VHBwnzZIBbBa-IS+hHY%E=h>Zr9yr&z5Lar}j%H`nQO7DsSXkC$ZS zuZCpn-OWEBn1_e>t?CjMyEAMLtoGHS6t?*hzn8u$TV&%{6nIXs2_(Dp_6hWkxVIE6 zkAOGiy{j7XB|HQ23roI8Om$!WE*7{sAljg}cpZ<}FgN+=Ty7pRT#B#FYb4A4;&KqY zHyNugf)9Go1%pwQTm%WoWkl1A*SPigwh^-qiYu>l_J`_TuYkgc|E$aM=f`K8t2c&* zeN`WWH=HzCnu=aUESM@B9?A-h6l}%Z%$KmduRzE1VB-Scs{xRHjo(+uq zH5$BuN%1E-xKAb4CIoHtH_oWvzI{7Fk;-v|GqCB+a>&6(t^1chjS<_?>-oj__(8W? z&5!J2S@+Xw_t$RvZN{ihOuW=`f0jzj$S=Cv*le5ZGG*?78xb`3>*>Mw;;%=1 z^~R-3<%HA#%*JWg9mm@CgO#(VC5R8!Qghe8Ssh#q*=o7FylxhlHa@e(UeqveCs`sbM8h>(xNR9FSz0Z_dp?cK@k_WR^2eHX+HQ&p} zz6Z&#E`41l=DkChP#=C~Wn?zXByJWU5u*6pcGZuN`f}|wmUy3>7?lvPSlw9O zX2mR}%HezEne0#NgZFUXz&bx|-d@Eo`_2U7bZ%=-?|50X@ zSa>_NbH8>6v%)?5^@RMyZjcisN@_@yke~0M!QK{HHjm|xz%Ibl_kIui&z2fJx31BW z*<$MVpDpMUOvh=5Dr`^lB(6^;WCTA27cPDGqsIl%hHiV#?5?QZG%-m8LYKnlTqP!> ztE(P}q*pW=r0L`e>Z=?-yD-H5daIR5bngxa@cvf7`_Cy3PUGQEfcIy2F0=)1=l8^; zQ`)gVv=xQHolc&vK1OA$wL1#|AbUrB%v1ik(N*hHxcOS~;PG0a`}Zmss!g)=My!NW zO4w`v^?{;BPQp-U$m-?B=09MO#dQI@z~G$_v+~=@<||vwP1E!uJge|Gu%O&o>$8$I z$~fcw^Nl8pLi_XJ0YA52HL3pF4t}dYYMZdS1oa(nr?Wg+mRD@?(HGJJ)lz+TFN1hm z+f(uQ8S2niP%M31niNZ$AADTp)l=Nx%sk`0$>=_inr(EdA|K268Y2J!<771N-)H|#&?A{M+$;rDBc zkODqACJ$~5OydsO{d#sHx(GiWU`S?TsOi7koP-K^yWJ3S|3($!^kT z_bVv7r~X%_4m4Pk6t6V$%%p&owpv8HCHtm(Q z&>Y}XvcjiHq+r?SFjLQAiua^@6%zHF4+ZGYYkpBd`?Gg!9&-d8U0 zKT#jo4gGd$)H^TQv>%!^Y}bVGmVT2cLJOa%e=cR>ww{0`$oZql%GslwItpUDrY1e7 z*zC*>K7z=ZQr9bBcbl^NZGV20$IxPwPfb}?Mn+(DZcowO3*`#~PARn;%fa8A$Waz9 zxCP&>nVdA!6nxo`d$C7czW?#hz({dRjohpDU7raXlPWLLpvq~U#@XOmI2ZGd^`O1{=2TI;F6t!Fhi zX33l}pxbWHkF{&(qcrdVw^kN?*_vEy&U@EvlVCxV^C&1V`bc(v1NDMRda}DKh46`# zcu4pi?44+uwo8pE+h2dXewRWcd3E&|$j})AwU|r!{kJBKvNEd7 zqhuG1{dVSSTY@%57Xuw0`R~unOM1RZAH|UK_)B z-VI_4Z@2p1Nx9u8JT_gLk`6-YxM;(KiAvG6R*AKFzhh^XI1p>E^asua(O~yOq<@|w zrx;)X4os+;mI88L4_kVsC=F1r42*EtJl!5vIh>I?Ww+Hnu@7JTy*r~JsCvJF!yN=U z*23vHzw}fW?~c%8GPKNV`I2j4dJ8BqqGQKwVeLq{BWmq>^}gp!wwTA1kl$`mtvHwV z@P0`557mH+=@n<+;vP8Lrd79FepDh0HK%CmF<;FXOh~b`a~a>3>VpxB+Z8TsjQFJO z&cv!)Zw&i5-T&=pL1<5w(vI4l*TrZ04OCRF#+$jth3t+W@tdhtiM4Z9cN`+tGJ>8P!x+4s}74w@3=n8km2$#j|6qvwr^)hQDtcYPts}ovSsUN zImGDi5Thsk8##T{lt*c{dPGBJj{5*!3l>)Cf!hK3jV%1aJSd5Z3Y&FXVsD8=B1koo z-O5o4yGz$|*pj!NujCchG;E#x4!(FQX)=K&yeTv(_AVL^eppESn)j}HD)8ld)9zfm zqC7k7Xux6+e&6wa{5(r=PXnFQ5dUJ$Mrw-h7izIP->4i$YcSx-MXlu(T2l-DDY4Oh zR&t77$al0Jbsq>J?|HQ5RtS_L%izVbu2qHS)M9&d!N&o$cu}hb>s`F;yby>?jjB>| z%t{QbhO!i>_QubO+^czo+bVA8sn>0-H!VOAEu#=vkL_q3jv`PKEpkJ zT6zAqGdl;qRyae{cW~`2aqexZ-~QOc6W_mINIM@eU!LPp6km}(yBKm%X&x}VhG#X+ zJ#jBDFK=T17#GtTr6F@0&QDeyv{&3EHq2de(F1|5kijkcHR`$2hG#|OnvDe4j7Pao-+tU|Vuu;dLT>}Q zo6LGd%;GB-;=#9rf0&G62Umv@{6+6?F&i}z(heHS zGnIus@d~pVx?w-97HVsAU^r7Yh5gM_%X1#>h_k~0a#TClYHV{(h;^4ir~>hf+D!$lc2=6b`y?<|R~3CFm6 zI|Sx%3EN+qu4pN0hSPCO?S`yv5HO0(<&##`-K=)Ggj!sJ|Kj}(`Hf}(QluP==4iW} zmT-LKEMa|P{7pGb;^(M9i7m*gv{Vg|sKDUVr|for#1puUXqmj!Q!Bb_3KF)JtF6Cl zcLKan?y)%Qy>(@>P$WQp&qp75n-y~js-CpGynr*uC>|UW5SZcPl<~CpV#%w2Zc0J< zM|gu+)%^e;Bp01_mb3I=uHPf;ZX>;(sVOmsdL2{@G|Amjr-a_NeV-Zn_430$ituLP z914->ckHR)#F|{sv2>z$FlySsC*|lLy%mGf+|(}IfXlx7L3LrFrR1>ZOTHJ!4GtuI z7UTf170V^>Pw|6u010OVa5$#}Im)NV&gqXhWAT%h0P!}UnWngLF*GpM(-`PY4*~t2 z1A^;gfa_-TjC#zS<3VBV1L4Se|6rD0MXG-X$I{#pvt?&JB3C3CX+0a=>ST zAHt7=RvvQkppotn4%!g^@6rc{E|QKNO{#tTw+`_R%W6AgFqIFjYy}idRvNOhxnlkW z@`F(G>TDMmSkJ8@z$4?pq!=Gen90P%83w@DOV`lm5_i}>ct1$Nt9?5P@$B4T1>;-} z*#&@bL)j!XLx}1Pf~8PvCt@K*0?Y*E(#QS{=Kuezv;t~A_CchAh7c4jL}*`GE-bzj zk&%CghT_#U|0=;0kkwq#_X-+VWWkJ=c5Kx8ry+}1P6cJ`3(}*dC zln2OkiVWe>DE$MVtVlRiMtqBAFHs=X7zd9v|pdeYh^7wIV4aXFoY+Z+v!5n zOumvccrVp?J)rpl>3r@q_w=A`q6l`+AD>5_3-w=wFynX=9`K_H9H$5R->UP!RWo4Y ze|J5vniXn2cY%P0CSe3a7{5lBo|^D9JSPd>OL0z*^6irKJOu(1_k<4GV@fon!k>~BxfTr|bqUIp_M@Wl)yA*0 zJ%$iYfH3i0mNM&!I6WD$FQ-p;uTJqFQ<2JGMUKTZ?!(%@gU z+1?AXdQyuPCdJzqvz^}~}6om;! zw*ZZ`;ewv7(*RX^&iQXcL=OsPu9x%ockh_!>(9)jKyZejb`LYw(h?H9Z)IM2+$b%} zAjDEGs5*V!!+F_?ycTF^oWLXSs-MD;A_e~+Me2Y#u5CJHd2f59w&%2vTjiG(Bn)m` z@wqr1@Se#nD28zN12U}zzeeKLrF<@vW7jG0)lcx|( zFTO;(KV347LZ_@>toMcp_&@>n?0cBwd}~6s|IlPAZ^Y5mb74ocTt5W0C2X`19X2Gk zWKs5Q>tTBJgO+@hleK>Woh6|{I)l9luv?c_MaJxaTKI3+K-Rs^09d>37>5DT|Fa2< z$xHorQF^j_l2v{p?Xzoys0nR!U0ueFeaVMlq11V zDENx!TM=Z!&l+H@uJ z0;)k=qU@Gf`|!IU$Xavlnl@?LQqF|h63t%8LFNQCLePGymn_L=FxZ;`HoRXINv{UH zt{(pYg+aI8gWa(-X6+gIZ-)fYy1zVNwpd+d>c8)xzT;QE-96ks%Uoc&-6#pk!xY$o z^93rw_`!CdxobRa3gGGgvynguG!mqS44izBkf#kgQRIW5-jYtJ_rk%uQ+|U~n_qbH z9@?-BksvaQ^e9vXaVfKP2qY^l;ECz;(Krv<+JI7Q#TSEWB1^Ccu_Z(7-MO{pN!^8| zd$hHfQ*o9&XtW<>oh=vJ=3~-;xpQ3b?Ysg_kw;ceL|q)2Z<_JlL&!j{Nq|J6k7Q=V zh*s*f1I((k)o6u~QOF+f+kdd+Xmi4idWjxs5#ZCIJUP~T;dbhab+A-A4{3W2Ad@E= zX!FSDGC4)^5Q_$ca-?DmO%Lm|TX!JZp|4z9|e~2P&u{go;)!nZowYmiQDlU0F zbV^Qfbxd^G8|>(S6SaebgYP{=szdTP4p~T`yxvnSdh!eIqdCc2yONkZ?H=-ovT6;Q z=8*B7pZ(r}zu$$#T|a?Pa-1bj^cY#ieLW%D+HV8ubjz*9?P}nL{p`1IRp`$k^dtcS zAl6^s&C1W$=>D>}ELa%bB2sOzyu4f`-VSXv^nHl=<^;Nh=(I2sc8?y; zYhGq!7CxiGL?Xb``oE3EWIKW1kx_P^2mMF>^ZXx6_vb+u2mmL%@W+xtyxI}X zDj-W;A_DnTS*T{&J+Qqo`>qy%DgHMl2kd!r`9*z1#2t-`RkY-OQOF)mB(=B+Qvs7b zM%f+Ce8pz%8%Op+;|uu{QT`;Vx8!}|GYV90?%*d=Uu0JP%DVY-;-$7i3@{Q}w>^77 zB|XnblyDl$DeL_zV4>Pb3$bNAGgMyud~cd(3n&;yd!l=?=C4x1zBQ~w-MejMA->w(rQHI-zW~Z$u<>py z?Q71>N%F) z!%bwqP;gIu*a2$)r}tW~xc_|fnAFL5PuGfnZII`Mvz+Q$mE>Bs-os;b&Hf{#)af;U z-8In^-S0NH0!6ZMyxeu53N{b?mf4;HT$o3UbjN*`zR<9>lLtGebUdU3mg*i8~52e(Y>8{}ns@ ztGiJO1HHfAjzZ=y6H4l=;W>Sg`ew7E&CP0CvoEz}M#=T8tQMK{e16_O_Ah8()v zUhnWBS*|0MA8gmOQ%eSzUEn~V0+iJou~nV(^7CI+Aj1gThj7ya-Oe(* zXb=ud1g$*20%i&zVK`C$j(Y$U=%xMP_LgU^)oxg~kyc#zBS|B zRkXaN5#hr)1xs&aR`5vGhkHs*}0YKd#;qd{s(B~_^DLf}rXNnCn z-XO36ovuAqe==1eAvpuLaMJ98u-qluE40TVMWDIK0qj8zSLvWYaFUBXhJb?OhZ+1) zdN|2F|2_%wjZfS5W3UL&QW1wi&PB^{Lvf31C zlm?B?P-pfEKAx1HP*L!W9lhbA8RlFj!j6oFh5Z0vA@*G+5|PGZU@hW z0t@+*)Yaks@2um0yKliv7A^()$ocNvQBuWrO0q5#KF8khJM<(rnOIU2rm6-sAeVR5H)B)h9r zcoco(6vRp!;NRtssAvsdFY;K(4TOfl$!_KM0kj-D&~dk={`^N{vXvGM7k zP`n;f_&6LYFXgvGf`~;H=#8aknXfH2rb2VOfVnMrz}ym+t1J+E zQAnvAGk}8+vKc(Vf)9s*@DEpEYM5`#&Efn$w1jZlw>;|94kSJm>UwVa zq!w&`;O0n3EnICc)yN0~I!lZG5cO-27cUGqV1@~Kpt$MVsrL6o!by-i#fCZ#Xu1zH z-_Gn3hO%^8iVswqtuvsii4sCZ$b0ePD&nm6bPozrU*PsNDI@*M4_c7ix028o*A-Vr zluS%4PTlO2VP5?ZpDCsMHp@$YqqhnvVsxRE)N=g zw_33`1VZ|xN?ze_g2=*#+4di8OaR+C!-}zt>5?&ZcKQI&yXEPQvQHEbnq~}Xv97w^ z)p1vuHHNR@w%yhm=@LJY0ds6gX~}*?c}m!H!D}VuZB%^pt^Hb`%**_h_>c zl?_lDsCxa4-XPb}6ShiXtacNQm)@3~d;yI33t83D>yXz>F(vXMTo!-+So!BfMla>= zlxH$!ck4MvTkf9fP0_Ib3 z*oBb1gKXcVh~@2_iU?qxjEzhq41v+;P0s8G@bDS=yGE8`q%N1H)_JrdPonJ_*&{Kg}z=g=n&a z*pyFj3ZzbWyN(!6p)ChUX+QQc(zk9Nbvj^ose|j-UF(aC>cBGjmVqdP$Z? z(OkJjNWb&=!haAfs@EVaNs^OUrGqAf&%-7>2kgiQXR|;^4wrCfp$VlP#U~VBobBMUE{UAw=0`3c-st6e^u${zMp>zf~Wg~Qoq>uA-A}4q^bg<-f zEV74ankW_&s*zldoD#KMnBlLMoI7`^dR9b?*V-C z(Q9J5j2cX($ws-&Pzk1zN!%LO)?)O!J*j3=nCr2PGI%Y@;XTWr&5KcD)@})K zg>ybzzPosZlSI;Au;z``p^%T$L2r#+GmfAa|7 zrr~z#Er)+iTtsRSE;jAoWKBmWtujvS2GTOXYi52jLd+ryT?05iA0@;IaQ22Kx@#(m zPX5YuGz@oo94UI7364B|h6&v73Ax4spw;soKkk#pF#*dbz-Fy=`2sl&7JvXAv6NKN z=U<3`t0cj18A^e@D3xwJ6i{6yKyHSg33mwq)q+X^0pOIc9K4A7@U>hZ8hN4POd1F! z^An!Or_Xd=1oIlwv0@_i&}2{blJAm0!}GvlYi?6{1e55Mq>b*9e8Cm;;u;#}$kcr1 zs~S1%8)TMA{|yHaT{!*mVJKK-Kq8fz9NvQOGtmO22#0roOKrY%A95Hj4b(?k-SqHx zp!DG`W3M})o&;1lE0UjZ>NOepNj6?O();0cal)-6#)0^P<<_3l(pZNC4+VcZIGW@6 zMF|`_3O`X0&Bcq+m^&AAIAI-4sB)a3P3xo6T2`u2Y}U$YGv^Q2?Z60BU92<3P6X(P z$B(E^?>;^2ss+{Hkac3S`%$Lf{Jd zA^SZjn;bkE!&4J^k>ox3f6}FnQd=t=LCKdzioO)Hzc)=o;ubS(0VRC#dQO}1*lMDn zP63;Y32f)JpQzk#ld-zQ+bfr^v{>`n(gfwi&vM_e?L9BF>%I=iUbDex_`OZ@Ql-Za)C z&0=Y1wa9z$f3o^WBz->#&v_}4nxg3mv>>y1>P9?uNl8b`agJx$csl-Jl1HGjfUkUQ zn6j$5K`!ALObhcr?`2iTWH&|r%h0@e)x?I^H^>NY?b=?d}`~919IlCDF0Z#Nl+@@xQ z=bTcgOR+o;NaVRa1(&4pHJSFKKF86HQGkL=kXE7UoLKz7quw=I%N`QPu*8Sd3h=li zNbv!X*T(m)Hpj4T_FB6WJewu<6oi97b<^#0G;8KdVR3@>Egqk%ryS1}k&2Gszvo!s zIXp)R_nty#b(4FFVvlB8Xm#iuPA1$?ANRKxpm*sFb7yAO%h9hN&K?rmKx-Ww@h;(a zt_(NET!ITt4^)%q@0}bqX>#wIUa6><<2zfC5I!w`58LwXL(M-AXbY>ue-WS#$ zYZ842o>OW)-nx@J-4Mw`(i{rG=yHAzV_m)@E$Ts>@ILc3FP+2U9TNTvc!Dp-UUywl z0TW%mepOZD6xE$Ks*F7)y4g_ui3}zKN^#BImmfBvFg3-(hYY?6wBe<~mz1=dKpQmK z>9+5@Lh8`UKf|if31UbQ#}YroM8{iw%iDoO)ea##Tsg$ZCwvp8wW_sa0+ z5aZ2M(t=5Bd@TY_S1DXu70m@yy_EToVuXi*PFaDBDY^6FBn@ErfHaN}qrq~YIMYT_ z+N^8n6s`J89UG*qlj$5y72la&~qGy2E|N060hLKY@dg;bIqg zs3Ap$@w75?_;ImAX$Vs*C0^H^xR?p0X~3Ao0$+4Kl8Bz?+1^+YBlqZu`O^a1_hOFABqA=*libwWVTZ6l9WU%mlv4zuk3WzTTMf+Wx< zSK(1ZPsNPx!Y88-IY9w9aZKgrb&#+BweQGo+G^=*Vh(p3wjk93^~WcIZW;KVxs%RN z$_<#}2YBFj_u2~v9U!B`V^k&Q7#gpM7QVMWNg9xK9ga_V%45`Z8J7apkI+axu$Zjp z=Ls=NfU=usP_rq=B_rxDSlitcg4sD$@Dr85nc|!Glu)}PDIn{@e7lVDC zB(Jb4q7o|2>VN;S-Sat8!wwQoL4L}e7jI4%`ihUl5C$p@bPE0R*l-3aO`x9kCF0JN z$RS$!Q`frJFJ~Q)7JTmQ#Lc1dX7j^{rcMdC>~Fenw5jq%k>qhEp-4d(pU|oXwLTvy zN+=^DN>+CEky&>3R#pgc9I|OiG9r8LW6R7qC}nSsy~;jjIQF=nFTLNN>-t{* z!S{B%e$=gV&T~ATk9mLG9|X|CnXlpvY&Cr`4k1W+bABAm;qo9}`p9e^18%amIe1Fp zu6h5%p7NI=FRwpcP(Hi=7B9(StA@T z67l1wvCvDB<*VoS@|v)9nSg>PC;An*mmsERYQ4q&xnz=&vcttfN9Ss1j>p_nDmFg9 zx&!LJf%Y>BKC`OuBEY{5QX4lJ4{7rK+sGsbnnZ>IW@n(KT_k+bN*IX{dZ+bX>pax> zpy8hwN|_*gi!uWEis9zAL%w(ew4TCmOHRuC1)!_wq%C2iQ0dXxR*b)St_DVck24M> zp8{~;{`om6pUXGCf0xYtwDb14-XKwI%w{OLrPp+W&G6hL|BojXc^8~mP)55bA&Ys( z!=7x7%a-QP&u^yjO6&27wDRu%lx@x8oPK^TX~4>)mGs|* zeFa)5Br4@i0+;#t!!VY-wz8ml=q$gJj(h_agKlDf;QaLcN5L~1ot51HBnrSaD`q%i zGi|Jd<_+MYDhRtu@M$YUnpYMHQgtcsyR%BmFO$a2$XC zdEt!N9OyQOSyZ3R{}FDz;DwB3o7}u0NK^O09vOfSsO|{P&q0r95Imw>Mo%?~cR+-+ z9xNr6iUi!grjbCasjMv4R+2_Nbz$UO2{7vhKq2vu_9!)`|HKQ=*3^rL)gKovU>i@* z&mFV{@tByX%jM(fUf-V2 zd#CmBJQ+$t0OXAL!y_#ceHL&&5drB5ePp*CfbA4I6#aPx+O0I~kukJe0jl$SH2i<- zjJH5%2zgtCn&-m%FQV+O1Ajv7#mPbZt?~kjaSU44;E+AYzeG@?5z8$K#5C%u_CFhsQiu_#iBgY_=Y6CJrU4PE7|r z8W)<@<0Ofay1_%OH?PCN_X^jieJ54}Yh2VPt&N;KR7W~;xXDOcg3 z+iwO0DIIR;OPg~`FYx$;T5HhhrHZQB(Y22oc)7fwug*~ z(Z)i~$$iiVAavYZIYe3kU_Ae$3T+LSvX(<+m?PgPKo@<1pntbkM75f(aVM1&`cObD z&>peG{!OgrvEU?{h~BQpvW8c_GaZ{^jujYK0$MjylR2aTF%X?^n>d^ZRm{Tyd50JW zYnul%Wg^(j43{m(Q<$ysQr6#)hd;8pb3pt-Lz0PecK~(I*UL(@=e8i8G<@JqEJ)-6 zn@FggO$bgr6PXq>By#DP8PZ~!VEVZG3qyp^M~`28&~8AZ26K+QLMT9*biPQB%7k3; zu@5d%0i>B8X)y~TmjhIp>7ba6pMXZE=!>lYZ95RlC;x&&r6l!ugb?yg7b#?jqrq>p z%#~Y3Mz1UIfC~h~6wiaw$ z3?%0(s6G}ukEwcrY!+uR=NzQLQyrj7p#+!0441o`zBLP3;yL!l^cP7?)$!xT&z#Or zcLrR$i`c$_eDEV`;B60np09JEF;Aw( zDG(u{zJ}?*%4oTehvF+OkDbrPJ4jJZk9B!*@0d)@622f2!jm3K)x#zQV`@HccFJ#% zB}#4odZJ6tm;?~k9|-tqt?)V9EzLb_Mc8#5uWoGPGHOGi49E?6b|b`8P8z{WNw*%)2M;&(xIDlLnV%GWkK{ zoe@yYiMSoUBM|O@b_U$6S486Gz*+3eF9ORbNyI~>{LhOseKc3IL zW_=&n_oBezi5z5X0H_5I_Q>oD$1@jeHK!qZ zQ5h|e-BI%iWkmTu>anq3`x)WMi7!70&*2Zb>7c8yX=ElNxBMAbj*9Z{Q ziUAT&cw;e$IrMn;Pa^70$xVZ4R6!hRcSzDF-2)Tm+KKR`$Cuac8HfTgR^yWZ!INZG zJ?^ATSLmZkU%}50&D`-hv5yu;lNte^aO6ihQ(WWH9(#KM6DO;9ateOdEqMP<_OBiW zb0%i`uf4k-hrHQb6Rv8Gx(_g@G=G)T-%r{V>ecAPV*1%N4y=exYaasiLV6OWl_M2>Fy zCqb(s$mp1d!wvmXKIapuKCC%+g?sbBve)OpF4sqT1$@Ar9a^tGMO`41+$Lf#bh7TG zC-npu;*to;`SpD6%L&F9(Z1gBl1GS4=#iE6^9>mrM0qmWfWcZqSD#@z!m$# z_PPGRt0^mbS8!-fOUFKsVx9q~rZV}_{71Vu{*#vGhG~$me^G5q!O__h!xUW*o-5${ z1sh*e5N&%*z|-YqSE@z=!Nf8M`%jO8jfFft`$eH&#sQCEd>Ze^p$JZz)jga$d6n z$v4CEbqWg4_qCz;=d`{BhaWlcw1;m@F|`_~{{^{c1f|?NgF&GqHN`tC=roC~=EZK0 zm}u7si@j0Zn;x^$rLRWwnqgQ~^{}Y-ofqxi_s0>h-8S=k!QtfNQTxY)(_)jr{Og-4#UpTWGkV$7OViitU$Fl?Kb7DOYlW-PU zgBX$44vQS&-6k}w!lT9Um7U70S#G|D`|&7yX;Y)rlkjQNY&A1xCe?V34!y!|PpNAf z!&m<<+*#3n3Xb!GzW=oH%A3giE9ws~Ll949_+M=Z&`qcR;v*bFQQ`w$DglBzq7T@$ zGN;z@5w3_3IYE zWQdfusSGrASoi97g0_c^a9TZ*liH8PXvNPOYO>Wpz{E4#5SM~G_8_ubk*j;uF6IMu zSHP~$?1hLZxnL5gjQ*3+0(r&l+c{{_uhcLZVByFgN4PzMz|PEK`N=+p+Tpw%x;o0u zzw#V}Rq-kuJf^q^`2=k7LGLH{s!w|dGDV(M&mf%cg#dGKz8ipn-kq~jj+q2n>fQeL zS74gNA5tO#C6`Hvi0Wtv#CLa0x_Knu6Jm_ne)cb*p8%hfly))f2`;?Sssl_!(d$(w zK$iNfQ)6!8%9O;siV{BXB2}2T_uBvED5(?-Kq)BupHHI=oZxyv(L$%@n&}(?iSNoah5?NyZMSNX+1L_k{qfLZD;Sn{x}+h85wV~kpw#DVOy{bKgBLA8 z`7g-TZ~&S5>MqLv)B^QD3bE+=I6dcmukTMh4kt;Qch!-ro05U;>{gSX)-!^VGCtV- zLG|7t=%g{%j6T{A&#$KMKhF)oJAfTn7kHD{JsD0z*$b)@c^SVdo5?0N2d`%wz50Ho zDP%pR4f;H&zl#ubUNzUGnRpcr5gDEb#31r;5&ISg45!T_WfDs&;K2ege%0f~IrZP) ze5Chs<*o?1%NoL&mw^xan(-;9gR2`t0aHK784`=*w=SDY+L8xU0$a;3ef5s{pQdt- zWFnESyXi#G7v5I&mp6F8`nc%*?BjgM9~}eo{Zb(@@p4O)?v>}jQ;!n;tb`Z&&~hM| z&1K}K5nI1#QDi$;dNi;TPh~m(U@x|SRD&$Rf2%)eP^gD|dHzhBwk4wK_)pGrT#zt+ zgT8mZZTY2-Eh8S#&QTuW`gm0JQQ@5GO$nygG@Ht@tO#CEf!%j~_?+MO0C5d6qPF1h z1X&-eDb99k_Cuv*v_;BC0ll8LaX__xJEQ;gD4$ae12mfm#|q7_TUuV1Kwt}kXodg< zpsD-Rh+KpWokF4P^$0i)Me)~juH{n<+$KP84hT)tVfy^*J|9y zaZyja2fS@%nQZ@-a|V|4Hw;e_(pV~>CNax&!$s_rFO|3rsx&2jol}9)y!zY3p%x74 zs29Ik#giHOv)J{fmj{A8DOYN+EhZ3sBO0 z2JiVBzD_SxuYXTb$xX5GWk6>N4%FqmpMLp0JMR`|Tw$5I#16D_I7lrdv6`#YMh@_O zN9fywt2GqRb``Y4gWb0KYaR;X^y`X-G61OW+pNkMw|c^&S4RI8s?wT+QmVrSNyNZz zD5GQ;NQ~PFb~F5X2hfk;s!P8HC?PP=e0iIQ$88M=2dj&2XUmoCr~XTdCT0`<3xhG zBK)XG;X_v%B(c|l#9r^km$)s;$jq*q1yzafy^o9BVM&#GcQpKE^ofz)^q+;iS7RBO zRC;`#-vwXLPfgqqW_BgUqktL9tmCz9sQzDw3XCs48y?qamPv3qQK7B??k z4g(SmTuL?KOLPdtoNFh3%~x-V4l6q8RPO*7p6v#SVc{B? z86^@ys@CHz(!G?y4HFz9x9E7$su6+pZr#c5lY=R&z{XzHN6f~swwOF%TV zLah$s3WGh&oki@t6g}p|2B~9b@i*H@aZ#FM>bCu=Xu>Pd)b6@h@pAdz;$tnGOR=!d znd)!BDZY!dOLKPD^U5K;OaMSE#7=gy!E@#08FEajlwi$2?)DOA5XAdkY{BFxkgLxm z+4|c1%@C)`aO3SQa+ifWAg+v8Q~Q9gb&cnG%zrV+5KcNd!noJ($av7p5@4ZH#Qsu4 zG;5IT6-Rm2O%9n0bFQz6%HC<+%88V$Pc(T6-a2^ASp=k(zR*vQ(v1kKv6b~k8LYO~ z@$)cVwNB3RLY9z+89rYY77@_N*oZpx!PaX(HKta}3G4O+0D2cA{Wb_}H->!`_YLYmeiaAqK;Ex-%3=3!0+Dne)aljPOgC8c=^*?-SDIsKKYO=U4W&5 zxIL|}|K&xX?y}9pMSn#T)+f};0fd-(c8}SgV3bqwdg&Ssy>i3Uq|aK98qkxq@C6p$ zc9uLZ<07#xpG&s4L;=Xgr8z?2Q8C=OI^NW|n;~Ecyz-?2(I@=CzhFlgi{^8|sOpn= z&rV&6xC|=q-N|1!5pUnc_w49BMZ4GqCV_~$0lv*?1<((h)3Je)0%0QF&k3iQH@<&T zjo^hBvHN`zZJHx{X(PYY5-Xqr;`F4cuZx{;fZ?V~WaBnqN&PYVhBvzdJ5~etGzRWm zt>Zupiyd>k;A?;BfKHo=-28`4TX-=wc6x_8S$qQXP%e0CZ~rP|CF}gI)>P0%%}a2)iOF$D9CYyqm#%9FXb(!Z^m&Qdtr;U=i8(>r_h#3WX_uP%8A0>Wv-e19wv z(f2D|{w`l;2&As>p^uO9MZXJ;C@7CRjViiLx|Jz~{*nRB#*O4xr30?In!UE;{XiX> zQT1Oez`JMqdMOe4G9mnHpr~G?0E+4_sPA*@y=j#*YWbnw&}Iv{x1iSP0O?bD(DOH@ z1y~UktzTK5`q9IeSYbVA=||Q)s80mxbp>*lr+k!dxBOuyA>c^;!MYu0C(iM1(3tiU zs4BN%m~D6*egOz&b6Pi_0~PoYMAyUdW5hDAXj1Uaqj+YJ|G9s0=esN3WMa1=9NCnS zmL|i0CdixaqLa6*#X5Q7HG}D~#9+siD8*=~TOT!y-TDXJq;5U_se0lLnxztson_gE zXJbqJc*t6q$xw57q-6n8pz>U_0HMvO?+fW6+8Q%Mb?g`A)p8tuMtaoGx$?I}m9?8N z$3Ps_@i%TFk;o@nTC>JMhB_vbujK94C&84AAJizP=i$y~J&~xJqxm=4s!#l-ekWfm zWThTSAEdV+s*DkqMt} zW2SM|E38j^_`p=*NI%G8j!k?`vsob7Zv%+k!NWsO&0hmn9WfpKS;|=e+T8zDmKf0; zpA3Z%Bm^uauiCDHzNg4*G}n|gH9u=9>6{~Eiv_2^AHq!7eY+mc6gYR9aU;|jQv7^L8-^tX=P3Czq~dV3^cg#+pHUNEDv>Y zMAOjH0&2cAEjiVG9n?n|cbR2JX_ueO)7u};w*-A*6wG-s&vD2gh`~IkZTSM9EmTh` zfdj-U1mU(x9s-!~{`rn9W?uCg_YFrpJd^Vr2cR>*h&u4_=*G}u?X-2|boA0|s;~=B=s2eIUTVaETgVMGRFHI`1`vK> zz|4$Sm>ihnIIUOZ3Rpmq&qts--hCtUwg|RT?_U=U26~wRJF)Z4@$@1PtsA$mPOa>9 zufPPr=~U-QEBph#{Vo#3y@vkAqUB z1`q{!VXpHhu;vQyk5J=( z@tn{i4J4#>s6KUpEK9&!sBsF=StF4Z1^U$yoElX8q7TTys#CcG7V!S~e%9_UhU>5c zELeLisQ^PVfO|mC@t*V>C>r!6NN?4tdX=Y*I4Et}`P6=B6K?=#%NdZMdH{G&AjV)d zEx79V>Wnw^TfzkY7jb#wzR|u(L?;XOUy>klTm72G!Pj%t#U?AI8=!4dH>!E_Lp^2S z8wKH@V5rz4lyMgM64vN9?0&EP#RstGp;3H&`^e6$^496=`FaRA?JckZ$6a47b z5lOk5ydb;_K#=G z&=rFc({lGHb&IT}T$-JP}Ckn8JvR$Cv5$Y@(SVk;}(D4=+ zFRx;yE9VU^QwZ7z&ACk2b)fpyp?$!h7Nk`1uQyq? zu{Wz&uW48?UcC&JO7-u6H7p!Hzp=tByAIl#!vk!gpzXf)IdKJ@*aufAq4Gf%^bGx3 zG8=4hO?meiPsq;Wyk-2hEb}MhdF;TlB21FU=Sa78^LLZv z`sd`XWUo_?<-xC!5ItPT9kk2*W2i3_Ojpz*7=x&4%Hh_g(CWA|rgkJ$J28MSxg(gj z{&wwpO+Fx7^W!AW&dYlY1~O#&9PI|+8nO~8W*-C~W8YuprF1O<9nHU0Zd^qD{-%Jj z8xfWC0KJmK4N{*0`(`52Li-Kf4`)EcWC3wWLZqc4mEB%%DO0)ap8%>U&QxCs+iaBd zsHr#w2Q99pd^jh?_ukp*F~Xq!MfJ|cv{~h}uXrvBb-yq{&2M-7ECwRnsx}`yNIu$w zC{`)9{hlMdkljK;Li|sE{1mPlFZb3OU8Zda2WG+paKq78>5yeckUzEr-KU@N@QKPt zn~x8+=bI>6T0dNA%F-(~P3~bGf8WC3l?Zz0WF7056>J9lPFKua+5oqDM(AN7gZt{& zQMbkED@t{Mx8(NC*@ipM?SLH#aU?oy)4|mKht8d2{6$&Ci|YC4738aft@*8HdZ)*W zJV{n(C%Xe;X-@SAx`1EPvU>A}bo-RoT2@6dDZQSqZu`?frr+Nte8&p|khvb+fyl&0 zF%{V$S`sn6Y9HxD4k`t_sKm=Q1%`GQbu}-Ov)z?p^}#>{;Djue5b!Mj5*4N3{tWNt z@>=Q(LyAa;YONhDgs05mExesr;op;;J5#q7-B7th(ON1JpS7dsl%z)HjtqxvMaAzIW}gv zJX&TmJH1vuz&i){i(@ePdL3tLWyJ&U?->qZFhOI!qor2qub1NUiz7-)OKEzPsSD0t z{g!u`L=Lxyim%QbOq4l{ct6c*-U76Bk+PRX_1~|RDpyWcoSp31B(s73U1mLe`;M=& z#!#!79#e)?QLVmCi_qFdZ5N^V(V07XIz8(RXLwMDXDJ{aZbuHAmYLd^`K$?PIxQUS zEOV<%oPHZ>8!?6JFtwU)K0piXl*u9nMm(6)ux+inx!?+DVitT8OhlE-(7dwhy4h_VuY!3az5LdEN zNVFa-BD$q&+a_bhGOl69h6-6BhEk|cbJ_K4mqP-rhDR6}B!eMeo^#Cv9ZC{9!RQy~ z#2ngGrWVqNN<8Qte$lNDta8+pP_gEoxtZsImF@HA;cqTW^uBczUVf8u!PfWc(Q0kV zCHl%>h;iB>dHVlDS)W%cYu~WXt`WB=vQ|lb?2k5%y{wCz-`5ywR{9wax5@!=-s#0IHC8f6u$^ebF zC=kJ%LGWF4)eD4!C84vGUPGgcO3PpV*I4qs%@r@d8fXWQo7~7X3NuDFvut$)wi<%V#}Q+o4H@K$uZ=@Bg`w|d7N5z)DrIo z({Q^Kl`?=4JDx|VcZ0)beyoUv&gc+NT*TR^n-QQobebrtsWGfS*)>`ecBfuQ@jZ;& zcB)-1Ma&9sFLXuP4rD(vF+pFtDWT-Kw?4V=bPw(}?I0q$QHQWv=rrKB-MYOzg|0=g z*_fJ|4k0w?0X9=-P5QW%bqn-Kx2+VT?}656<6?DgY7GGs?OR5ZGzXJ=)8gH4e0R%e zdR72q@aN+C!^e+1+AYT&DnEnS0$m1;HC3Cn4tXXzHwuVf^gcnUzTTa6n{d_0f}F^~3Zi+ei(#Gzk46EpPgTWo`N z`}W_83>*+4p-Pf45)HF6x{*O=3poEhldEd-pAD#rICQd9OcofFSpp9`@>sK~Id_ke z-l^{E_9+})%Bb!jfW&IsFd-E~+gl9EtUHpu)_)rZCrDdPiaOd+$)3A?=>gqN3AT$}#1~Sk+Ds zqNMzF3#)&4Fo`Bv=;(RO~7*hdvlNNxGs7$XGaOx%6iS z$)b3;2<$7zbj8tCC%}_95rr#aWsGN2buimX$ znSZyKg4n9c8jdmZnJ;jzMXud5a;S(ZGr49z-dPU@f+8I-2cEeIRIQzkg92I|B66M& zYLMdKZ8&zBuiKRju_;yp+_+id-m-EGcVs*!Kk1;To=I^sq|nYLZ$0z$TQO(}uH@b|^*x}jJ_!|{ zn*b#3W~ZfV`6N1gs~%{PoC*C?7L0-h%DYydsi$~QN2=BJ6|zu=6>4Xx%=TT zK*I@z*>0HN)qF`S?>^;RYwUhPp6#+6F{> z|Cv=$Y&P#A3X27V`Fs}5V)8=B1TmEqpGdMU zgobL*!$slajx+B##0Q`!Om6zlX||YF2Bv3&vor+gLGt)``D;Q=pn=`51tjo ze=x#lk+gRq#ryD4B+RbzlV*ru4==9FtM_|gDDMOewQkzb~F1(6nYcBd=F39dy@`g~eL=NwYHqYJu>OI)m8RF#-ItJ}-}DHi2KB}S8$*v;CTEB;rA^fVyG0*!z1!D0`S%I zw;w0PbH4w9+V0*h(`#-7H5-eDW!?0bKJDJV?p5Y<`u%vC0whqB#w4G>^gn2P4%79ryK4&GW7$Z=hEZ%yNW zvDAw!B|j9H7g?%i$?;Sr0H=awkaYn06iLS_rg9>!iI;IK07sywzbjY~n67 zOZ(HEV66#q{xcLz*=&-Lm2HAM#DKp-;`IgzUNnpsS#uXJZx<7NRJnXl#z*Om@Avh| z+A2{4M4{VYgJ4U_CM}p_^YD8* z6)m~8`h(L4+i7WgN4@k`D|6h__=&FGKQ3wDnpRpfLWSQc-Z8B;q&*`S?s26a8zhW(PrN>w+ZK#c0NTWhu7<8J|`8I=v-?qF^b9U zPCH2t5S`$ZWz{A1cAgrtDwwJ;i2fztdI3aSz^g6CZ1LjLq|PPPy-# zPKs8OSiVgafjv>fAzjY!TpCZ05-?;;>IdHp{o{+9myQsaV#v@>T%Kv}%jn`;=;DmA z2ovu%mO&h*25bdN7ZhGGWD;t`&=nvDy8b3Udaw3Sc&%T)TLKYFdJ|XsNs4O)Ojn7% zB}u0;|oW=1Q?A;%y1$~IdCx%m3@}@m4%dBD@D8%7br}lft z!v+C)dU)7BcTM6B`V^Vk4rmKbG`YM!M+{Xyw9gvqF>t2M3N|lkryL>zOPyT5fp7vhV%F7$rR)y9+r?w-4p@nQmsO z$Ge->q`MsNFLqv(Jt4!^x#HkDR#^t~n&bKE)4tX}{>C&UnhQI#%hQ!ly==n8-B)dz zs6V;Z4 z+_l~ePqTg!?V~P~G{flnk_n2S?0l589q{bJkyEzryBD<=g&(?4dIVN;b+2*8w0-wE zY`={5)Tt%Lf*Dcsb=$o9i(a9oajvV*Enq$kqvel<8f@K^{aLh;qtK9*m6c;cs~g`n zlA5B!LPfsYALS!a1DL>o11BWK9k|cT=@B%)F;04LtSH#xrr&B`ryp63t{CDm`eL64 z%ZY$ROM79})B^S<%CmT|`RuG+XYpxtkHq#Tz_ydLApQXn{P508iIW`}m;I;qOu{gX!>6yfst5}7Gvy>PiJkZ=zU&t73Q9C0v`sh& zrF=2E`6MTpCe<#+p_VD{M<~6>RAPytc4^ARoCYb|2dI3CGBe<_hT9J0Bv9O4%wi$| z>LFX@>=+>s6fcI%GeFNAyF|rZGkFyN2(hH%_LfiD)ub&-j9+~x+**`A+nu&gma2A4 zFWfT}$1YjS?Z~|8&37V>s*Yi#Go2p)*EnC&Azo63~VLOdv%X#00M7xetNF8gOrwofuT?(&R6oBm3UUpb&V7ZOK69V#RQo!J zx+V7{5Jzuh4{=doW@^Gw`n-7V0YVSR=7)Snc1zXQw^Myl&Gb-O^`ub{hjV)!S;~g<8Y7*h%5>f+1oq3{5JL!J@$0lm*2$ z8g52w{3@;5FaLBCo727Gg-{LMQS1j3Vbqg7w}Lt!Yb`#gd93fZU$-`7ge}tXVd)O^79J+g);a~nT>9r?Z)z#)(O{y{JtJr&z z7sTUsXx%KbFtz3BH@3>@3q*5&tuEhpT(+K-VCVbUieufNEo>0BDkK4>@^z?g<~BTB zZugH=TX$Md(a|09NRkwGnqt`w4wJ%Dj~QR_sdU>w*S@GU(5qfvFtVIgOPZ@$DH7T! zT&qv?Bt4DN3%$=Nu@e(BW?Bu?CU?j2mpvmuiOCF5i`49x>7l-Pc#vwCfd~e{Byb0g zF``?#_xTEI(U+;(HQlwB2QclE`~62h7{H`3e)GmLN`YZzSwlv$qz_mh$Ey8F8tbS& zFwW}^@5!F@0(S-V4d6SJUbfl#f<8m<9h9wtfkG~Q#WAoVAa}8t5+O5B_1Zut4>?o6 z6Y_0EPwDIEcNcgGj!9l|F#CpDjC-A^>Bq%lB>y}r%pb+e8=^%k=1!H`%%L=)yifwu ziVGpi(N3jkVSAL_Cq7O!1x=*6fz6ELcyS+w7*0k%Jr%27}HI6W!# z)4ySXoea~}Ir-BYBo%~vV;uFY-wrI@t3qPLOv*1{vX#jZUsu?c4p)A%(VD$j|CMXz zkE^Gv=`XLOVDvE$C}Nfb6F>4KHBqBmCa>S}v*#F)bYAcM&16OU=RGk4xR?%`u#s0o%mUa77u=}L4zDxnA{T&dXTCGAS4gW zDYEV-eszh-xBB>LnB)Y186#{3k|Wzc+u~0{o;_1AIa!l=?VJk<(y31$@kMQ2-PWDu zlnw!lWMR%L_CzR0dld(e^&Bp9UFI(4$8R$ z2j~HbvqJ7x7y8ti!l*;aXGy~$^}pYD;^QMfN1t9WQt}sjF%nl=n*I<>dFZsmFVK65 z)v55zdMmZ0v0+pcT(=Xbiv}Hedcd6bB8(&}Q!eP7@odyipDyTCI^-OOytI_$rbyPT=OboYxB zVV-aJ(!D3>x12|h>V?9ntEf?$#HhpkNSYfaH@x>u+^t{j_`Yai^s95lmOCd=eC{_l zX1bk~FNMRS0$PLPm%o;piA@3SNt?*jD^{vhtkq%7pPaL{J9 z(m^ue3fh39V9b)aX?-L6?ZJs=1*kF9>{ z=*5k9Jcx-L27c~P>=;ZtiE`N)ckg4>lqV;`Y@OcmI(KjkS9BC7rzKjqkUyrPS~B_6 zrw4cP@T~TIDC!-Iitna~tVuFmPgyy4p#B~cplWzc%CmdO`i?$h zqf)w+i!I~NSl-8Ku^8tCiguwms=Y10r7ar*yA=kz*TwcS<1IUVp zXLvcWcS^_^`9}!M4++meVl2kQeH0@hug*K#PaUqv;QWojdH***l&IXRKe8Gtw=F$! z8wb*gE5Cj=fk|UXGDc4`(WHGWzKGyAFl9Ew3f$D^vTlii zi9J`qtG4ijOp-QHd0(gm(?N$jp*4M3Up=Sh*EfKWPpL0h{CG{%pfpdoDWZvwW>047kGLC(vf$1z~JJA;m5kEhew-plh1fIPOSP^a`mg9 z7*;tt)VnTK=d14xA{rL7_y?XXxc{Kr{rRbeuBXOO0FLoY-{o1*8hPH@BX3r3FAC*K`5Z{*mle_h{wRpHa1 z@71}XVlrN5Byz*`ka;_!M6G-$_b=Vt(C*;=Lws#sq?BH5MJSfdlTP6>Bmd8WtvFHp zXo)yr!^Td_uD__8vI-D3+ts-#abOa1Qr*s0$3kv3sFwzJ9_|`# z-?lor)a84@(n0zQ)+3E#S^~_W>~s%Qmpb@4k^CGgSP|w~y}NU+{|uUG4G_5l_PKFq z>+G~<*VO#6*&r(LG5J!lRw*f$;^hoR#6I%ys5baAYy6`aF(yDn!KWTKELLkBqI9%N zuXA+thij@oP}>bV=$zD`eCU1cq;H_QF!8i8zv}$})7eh6%i&8)^3B~59|}aAr#@ob z*stw`2nGE5=;zl9^-8gOw+qppxR9xVEJv&$`;`!&PZg^lwKsrnyrQz&^ zsr1>ek9K%@=T;Qutw>TS_$qhcGcl@CWh?PkUjzKGT=(RD9|e!kvYD9A^Pbdz937)H zRE&98{a^O7KeBgjA7Y0b1a1hsK3|Z!P8VU@oBcbk=plyUhkCXz3)uqiOX^gt6mFQ@ z=SKoj`C&irq1X+VX$UYD|fhg53RUVRn`#YvE9A`vPUO1FdaWk zf}~d^-;h@omH^kv8g@Ts70k#yi#l5OYfPjP)9fdfSZbdccdV5J3iK%1@076mZ+1fG zTb(;qv&oE{+(wmxdmZSfJI@h4+72n}+o|{zf(`r2S<&5`!#^Ka4R`RI{_T}rV4pec z-?P^*Sfu*DT(_n~5XsIOK`OPn`^b0?jx@5^>6b_{o_ye09`{_d7>vFel4yl*{H?|m z%dCOiaA%mOCl5AjrJK#>@Mcv@z5`+2x~!8xCQ{2U*0r8J1$#uZOwA_JEnezkq3N+vKm$Fo@XP$JT>||;;HotA#@zIt94~@&!wQL zu{*JR3xQfE>nMs#AQj?sVa{ovOWD0rY%zOMBp{2;-~PoNa_0?uX#rL$19hjLdEo4VcL^1QjOSOw8K(f zvc=Ju#Q@6&FhZCGlnn&-BzkZ)xXSS^medxe0pe>>@teoVUK^2rXIm0#vUt%kIb}17 zXOf?)9f~Rs$Tg5Dp6Ysq88y5~oErx%((N>pRrj}XH85=-CrBXWgM0&fHzW>Ep5`#R ze_;(1d$QwY07CYL=_??w1qHS~z-qISYdADWCrmY(IbAQ1F>u%u#iR{3WY*M_mzN7J zM)u))kn))+Ik|S9hcS#}m&r9e=4pD(0t785z$odii(@?~a+HqytN8KZtCi`ourL!{$i5H1&}<)LWmJlF1wv(B9R zVo!iCMs5#$F%vHu_OC@Xg?xvpGU)#A8*koC+~l2}_9C}i>@lM>FxfI%OcG1X53LdE z3tFg}?iSYLz<7IpJ&ilPoJBZuna!F;4)f=bD9GE|9A`6V{sqXN$nowi0#FYCJv~LnUx*Tb z_DOlzJ{~XQ@a(z^(F6-wY zM9S0!QDTtbii`ala|wKvQjUL2P#pcO23%_w7>GuW6bs2vJMYnUsv5fmpZ|1@&SHkM z!RMXu&X+*~BS76seP5ys8>G}2J)eCL0FG4E-|oAAzZ|r4=L!G%{lHi6_9 z)7^d|=-)j9&cm^5Xn#hn6>L`t*q~7UQ0b7pIUcVngi?**oXPUPt@m^?8R$0!DWGPvmv=G&$ttDAe;&0( zUb=9In2EOUIR^2XD%g9d1l$Du>V1LX=H~*#2dcWf$sGAH-keXWExC0wqMtO(vp;Fj zi4(j#`h@Pqx1>QQOxE*o1_)LQfTU2diXLP-@81ELPQj$09csYU{2!fIc_5E5#ky+u zGeFAlL(D&gUX$k?q22BAC~u*j%U<_%^>Kk|BrfY|AUadC1)U{h%d5BXlohC<3jseM zW&I=U*|a!NF-=gWe@#5>IUk@^QUCYWvz!PfaIs=*-9d%W|IZ`^-eejvDnF((qCL(c z%Vp?+f!5a&<`vHnQm$nysQ3uZhzb$b250L0^3rR^(Q~jQs=-cAXfP9q$ZuaxC~w8I9vG1 zS3sZumV!MGl~;iRe-jVZJ>WXjrw7jKHM|#zagu!e+V;9ns#;)LyA-69_Q{}i6QXnw zW}iRuuE*$*vN9r>*uupW~H>0FWzP>yD63-|?4jz)FhhN2m0m*Du1 zIp-*n*?S|#Sbp~iGHI)nz?+dJ)j+=MY*$z8z{;BivgrDui~22B$_#?&KJthI?h!#q zi`%+@Z^Vh83(JcPAS~gx{|U>N+vChf50frGiS&VfewPHSGk_T7=~Nk&VthwOx;{#; zKqeu%zitn`@}la+AC6MH(>bx}>5|E!{<*zHXZ69l_VZB(-)Mp9oY=sea)X;ZQRzhG z@1{sYbaws!F}wZZSCM;(VqI|%7fhxW5X#FyC=ZrH7V2{xP3e;DJ{WFSyjpd0oN`E>RJ>!~Q$}?yz43w(hBtiFaudfwg@+TE|(h3xWunF`AaK`Oj# zdJxs|yWe#@*n}w(uo8f8w}Z~5e-5}5hD#t)jn6LoRL|lMze@Peh+YkOvqXgyBaz>Q zj%DNyFrvgXfTdnSHo8GlUzaywbv>?e zzw8WWOIgcA6`4w3si)uV7)QW~aKA|3*KPLD)%9{qy|vBRPpLe_r=C^f{b|g#p?=&| zXWgEuXw)-NyL~!9CArz#gzd%7LL5kZbZ$}n8lU+NXDT9`nX${68O=WH3h~RlpVyIP zi-SHNuR(V(u!Tg_AH8AxWTbpM!?bEJ&uLmNHSSJlQ)Y*v$^OW+KGTV{e;uL-6C*5h zyI)^ACwm)#ul;zXrr~3w+JTL(<05qzhlD%EAr;+Q5%%?Q5!$(DlIwHk%k=W)7U%7D zWBcY}p5jp#+O9#x*zKR}-F237$VG)668PT^MbTX+Ap#|U>GX#sDmEwS|5`u$Eh#2q zbqa<*ZJIYdcF^7W7qqy1r_qi zqafND&yjBHKGJQ~-o35bR@IwH>gx={n~3FuSg%f6=nmr*=_Z9~%O!49W;_>njv|?# z8x8REpDCFOIfx|jg!7`c`rg9}bo|iU5v+fwH7*Zo#H&wyZWDmTB!c0Mkk{F8a--Qs z%j8;SZsz=#qytatO%*0ae`@U~kD6Q114IHWl_FSn)T4neQ=euZ6o)=K>f9OZcwZNJ z0XS1*O!PLpjw|w(k~zno2j~NmQ7d*#mB7Pc%IflJ1>Z>!T-RBsA~tX)6f_GL({ddM zQyzPyo(r4=mORCY)#N(Y5V+4N*-@S89yPnXWjL3=Pi%2)9u&7I?I1}>7oudvTe+@-y$o((qKcBsPB|WR*+&1l`>J7j%#ER_f zRfsbIPpdL9Zq3z;!3F_?B$C(HLP{L(3sy+uqNK ze&o|kw+)dyWsc}jKMG>j;g--5`vcFRl$KHONHYkT*HSry754@EMuam4GgV~joEOs8 zXRFQDR%QhTy;tJBgl%It++TV(_F1+h@F5*mpgB@3ne!9Ak~@XsBw2bLF-|^~9AX!2 zBr%6U@5DrXB=1O5>A*7xnQ_uG3rF}$ZdYWyO+Uay|30t)!Nb5Y?HVp>xzpk_≧- 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 literal 0 HcmV?d00001 From 95bf2cb024e30d8138f992b91ac87e6f2b0f0e15 Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 18 Feb 2025 13:24:58 +0100 Subject: [PATCH 26/27] [feedly] pr.review: Add playbook readme --- .../Playbooks/Feedly_threats_README.md | 34 ++++++++++++++++++ ...Mon_Feb_10_2025.png => Feedly_threats.png} | Bin 2 files changed, 34 insertions(+) create mode 100644 Packs/FeedlyArticles/Playbooks/Feedly_threats_README.md rename Packs/FeedlyArticles/doc_files/{Feedly_threats_Mon_Feb_10_2025.png => Feedly_threats.png} (100%) diff --git a/Packs/FeedlyArticles/Playbooks/Feedly_threats_README.md b/Packs/FeedlyArticles/Playbooks/Feedly_threats_README.md new file mode 100644 index 000000000000..64f76b1b0dda --- /dev/null +++ b/Packs/FeedlyArticles/Playbooks/Feedly_threats_README.md @@ -0,0 +1,34 @@ +Links threat indicators to the report incident + +## Dependencies + +This playbook uses the following sub-playbooks, integrations, and scripts. + +### Sub-playbooks + +This playbook does not use any sub-playbooks. + +### Integrations + +This playbook does not use any integrations. + +### Scripts + +* SearchIndicator + +### Commands + +* associateIndicatorsToIncident + +## Playbook Inputs + +The playbook takes as input an incident created by the FeedlyArticle integration. + +## Playbook Outputs + +The playbook links the threat indicators to the incident. + +## Playbook Image + + +![Feedly threats](../doc_files/Feedly_threats.png) diff --git a/Packs/FeedlyArticles/doc_files/Feedly_threats_Mon_Feb_10_2025.png b/Packs/FeedlyArticles/doc_files/Feedly_threats.png similarity index 100% rename from Packs/FeedlyArticles/doc_files/Feedly_threats_Mon_Feb_10_2025.png rename to Packs/FeedlyArticles/doc_files/Feedly_threats.png From 700669801536da3773477c431f05211c6b419ddb Mon Sep 17 00:00:00 2001 From: Mathieu Beligon Date: Tue, 18 Feb 2025 16:09:05 +0100 Subject: [PATCH 27/27] [feedly] pr.review: format files --- .../classifier-Feedly_-_Report_Mapper.json | 182 +- .../layoutscontainer-Feedly_Report.json | 1590 ++++++++--------- 2 files changed, 865 insertions(+), 907 deletions(-) diff --git a/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json b/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json index abf923647f8d..c1b988cd4d3f 100644 --- a/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json +++ b/Packs/FeedlyArticles/Classifiers/classifier-Feedly_-_Report_Mapper.json @@ -1,104 +1,82 @@ { - "brands": null, - "cacheVersn": 0, - "defaultIncidentType": "", - "definitionId": "", - "description": "", - "feed": false, - "fromServerVersion": "", - "id": "Feedly - Report Mapper", - "incidentSamples": null, - "indicatorSamples": null, - "instanceIds": null, - "itemVersion": "", - "keyTypeMap": {}, - "locked": false, - "logicalVersion": 10, - "mapping": { - "Feedly Report": { - "dontMapEventToLabels": false, - "internalMapping": { - "Feedly Malware Names": { - "simple": "indicators.Malware" - }, - "Feedly Threat Actor Names": { - "simple": "indicators.Threat Actor" - }, - "Feedly crawled date": { - "simple": "create_time" - }, - "Feedly url": { - "simple": "feedly_url" - } - } - }, - "dbot_classification_incident_type_all": { - "dontMapEventToLabels": true, - "internalMapping": { - "Additional Email Addresses": { - "simple": "indicators.Email" - }, - "CVE List": { - "simple": "indicators.CVE" - }, - "Detected IPs": { - "simple": "indicators.IP" - }, - "Domain Name": { - "simple": "indicators.Domain" - }, - "Event ID": { - "simple": "event_id" - }, - "File MD5": { - "simple": "indicators.File" - }, - "MITRE Technique ID": { - "simple": "indicators.TTP" - }, - "MITRE Technique Name": { - "simple": "indicators.Attack Pattern" - }, - "Source name": { - "simple": "source.name" - }, - "Source url": { - "simple": "source.url" - }, - "Tags": { - "complex": { - "filters": [], - "root": "tags", - "transformers": [] - } - }, - "Threat Name": { - "simple": "indicators.Malware" - }, - "URLs": { - "simple": "indicators.URL" - }, - "Use Case Description": { - "simple": "content" - }, - "name": { - "simple": "name" - } - } - } - }, - "name": "Feedly - Report Mapper", - "nameRaw": "Feedly - Report Mapper", - "packID": "", - "packName": "", - "propagationLabels": [ - "all" - ], - "sourceClassifierId": "", - "system": false, - "toServerVersion": "", - "transformer": {}, - "type": "mapping-incoming", - "unclassifiedCases": null, - "version": -1 + "description": "", + "feed": false, + "id": "Feedly - Report Mapper", + "mapping": { + "Feedly Report": { + "dontMapEventToLabels": false, + "internalMapping": { + "Feedly Malware Names": { + "simple": "indicators.Malware" + }, + "Feedly Threat Actor Names": { + "simple": "indicators.Threat Actor" + }, + "Feedly crawled date": { + "simple": "create_time" + }, + "Feedly url": { + "simple": "feedly_url" + } + } + }, + "dbot_classification_incident_type_all": { + "dontMapEventToLabels": true, + "internalMapping": { + "Additional Email Addresses": { + "simple": "indicators.Email" + }, + "CVE List": { + "simple": "indicators.CVE" + }, + "Detected IPs": { + "simple": "indicators.IP" + }, + "Domain Name": { + "simple": "indicators.Domain" + }, + "Event ID": { + "simple": "event_id" + }, + "File MD5": { + "simple": "indicators.File" + }, + "MITRE Technique ID": { + "simple": "indicators.TTP" + }, + "MITRE Technique Name": { + "simple": "indicators.Attack Pattern" + }, + "Source name": { + "simple": "source.name" + }, + "Source url": { + "simple": "source.url" + }, + "Tags": { + "complex": { + "filters": [], + "root": "tags", + "transformers": [] + } + }, + "Threat Name": { + "simple": "indicators.Malware" + }, + "URLs": { + "simple": "indicators.URL" + }, + "Use Case Description": { + "simple": "content" + }, + "name": { + "simple": "name" + } + } + } + }, + "name": "Feedly - Report Mapper", + "type": "mapping-incoming", + "version": -1, + "fromVersion": "6.10.0" } \ No newline at end of file diff --git a/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json b/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json index 7b6a87d6405a..4416af5d8db3 100644 --- a/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json +++ b/Packs/FeedlyArticles/Layouts/layoutscontainer-Feedly_Report.json @@ -1,807 +1,787 @@ { - "cacheVersn": 0, - "close": null, - "definitionId": "", - "description": "", - "detached": false, - "details": null, - "detailsV2": { - "TypeName": "", - "tabs": [ - { - "id": "summary", - "name": "Legacy Summary", - "type": "summary" - }, - { - "hidden": false, - "id": "h2hjyyhld4", - "name": "Article", - "sections": [ - { - "displayType": "ROW", - "h": 11, - "hideItemTitleOnlyOne": true, - "hideName": true, - "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-77ff1410-8700-11ef-88e5-01f8fe79530d", - "items": [ - { - "endCol": 4, - "fieldId": "usecasedescription", - "height": 44, - "id": "b2bcc480-8700-11ef-88e5-01f8fe79530d", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxW": 3, - "minH": 1, - "moved": false, - "name": "Article", - "static": false, - "w": 2, - "x": 0, - "y": 0 - }, - { - "displayType": "ROW", - "h": 2, - "hideName": false, - "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", - "items": [ - { - "endCol": 2, - "fieldId": "feedlycrawleddate", - "height": 22, - "id": "def797e0-8701-11ef-88e5-01f8fe79530d", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - }, - { - "dropEffect": "move", - "endCol": 2, - "fieldId": "feedlyurl", - "height": 22, - "id": "bc06e420-8701-11ef-88e5-01f8fe79530d", - "index": 1, - "listId": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "sourcename", - "height": 22, - "id": "b4bf55d0-8701-11ef-88e5-01f8fe79530d", - "index": 3, - "sectionItemType": "field", - "startCol": 0 - }, - { - "dropEffect": "move", - "endCol": 2, - "fieldId": "sourceurl", - "height": 22, - "id": "b8e44760-8701-11ef-88e5-01f8fe79530d", - "index": 3, - "listId": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "tags", - "height": 22, - "id": "88895d10-a1de-11ef-823c-870772ed0f9a", - "index": 4, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxW": 3, - "minH": 1, - "moved": false, - "name": "Article metadata", - "static": false, - "w": 1, - "x": 2, - "y": 0 - }, - { - "columns": [ - { - "displayed": true, - "isDefault": true, - "key": "indicator_type", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "value", - "width": 300 - }, - { - "displayed": true, - "isDefault": true, - "key": "score", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "firstSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "lastSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "timestamp", - "width": 190 - }, - { - "displayed": true, - "isDefault": true, - "key": "relatedIncCount", - "width": 150 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceBrands", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceInstances", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expirationStatus", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expiration", - "width": 190 - } - ], - "h": 3, - "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-e33dd7a0-8702-11ef-88e5-01f8fe79530d", - "items": [], - "maxW": 3, - "minH": 1, - "moved": false, - "name": "Indicators of compromise", - "query": "-type:\"Attack Pattern\" -type:Malware -type:\"Intrusion Set\"", - "queryType": "input", - "static": false, - "type": "indicators", - "w": 1, - "x": 2, - "y": 5 - }, - { - "columns": [ - { - "displayed": true, - "isDefault": true, - "key": "indicator_type", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "value", - "width": 300 - }, - { - "displayed": true, - "isDefault": true, - "key": "score", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "firstSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "lastSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "timestamp", - "width": 190 - }, - { - "displayed": true, - "isDefault": true, - "key": "relatedIncCount", - "width": 150 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceBrands", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceInstances", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expirationStatus", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expiration", - "width": 190 - } - ], - "h": 3, - "i": "h2hjyyhld4-b282caf0-870f-11ef-88e5-01f8fe79530d", - "items": [], - "maxW": 3, - "minH": 1, - "moved": false, - "name": "Mitre ATT\u0026CK", - "query": "type:\"Attack Pattern\"", - "queryType": "input", - "static": false, - "type": "indicators", - "w": 1, - "x": 2, - "y": 8 - }, - { - "columns": [ - { - "displayed": true, - "isDefault": true, - "key": "indicator_type", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "value", - "width": 300 - }, - { - "displayed": true, - "isDefault": true, - "key": "score", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "firstSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "lastSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "timestamp", - "width": 190 - }, - { - "displayed": true, - "isDefault": true, - "key": "relatedIncCount", - "width": 150 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceBrands", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceInstances", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expirationStatus", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expiration", - "width": 190 - } - ], - "h": 3, - "i": "h2hjyyhld4-6e0a9cf0-a1d5-11ef-aeae-93c18a8c3773", - "items": [], - "maxW": 3, - "minH": 1, - "moved": false, - "name": "Threats", - "query": "type:\"Intrusion Set\" or type:Malware", - "queryType": "input", - "static": false, - "type": "indicators", - "w": 1, - "x": 2, - "y": 2 - } - ], - "type": "custom" - }, - { - "hidden": false, - "id": "zfhf0tdhhj", - "name": "Indicators", - "sections": [ - { - "columns": [ - { - "displayed": true, - "key": "Tags", - "width": 200 - }, - { - "displayed": true, - "isDefault": true, - "key": "indicator_type", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "value", - "width": 123 - }, - { - "displayed": true, - "isDefault": true, - "key": "score", - "width": 120 - }, - { - "displayed": true, - "isDefault": true, - "key": "firstSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "lastSeen", - "width": 275 - }, - { - "displayed": true, - "isDefault": true, - "key": "timestamp", - "width": 190 - }, - { - "displayed": true, - "isDefault": true, - "key": "investigationIDs", - "width": 150 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceBrands", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "sourceInstances", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expirationStatus", - "width": 175 - }, - { - "displayed": true, - "isDefault": true, - "key": "expiration", - "width": 190 - } - ], - "description": "The list of indicators related to the incident.", - "h": 7, - "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-indeooemoh-1840e830-6dd5-11ea-9e64-73fcd6758f5c", - "items": [], - "maxW": 3, - "minH": 1, - "moved": false, - "name": "Indicators related to incident", - "query": "", - "queryType": "input", - "static": false, - "type": "indicators", - "w": 3, - "x": 0, - "y": 0 - } - ], - "type": "custom" - }, - { - "id": "caseinfoid", - "name": "Incident Info", - "sections": [ - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", - "isVisible": true, - "items": [ - { - "endCol": 2, - "fieldId": "type", - "height": 22, - "id": "incident-type-field", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "severity", - "height": 22, - "id": "incident-severity-field", - "index": 1, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "owner", - "height": 22, - "id": "incident-owner-field", - "index": 2, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "sourcebrand", - "height": 22, - "id": "incident-sourceBrand-field", - "index": 3, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "sourceinstance", - "height": 22, - "id": "incident-sourceInstance-field", - "index": 4, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "playbookid", - "height": 22, - "id": "incident-playbookId-field", - "index": 5, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxW": 3, - "moved": false, - "name": "Case Details", - "static": false, - "w": 1, - "x": 0, - "y": 0 - }, - { - "h": 2, - "i": "caseinfoid-61263cc0-98b1-11e9-97d7-ed26ef9e46c8", - "maxW": 3, - "moved": false, - "name": "Notes", - "static": false, - "type": "notes", - "w": 1, - "x": 2, - "y": 0 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-6aabad20-98b1-11e9-97d7-ed26ef9e46c8", - "maxW": 3, - "moved": false, - "name": "Work Plan", - "static": false, - "type": "workplan", - "w": 1, - "x": 1, - "y": 0 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-770ec200-98b1-11e9-97d7-ed26ef9e46c8", - "isVisible": true, - "maxW": 3, - "moved": false, - "name": "Linked Incidents", - "static": false, - "type": "linkedIncidents", - "w": 1, - "x": 1, - "y": 6 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-842632c0-98b1-11e9-97d7-ed26ef9e46c8", - "maxW": 3, - "moved": false, - "name": "Child Incidents", - "static": false, - "type": "childInv", - "w": 1, - "x": 2, - "y": 4 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-4a31afa0-98ba-11e9-a519-93a53c759fe0", - "maxW": 3, - "moved": false, - "name": "Evidence", - "static": false, - "type": "evidence", - "w": 1, - "x": 2, - "y": 2 - }, - { - "displayType": "ROW", - "h": 2, - "hideName": false, - "i": "caseinfoid-7717e580-9bed-11e9-9a3f-8b4b2158e260", - "maxW": 3, - "moved": false, - "name": "Team Members", - "static": false, - "type": "team", - "w": 1, - "x": 2, - "y": 6 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-7ce69dd0-a07f-11e9-936c-5395a1acf11e", - "maxW": 3, - "moved": false, - "name": "Indicators", - "query": "", - "queryType": "input", - "static": false, - "type": "indicators", - "w": 2, - "x": 0, - "y": 4 - }, - { - "displayType": "CARD", - "h": 2, - "i": "caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", - "items": [ - { - "endCol": 1, - "fieldId": "occurred", - "height": 53, - "id": "incident-occurred-field", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 1, - "fieldId": "dbotmodified", - "height": 53, - "id": "incident-modified-field", - "index": 1, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "dbotduedate", - "height": 53, - "id": "incident-dueDate-field", - "index": 2, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "dbotcreated", - "height": 53, - "id": "incident-created-field", - "index": 0, - "sectionItemType": "field", - "startCol": 1 - }, - { - "endCol": 2, - "fieldId": "dbotclosed", - "height": 53, - "id": "incident-closed-field", - "index": 1, - "sectionItemType": "field", - "startCol": 1 - } - ], - "maxW": 3, - "moved": false, - "name": "Timeline Information", - "static": false, - "w": 1, - "x": 0, - "y": 2 - }, - { - "displayType": "ROW", - "h": 2, - "i": "caseinfoid-88e6bf70-a0b1-11e9-b27f-13ae1773d289", - "isVisible": true, - "items": [ - { - "endCol": 2, - "fieldId": "dbotclosed", - "height": 22, - "id": "incident-dbotClosed-field", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "closereason", - "height": 22, - "id": "incident-closeReason-field", - "index": 1, - "sectionItemType": "field", - "startCol": 0 - }, - { - "endCol": 2, - "fieldId": "closenotes", - "height": 22, - "id": "incident-closeNotes-field", - "index": 2, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxW": 3, - "moved": false, - "name": "Closing Information", - "static": false, - "w": 1, - "x": 0, - "y": 6 - }, - { - "displayType": "CARD", - "h": 2, - "i": "caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", - "isVisible": true, - "items": [ - { - "endCol": 2, - "fieldId": "details", - "height": 106, - "id": "incident-details-field", - "index": 0, - "sectionItemType": "field", - "startCol": 0 - } - ], - "maxW": 3, - "moved": false, - "name": "Investigation Data", - "static": false, - "w": 1, - "x": 1, - "y": 2 - } - ], - "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" - } - ] - }, - "edit": null, - "fromServerVersion": "", - "group": "incident", - "id": "Feedly Report", - "indicatorsDetails": null, - "indicatorsQuickView": null, - "itemVersion": "", - "locked": false, - "mobile": null, - "name": "Feedly Report ", - "packID": "", - "packName": "", - "propagationLabels": [ - "all" - ], - "quickView": null, - "quickViewV2": null, - "system": false, - "toServerVersion": "", - "version": -1 + "detailsV2": { + "tabs": [ + { + "id": "summary", + "name": "Legacy Summary", + "type": "summary" + }, + { + "hidden": false, + "id": "h2hjyyhld4", + "name": "Article", + "sections": [ + { + "displayType": "ROW", + "h": 11, + "hideItemTitleOnlyOne": true, + "hideName": true, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-77ff1410-8700-11ef-88e5-01f8fe79530d", + "items": [ + { + "endCol": 4, + "fieldId": "usecasedescription", + "height": 44, + "id": "b2bcc480-8700-11ef-88e5-01f8fe79530d", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Article", + "static": false, + "w": 2, + "x": 0, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", + "items": [ + { + "endCol": 2, + "fieldId": "feedlycrawleddate", + "height": 22, + "id": "def797e0-8701-11ef-88e5-01f8fe79530d", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "feedlyurl", + "height": 22, + "id": "bc06e420-8701-11ef-88e5-01f8fe79530d", + "index": 1, + "listId": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourcename", + "height": 22, + "id": "b4bf55d0-8701-11ef-88e5-01f8fe79530d", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "dropEffect": "move", + "endCol": 2, + "fieldId": "sourceurl", + "height": 22, + "id": "b8e44760-8701-11ef-88e5-01f8fe79530d", + "index": 3, + "listId": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-c90b5e90-8700-11ef-88e5-01f8fe79530d", + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "tags", + "height": 22, + "id": "88895d10-a1de-11ef-823c-870772ed0f9a", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Article metadata", + "static": false, + "w": 1, + "x": 2, + "y": 0 + }, + { + "columns": [ + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 300 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "relatedIncCount", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "h": 3, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-e33dd7a0-8702-11ef-88e5-01f8fe79530d", + "items": [], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Indicators of compromise", + "query": "-type:\"Attack Pattern\" -type:Malware -type:\"Intrusion Set\"", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 1, + "x": 2, + "y": 5 + }, + { + "columns": [ + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 300 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "relatedIncCount", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "h": 3, + "i": "h2hjyyhld4-b282caf0-870f-11ef-88e5-01f8fe79530d", + "items": [], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Mitre ATT\u0026CK", + "query": "type:\"Attack Pattern\"", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 1, + "x": 2, + "y": 8 + }, + { + "columns": [ + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 300 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "relatedIncCount", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "h": 3, + "i": "h2hjyyhld4-6e0a9cf0-a1d5-11ef-aeae-93c18a8c3773", + "items": [], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Threats", + "query": "type:\"Intrusion Set\" or type:Malware", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 1, + "x": 2, + "y": 2 + } + ], + "type": "custom" + }, + { + "hidden": false, + "id": "zfhf0tdhhj", + "name": "Indicators", + "sections": [ + { + "columns": [ + { + "displayed": true, + "key": "Tags", + "width": 200 + }, + { + "displayed": true, + "isDefault": true, + "key": "indicator_type", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "value", + "width": 123 + }, + { + "displayed": true, + "isDefault": true, + "key": "score", + "width": 120 + }, + { + "displayed": true, + "isDefault": true, + "key": "firstSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "lastSeen", + "width": 275 + }, + { + "displayed": true, + "isDefault": true, + "key": "timestamp", + "width": 190 + }, + { + "displayed": true, + "isDefault": true, + "key": "investigationIDs", + "width": 150 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceBrands", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "sourceInstances", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expirationStatus", + "width": 175 + }, + { + "displayed": true, + "isDefault": true, + "key": "expiration", + "width": 190 + } + ], + "description": "The list of indicators related to the incident.", + "h": 7, + "i": "h2hjyyhld4-zfhf0tdhhj-h2hjyyhld4-caseinfoid-indeooemoh-1840e830-6dd5-11ea-9e64-73fcd6758f5c", + "items": [], + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Indicators related to incident", + "query": "", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 3, + "x": 0, + "y": 0 + } + ], + "type": "custom" + }, + { + "id": "caseinfoid", + "name": "Incident Info", + "sections": [ + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-fce71720-98b0-11e9-97d7-ed26ef9e46c8", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "type", + "height": 22, + "id": "incident-type-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "severity", + "height": 22, + "id": "incident-severity-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "owner", + "height": 22, + "id": "incident-owner-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourcebrand", + "height": 22, + "id": "incident-sourceBrand-field", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "sourceinstance", + "height": 22, + "id": "incident-sourceInstance-field", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "playbookid", + "height": 22, + "id": "incident-playbookId-field", + "index": 5, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "moved": false, + "name": "Case Details", + "static": false, + "w": 1, + "x": 0, + "y": 0 + }, + { + "h": 2, + "i": "caseinfoid-61263cc0-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "moved": false, + "name": "Notes", + "static": false, + "type": "notes", + "w": 1, + "x": 2, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-6aabad20-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "moved": false, + "name": "Work Plan", + "static": false, + "type": "workplan", + "w": 1, + "x": 1, + "y": 0 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-770ec200-98b1-11e9-97d7-ed26ef9e46c8", + "isVisible": true, + "maxW": 3, + "moved": false, + "name": "Linked Incidents", + "static": false, + "type": "linkedIncidents", + "w": 1, + "x": 1, + "y": 6 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-842632c0-98b1-11e9-97d7-ed26ef9e46c8", + "maxW": 3, + "moved": false, + "name": "Child Incidents", + "static": false, + "type": "childInv", + "w": 1, + "x": 2, + "y": 4 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-4a31afa0-98ba-11e9-a519-93a53c759fe0", + "maxW": 3, + "moved": false, + "name": "Evidence", + "static": false, + "type": "evidence", + "w": 1, + "x": 2, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "caseinfoid-7717e580-9bed-11e9-9a3f-8b4b2158e260", + "maxW": 3, + "moved": false, + "name": "Team Members", + "static": false, + "type": "team", + "w": 1, + "x": 2, + "y": 6 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-7ce69dd0-a07f-11e9-936c-5395a1acf11e", + "maxW": 3, + "moved": false, + "name": "Indicators", + "query": "", + "queryType": "input", + "static": false, + "type": "indicators", + "w": 2, + "x": 0, + "y": 4 + }, + { + "displayType": "CARD", + "h": 2, + "i": "caseinfoid-ac32f620-a0b0-11e9-b27f-13ae1773d289", + "items": [ + { + "endCol": 1, + "fieldId": "occurred", + "height": 53, + "id": "incident-occurred-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 1, + "fieldId": "dbotmodified", + "height": 53, + "id": "incident-modified-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "dbotduedate", + "height": 53, + "id": "incident-dueDate-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "dbotcreated", + "height": 53, + "id": "incident-created-field", + "index": 0, + "sectionItemType": "field", + "startCol": 1 + }, + { + "endCol": 2, + "fieldId": "dbotclosed", + "height": 53, + "id": "incident-closed-field", + "index": 1, + "sectionItemType": "field", + "startCol": 1 + } + ], + "maxW": 3, + "moved": false, + "name": "Timeline Information", + "static": false, + "w": 1, + "x": 0, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "i": "caseinfoid-88e6bf70-a0b1-11e9-b27f-13ae1773d289", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "dbotclosed", + "height": 22, + "id": "incident-dbotClosed-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "closereason", + "height": 22, + "id": "incident-closeReason-field", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "closenotes", + "height": 22, + "id": "incident-closeNotes-field", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "moved": false, + "name": "Closing Information", + "static": false, + "w": 1, + "x": 0, + "y": 6 + }, + { + "displayType": "CARD", + "h": 2, + "i": "caseinfoid-e54b1770-a0b1-11e9-b27f-13ae1773d289", + "isVisible": true, + "items": [ + { + "endCol": 2, + "fieldId": "details", + "height": 106, + "id": "incident-details-field", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxW": 3, + "moved": false, + "name": "Investigation Data", + "static": false, + "w": 1, + "x": 1, + "y": 2 + } + ], + "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" + } + ] + }, + "group": "incident", + "id": "Feedly Report", + "name": "Feedly Report", + "system": false, + "version": -1, + "fromVersion": "6.10.0", + "description": "" } \ No newline at end of file