Repository: mvt-project/mvt (language: python)

Issue:
Add preliminary ipv4-addr ioc matching support under collection domains
This adds preliminary support to match for any ipv4-addr ioc as if it was a domain.
So any browser activity to http://<ipv4-addr:value> would flag as a known suspicious domain.

Future wise it might make more sense to completely separate ipv4-addr matching logic from the current domain matching logic. But at least for now this would flag as a detection now also for:
https://raw.githubusercontent.com/mvt-project/mvt-indicators/main/2023-07-25_wyrmspy_dragonegg/ip-addresses.txt



Discussion / hints:

Fix patch:
diff --git a/src/mvt/common/indicators.py b/src/mvt/common/indicators.py
index dd05aabe..c3c3f287 100644
--- a/src/mvt/common/indicators.py
+++ b/src/mvt/common/indicators.py
@@ -107,6 +107,13 @@ def _process_indicator(self, indicator: dict, collection: dict) -> None:
                 ioc_coll=collection,
                 ioc_coll_list=collection["domains"],
             )
+        if key == "ipv4-addr:value":
+            # We treat IP addresses as simple domains here to ease checks.
+            self._add_indicator(
+                ioc=value.strip(),
+                ioc_coll=collection,
+                ioc_coll_list=collection["domains"],
+            )
         elif key == "process:name":
             self._add_indicator(
                 ioc=value, ioc_coll=collection, ioc_coll_list=collection["processes"]


Test patch:
diff --git a/tests/artifacts/generate_stix.py b/tests/artifacts/generate_stix.py
index dbbfc647..174f0ddc 100644
--- a/tests/artifacts/generate_stix.py
+++ b/tests/artifacts/generate_stix.py
@@ -13,6 +13,7 @@ def generate_test_stix_file(file_path):
         os.remove(file_path)
 
     domains = ["example.org"]
+    ip_addresses = ["198.51.100.1"]
     processes = ["Launch"]
     emails = ["foobar@example.org"]
     filenames = ["/var/foobar/txt"]
@@ -33,6 +34,15 @@ def generate_test_stix_file(file_path):
         res.append(i)
         res.append(Relationship(i, "indicates", malware))
 
+    for a in ip_addresses:
+        i = Indicator(
+            indicator_types=["malicious-activity"],
+            pattern="[ipv4-addr:value='{}']".format(a),
+            pattern_type="stix",
+        )
+        res.append(i)
+        res.append(Relationship(i, "indicates", malware))
+
     for p in processes:
         i = Indicator(
             indicator_types=["malicious-activity"],
diff --git a/tests/common/test_indicators.py b/tests/common/test_indicators.py
index 7f386dec..9a687c04 100644
--- a/tests/common/test_indicators.py
+++ b/tests/common/test_indicators.py
@@ -15,8 +15,8 @@ def test_parse_stix2(self, indicator_file):
         ind = Indicators(log=logging)
         ind.load_indicators_files([indicator_file], load_default=False)
         assert len(ind.ioc_collections) == 1
-        assert ind.ioc_collections[0]["count"] == 8
-        assert len(ind.ioc_collections[0]["domains"]) == 1
+        assert ind.ioc_collections[0]["count"] == 9
+        assert len(ind.ioc_collections[0]["domains"]) == 2
         assert len(ind.ioc_collections[0]["emails"]) == 1
         assert len(ind.ioc_collections[0]["file_names"]) == 1
         assert len(ind.ioc_collections[0]["processes"]) == 1
@@ -74,6 +74,10 @@ def test_check_url(self, indicator_file):
         assert ind.check_url("https://github.com") is None
         assert ind.check_url("https://example.com/") is None
 
+        # Test detecting IP address indicators from STIX.
+        assert ind.check_url("https://198.51.100.1:8080/")
+        assert ind.check_url("https://1.1.1.1/") is None
+
     def test_check_file_hash(self, indicator_file):
         ind = Indicators(log=logging)
         ind.load_indicators_files([indicator_file], load_default=False)
@@ -98,4 +102,4 @@ def test_env_stix(self, indicator_file):
         os.environ["MVT_STIX2"] = indicator_file
         ind = Indicators(log=logging)
         ind.load_indicators_files([], load_default=False)
-        assert ind.total_ioc_count == 8
+        assert ind.total_ioc_count == 9