Repository: OpenCTI-Platform/connectors

Issue:
[Elastic Security] Incorrect field reference for sighting 
# Description

Using an indictor match rule in elastic, the ["threat"]["indicator"] object will never be in the alerts, the outputs are stored in ["threat"]["enrichments"]["indicator"] as an array of objects. 
https://github.com/OpenCTI-Platform/connectors/blob/1771fd54dc53b2f54afeaf254f9a80694363320a/stream/elastic/elastic/sightings_manager.py#L120

# Enviroment 
elastic -  1.0.0
pyopencti - 5.0.3
elasticsearch - 7.15.0

# Reproducible Steps
1. Produce an indictor match alert
2. Connector pulls alerts
3. fails to parse alert




Discussion:
The effect of this bug is that the connector runs and the stream works fine, but the connector is unable to create sightings to push back to opencti as it throws a KeyError when trying to access the indicators to create the sightings.
@dcode Are you able to take a look to this one?

Resolving patch:
diff --git a/stream/elastic/elastic/__init__.py b/stream/elastic/elastic/__init__.py
--- a/stream/elastic/elastic/__init__.py
+++ b/stream/elastic/elastic/__init__.py
@@ -1,6 +1,6 @@
 import os
 
-__version__ = "1.0.0"
+__version__ = "5.1.1"
 LOGGER_NAME = "elastic"
 RE_DATEMATH = (
     r"\{(?P<modulo>.*now[^{]*)(?:\{(?P<format>[^|]*)(?:\|(?P<offset>[^}]+))?\})?\}"
diff --git a/stream/elastic/elastic/console.py b/stream/elastic/elastic/console.py
--- a/stream/elastic/elastic/console.py
+++ b/stream/elastic/elastic/console.py
@@ -26,7 +26,7 @@
 import yaml
 from docopt import docopt
 
-from . import LOGGER_NAME, __version__, __DATA_DIR__
+from . import __DATA_DIR__, LOGGER_NAME, __version__
 from .conf import defaults
 from .elastic import ElasticConnector
 from .utils import add_branch, dict_merge, remove_nones, setup_logger
diff --git a/stream/elastic/elastic/sightings_manager.py b/stream/elastic/elastic/sightings_manager.py
--- a/stream/elastic/elastic/sightings_manager.py
+++ b/stream/elastic/elastic/sightings_manager.py
@@ -74,12 +74,12 @@ def __init__(
         logger.info("Signals manager thread initialized")
 
     def _get_elastic_entity(self) -> str:
-        """Get or create a Elastic Threatintel Connector entity if not exists"""
+        """Get or create a Elastic Connector entity if not exists"""
         if self.author_id is not None:
             return self.author_id
 
         _entity_name = self.config.get(
-            "connector.entity_name", "Elastic ThreatIntel Connector"
+            "connector.entity_name", "Elastic Detection Cluster"
         )
         _entity_desc = self.config.get("connector.entity_description", "")
 
@@ -89,8 +89,7 @@ def _get_elastic_entity(self) -> str:
         if not elastic_entity:
             logger.info(f"Creating {_entity_name} STIX identity")
             self.author_id = self.helper.api.identity.create(
-                # NOTE: This should maybe be `system` See https://github.com/OpenCTI-Platform/opencti/issues/1322
-                type="Organization",
+                type="System",
                 name=_entity_name,
                 description=_entity_desc,
             )["id"]
@@ -117,7 +116,8 @@ def run(self) -> None:
 
             # Parse the results
             for hit in results["hits"]["hits"]:
-                for indicator in hit["_source"]["threat"]["indicator"]:
+                # This depends on ECS mappings >= 1.11
+                for indicator in hit["_source"]["threat"]["enrichments"]:
                     # Get original threatintel document
                     try:
                         _doc = self.es_client.get(
@@ -142,11 +142,33 @@ def run(self) -> None:
                             "internal_id"
                         ]
                     else:
-                        logger.warn(
-                            "Signal for threatintel document doesn't have opencti reference. Skipping"
+                        logger.info(
+                            "Signal for threatintel document doesn't have opencti reference. Searching for matched indicator"
                         )
-                        # XXX Optionally, could look up via OpenCTI API for an indicator that matches
-                        continue
+                        # This probably isn't perfect, but should get us close-ish
+                        _filters = [
+                            {
+                                "key": "pattern_type",
+                                "operator": "match",
+                                "values": ["STIX"],
+                            },
+                            {
+                                "key": "pattern",
+                                "operator": "match",
+                                "values": [indicator["matched"]["atomic"]],
+                            },
+                        ]
+
+                        _cti_indicator = self.helper.api.indicator.read(
+                            filters=_filters
+                        )
+                        if _cti_indicator:
+                            _opencti_id = _cti_indicator["id"]
+                        else:
+                            logger.warn(
+                                f"Unable to find matching indicator in OpenCTI for: {indicator['matched']['atomic']}"
+                            )
+                            continue
 
                     _timestamp = hit["_source"]["signal"]["original_time"]
                     if _opencti_id not in ids_dict:


Test patch:
diff --git a/stream/elastic/tests/test_elastic_threatintel.py b/stream/elastic/tests/test_elastic_threatintel.py
--- a/stream/elastic/tests/test_elastic_threatintel.py
+++ b/stream/elastic/tests/test_elastic_threatintel.py
@@ -1,5 +1,9 @@
+from importlib.metadata import version
+
 from elastic import __version__
 
 
 def test_version():
-    assert __version__ == "0.4.0"
+    """Ensure Connector version matches pycti version. If this fails, check __version__ in __init__.py and pycti version in pyproject.toml"""
+    pycti_ver: str = version("pycti")
+    assert __version__ == pycti_ver