pycti 6.3.0__py3-none-any.whl → 6.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pycti might be problematic. Click here for more details.

pycti/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = "6.3.0"
2
+ __version__ = "6.3.2"
3
3
 
4
4
  from .api.opencti_api_client import OpenCTIApiClient
5
5
  from .api.opencti_api_connector import OpenCTIApiConnector
@@ -376,7 +376,7 @@ class ListenQueue(threading.Thread):
376
376
  self.pika_credentials = pika.PlainCredentials(self.user, self.password)
377
377
  self.pika_parameters = pika.ConnectionParameters(
378
378
  heartbeat=10,
379
- blocked_connection_timeout=10,
379
+ blocked_connection_timeout=30,
380
380
  host=self.host,
381
381
  port=self.port,
382
382
  virtual_host=self.vhost,
@@ -1556,6 +1556,8 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1556
1556
  :type entities_types: list, optional
1557
1557
  :param update: whether to updated data in the database, defaults to False
1558
1558
  :type update: bool, optional
1559
+ :param bypass_split: use to prevent splitting of the bundle. This option has been removed since 6.3 and is no longer used.
1560
+ :type bypass_split: bool, optional
1559
1561
  :raises ValueError: if the bundle is empty
1560
1562
  :return: list of bundles
1561
1563
  :rtype: list
@@ -1564,11 +1566,11 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1564
1566
  entities_types = kwargs.get("entities_types", None)
1565
1567
  update = kwargs.get("update", False)
1566
1568
  event_version = kwargs.get("event_version", None)
1567
- bypass_split = kwargs.get("bypass_split", False)
1568
1569
  bypass_validation = kwargs.get("bypass_validation", False)
1569
1570
  entity_id = kwargs.get("entity_id", None)
1570
1571
  file_name = kwargs.get("file_name", None)
1571
1572
  bundle_send_to_queue = kwargs.get("send_to_queue", self.bundle_send_to_queue)
1573
+ cleanup_inconsistent_bundle = kwargs.get("cleanup_inconsistent_bundle", False)
1572
1574
  bundle_send_to_directory = kwargs.get(
1573
1575
  "send_to_directory", self.bundle_send_to_directory
1574
1576
  )
@@ -1690,17 +1692,16 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1690
1692
  final_write_file = os.path.join(bundle_send_to_directory_path, bundle_file)
1691
1693
  os.rename(write_file, final_write_file)
1692
1694
 
1693
- if bypass_split:
1694
- bundles = [bundle]
1695
- expectations_number = len(json.loads(bundle)["objects"])
1696
- else:
1697
- stix2_splitter = OpenCTIStix2Splitter()
1698
- (
1699
- expectations_number,
1700
- bundles,
1701
- ) = stix2_splitter.split_bundle_with_expectations(
1702
- bundle, True, event_version
1703
- )
1695
+ stix2_splitter = OpenCTIStix2Splitter()
1696
+ (
1697
+ expectations_number,
1698
+ bundles,
1699
+ ) = stix2_splitter.split_bundle_with_expectations(
1700
+ bundle=bundle,
1701
+ use_json=True,
1702
+ event_version=event_version,
1703
+ cleanup_inconsistent_bundle=cleanup_inconsistent_bundle,
1704
+ )
1704
1705
 
1705
1706
  if len(bundles) == 0:
1706
1707
  self.metric.inc("error_count")
@@ -1718,7 +1719,6 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1718
1719
  )
1719
1720
  pika_parameters = pika.ConnectionParameters(
1720
1721
  heartbeat=10,
1721
- blocked_connection_timeout=10,
1722
1722
  host=self.connector_config["connection"]["host"],
1723
1723
  port=self.connector_config["connection"]["port"],
1724
1724
  virtual_host=self.connector_config["connection"]["vhost"],
@@ -747,7 +747,7 @@ class CaseRfi:
747
747
  },
748
748
  )
749
749
  query = """
750
- mutation CaseRfiEditRelationAdd($id: ID!, $input: StixRefRelationshipAddInput) {
750
+ mutation CaseRfiEditRelationAdd($id: ID!, $input: StixRefRelationshipAddInput!) {
751
751
  stixDomainObjectEdit(id: $id) {
752
752
  relationAdd(input: $input) {
753
753
  id
@@ -746,7 +746,7 @@ class CaseRft:
746
746
  },
747
747
  )
748
748
  query = """
749
- mutation CaseRftEditRelationAdd($id: ID!, $input: StixRefRelationshipAddInput) {
749
+ mutation CaseRftEditRelationAdd($id: ID!, $input: StixRefRelationshipAddInput!) {
750
750
  stixDomainObjectEdit(id: $id) {
751
751
  relationAdd(input: $input) {
752
752
  id
@@ -1,9 +1,8 @@
1
1
  # coding: utf-8
2
2
 
3
3
  import json
4
- import uuid
5
4
 
6
- from stix2.canonicalization.Canonicalize import canonicalize
5
+ from pycti.utils.opencti_stix2_identifier import kill_chain_phase_generate_id
7
6
 
8
7
 
9
8
  class KillChainPhase:
@@ -25,10 +24,9 @@ class KillChainPhase:
25
24
 
26
25
  @staticmethod
27
26
  def generate_id(phase_name, kill_chain_name):
28
- data = {"phase_name": phase_name, "kill_chain_name": kill_chain_name}
29
- data = canonicalize(data, utf8=False)
30
- id = str(uuid.uuid5(uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7"), data))
31
- return "kill-chain-phase--" + id
27
+ return kill_chain_phase_generate_id(
28
+ phase_name=phase_name, kill_chain_name=kill_chain_name
29
+ )
32
30
 
33
31
  """
34
32
  List Kill-Chain-Phase objects
@@ -2619,10 +2619,9 @@ class OpenCTIStix2:
2619
2619
  else None
2620
2620
  )
2621
2621
  stix2_splitter = OpenCTIStix2Splitter()
2622
- try:
2623
- bundles = stix2_splitter.split_bundle(stix_bundle, False, event_version)
2624
- except RecursionError:
2625
- bundles = [stix_bundle]
2622
+ _, bundles = stix2_splitter.split_bundle_with_expectations(
2623
+ stix_bundle, False, event_version
2624
+ )
2626
2625
  # Import every element in a specific order
2627
2626
  imported_elements = []
2628
2627
  for bundle in bundles:
@@ -0,0 +1,22 @@
1
+ import uuid
2
+
3
+ from stix2.canonicalization.Canonicalize import canonicalize
4
+
5
+
6
+ def external_reference_generate_id(url=None, source_name=None, external_id=None):
7
+ if url is not None:
8
+ data = {"url": url}
9
+ elif source_name is not None and external_id is not None:
10
+ data = {"source_name": source_name, "external_id": external_id}
11
+ else:
12
+ return None
13
+ data = canonicalize(data, utf8=False)
14
+ id = str(uuid.uuid5(uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7"), data))
15
+ return "external-reference--" + id
16
+
17
+
18
+ def kill_chain_phase_generate_id(phase_name, kill_chain_name):
19
+ data = {"phase_name": phase_name, "kill_chain_name": kill_chain_name}
20
+ data = canonicalize(data, utf8=False)
21
+ id = str(uuid.uuid5(uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7"), data))
22
+ return "kill-chain-phase--" + id
@@ -1,68 +1,187 @@
1
1
  import json
2
- import re
3
2
  import uuid
4
3
  from typing import Tuple
5
4
 
6
5
  from typing_extensions import deprecated
7
6
 
8
- MITRE_X_CAPEC = (
9
- "x_capec_*" # https://github.com/mitre-attack/attack-stix-data/issues/34
7
+ from pycti.utils.opencti_stix2_identifier import (
8
+ external_reference_generate_id,
9
+ kill_chain_phase_generate_id,
10
10
  )
11
- unsupported_ref_patterns = [MITRE_X_CAPEC]
11
+ from pycti.utils.opencti_stix2_utils import (
12
+ STIX_CYBER_OBSERVABLE_MAPPING,
13
+ SUPPORTED_STIX_DOMAIN_OBJECTS,
14
+ )
15
+
16
+ supported_types = (
17
+ SUPPORTED_STIX_DOMAIN_OBJECTS # entities
18
+ + list(STIX_CYBER_OBSERVABLE_MAPPING.keys()) # observables
19
+ + ["relationship", "sighting"] # relationships
20
+ )
21
+
22
+
23
+ def is_id_supported(key):
24
+ id_type = key.split("--")[0]
25
+ return id_type in supported_types
12
26
 
13
27
 
14
28
  class OpenCTIStix2Splitter:
15
29
  def __init__(self):
16
30
  self.cache_index = {}
31
+ self.cache_refs = {}
17
32
  self.elements = []
18
- self.unsupported_patterns = list(
19
- map(lambda pattern: re.compile(pattern), unsupported_ref_patterns)
20
- )
21
33
 
22
- def is_ref_key_supported(self, key):
23
- for pattern in self.unsupported_patterns:
24
- if pattern.match(key):
25
- return False
26
- return True
27
-
28
- def enlist_element(self, item_id, raw_data):
34
+ def enlist_element(
35
+ self, item_id, raw_data, cleanup_inconsistent_bundle, parent_acc
36
+ ):
29
37
  nb_deps = 1
30
38
  if item_id not in raw_data:
31
39
  return 0
40
+
32
41
  existing_item = self.cache_index.get(item_id)
33
42
  if existing_item is not None:
34
43
  return existing_item["nb_deps"]
35
- # Recursive enlist for every refs
44
+
36
45
  item = raw_data[item_id]
46
+ if self.cache_refs.get(item_id) is None:
47
+ self.cache_refs[item_id] = []
37
48
  for key in list(item.keys()):
38
49
  value = item[key]
39
- if key.endswith("_refs") and self.is_ref_key_supported(key):
50
+ # Recursive enlist for every refs
51
+ if key.endswith("_refs"):
40
52
  to_keep = []
41
53
  for element_ref in item[key]:
42
- if element_ref != item_id:
43
- nb_deps += self.enlist_element(element_ref, raw_data)
44
- to_keep.append(element_ref)
54
+ # We need to check if this ref is not already a reference
55
+ is_missing_ref = raw_data.get(element_ref) is None
56
+ must_be_cleaned = is_missing_ref and cleanup_inconsistent_bundle
57
+ not_dependency_ref = (
58
+ self.cache_refs.get(element_ref) is None
59
+ or item_id not in self.cache_refs[element_ref]
60
+ )
61
+ # Prevent any self reference
62
+ if (
63
+ is_id_supported(element_ref)
64
+ and not must_be_cleaned
65
+ and element_ref not in parent_acc
66
+ and element_ref != item_id
67
+ and not_dependency_ref
68
+ ):
69
+ self.cache_refs[item_id].append(element_ref)
70
+ nb_deps += self.enlist_element(
71
+ element_ref,
72
+ raw_data,
73
+ cleanup_inconsistent_bundle,
74
+ parent_acc + [element_ref],
75
+ )
76
+ if element_ref not in to_keep:
77
+ to_keep.append(element_ref)
45
78
  item[key] = to_keep
46
- elif key.endswith("_ref") and self.is_ref_key_supported(key):
47
- if item[key] == item_id:
48
- item[key] = None
79
+ elif key.endswith("_ref"):
80
+ is_missing_ref = raw_data.get(value) is None
81
+ must_be_cleaned = is_missing_ref and cleanup_inconsistent_bundle
82
+ not_dependency_ref = (
83
+ self.cache_refs.get(value) is None
84
+ or item_id not in self.cache_refs[value]
85
+ )
86
+ # Prevent any self reference
87
+ if (
88
+ value is not None
89
+ and not must_be_cleaned
90
+ and value not in parent_acc
91
+ and is_id_supported(value)
92
+ and value != item_id
93
+ and not_dependency_ref
94
+ ):
95
+ self.cache_refs[item_id].append(value)
96
+ nb_deps += self.enlist_element(
97
+ value,
98
+ raw_data,
99
+ cleanup_inconsistent_bundle,
100
+ parent_acc + [value],
101
+ )
49
102
  else:
50
- # Need to handle the special case of recursive ref for created by ref
51
- is_created_by_ref = key == "created_by_ref"
52
- if is_created_by_ref:
53
- is_marking = item["id"].startswith("marking-definition--")
54
- if is_marking is False:
55
- nb_deps += self.enlist_element(value, raw_data)
56
- else:
57
- nb_deps += self.enlist_element(value, raw_data)
103
+ item[key] = None
104
+ # Case for embedded elements (deduplicating and cleanup)
105
+ elif key == "external_references":
106
+ # specific case of splitting external references
107
+ # reference_ids = []
108
+ deduplicated_references = []
109
+ deduplicated_references_cache = {}
110
+ references = item[key]
111
+ for reference in references:
112
+ reference_id = external_reference_generate_id(
113
+ url=reference.get("url"),
114
+ source_name=reference.get("source_name"),
115
+ external_id=reference.get("external_id"),
116
+ )
117
+ if (
118
+ reference_id is not None
119
+ and deduplicated_references_cache.get(reference_id) is None
120
+ ):
121
+ deduplicated_references_cache[reference_id] = reference_id
122
+ deduplicated_references.append(reference)
123
+ # - Needed for a future move of splitting the elements
124
+ # reference["id"] = reference_id
125
+ # reference["type"] = "External-Reference"
126
+ # raw_data[reference_id] = reference
127
+ # if reference_id not in reference_ids:
128
+ # reference_ids.append(reference_id)
129
+ # nb_deps += self.enlist_element(reference_id, raw_data)
130
+ item[key] = deduplicated_references
131
+ elif key == "kill_chain_phases":
132
+ # specific case of splitting kill_chain phases
133
+ # kill_chain_ids = []
134
+ deduplicated_kill_chain = []
135
+ deduplicated_kill_chain_cache = {}
136
+ kill_chains = item[key]
137
+ for kill_chain in kill_chains:
138
+ kill_chain_id = kill_chain_phase_generate_id(
139
+ kill_chain_name=kill_chain.get("kill_chain_name"),
140
+ phase_name=kill_chain.get("phase_name"),
141
+ )
142
+ if (
143
+ kill_chain_id is not None
144
+ and deduplicated_kill_chain_cache.get(kill_chain_id) is None
145
+ ):
146
+ deduplicated_kill_chain_cache[kill_chain_id] = kill_chain_id
147
+ deduplicated_kill_chain.append(kill_chain)
148
+ # - Needed for a future move of splitting the elements
149
+ # kill_chain["id"] = kill_chain_id
150
+ # kill_chain["type"] = "Kill-Chain-Phase"
151
+ # raw_data[kill_chain_id] = kill_chain
152
+ # if kill_chain_id not in kill_chain_ids:
153
+ # kill_chain_ids.append(kill_chain_id)
154
+ # nb_deps += self.enlist_element(kill_chain_id, raw_data)
155
+ item[key] = deduplicated_kill_chain
156
+
58
157
  # Get the final dep counting and add in cache
59
158
  item["nb_deps"] = nb_deps
60
- self.elements.append(item)
61
- self.cache_index[item_id] = item # Put in cache
159
+ # Put in cache
160
+ if self.cache_index.get(item_id) is None:
161
+ # enlist only if compatible
162
+ if item["type"] == "relationship":
163
+ is_compatible = (
164
+ item["source_ref"] is not None and item["target_ref"] is not None
165
+ )
166
+ elif item["type"] == "sighting":
167
+ is_compatible = (
168
+ item["sighting_of_ref"] is not None
169
+ and len(item["where_sighted_refs"]) > 0
170
+ )
171
+ else:
172
+ is_compatible = is_id_supported(item_id)
173
+ if is_compatible:
174
+ self.elements.append(item)
175
+ self.cache_index[item_id] = item
176
+
62
177
  return nb_deps
63
178
 
64
179
  def split_bundle_with_expectations(
65
- self, bundle, use_json=True, event_version=None
180
+ self,
181
+ bundle,
182
+ use_json=True,
183
+ event_version=None,
184
+ cleanup_inconsistent_bundle=False,
66
185
  ) -> Tuple[int, list]:
67
186
  """splits a valid stix2 bundle into a list of bundles"""
68
187
  if use_json:
@@ -84,7 +203,7 @@ class OpenCTIStix2Splitter:
84
203
  for item in bundle_data["objects"]:
85
204
  raw_data[item["id"]] = item
86
205
  for item in bundle_data["objects"]:
87
- self.enlist_element(item["id"], raw_data)
206
+ self.enlist_element(item["id"], raw_data, cleanup_inconsistent_bundle, [])
88
207
 
89
208
  # Build the bundles
90
209
  bundles = []
@@ -2,6 +2,46 @@ from typing import Any, Dict
2
2
 
3
3
  from stix2 import EqualityComparisonExpression, ObjectPath, ObservationExpression
4
4
 
5
+ SUPPORTED_STIX_DOMAIN_OBJECTS = [
6
+ "marking-definition",
7
+ "attack-pattern",
8
+ "campaign",
9
+ "channel",
10
+ "event",
11
+ "note",
12
+ "observed-data",
13
+ "opinion",
14
+ "report",
15
+ "grouping",
16
+ "case-rfi",
17
+ "x-opencti-case-rfi",
18
+ "case-rft",
19
+ "x-opencti-case-rft",
20
+ "task",
21
+ "x-opencti-task",
22
+ "case-incident",
23
+ "x-opencti-case-incident",
24
+ "feedback",
25
+ "x-opencti-feedback",
26
+ "course-of-action",
27
+ "data-component",
28
+ "x-mitre-data-component",
29
+ "data-source",
30
+ "x-mitre-data-source",
31
+ "identity",
32
+ "indicator",
33
+ "infrastructure",
34
+ "intrusion-set",
35
+ "location",
36
+ "malware",
37
+ "malware-analysis",
38
+ "threat-actor",
39
+ "tool",
40
+ "narrative",
41
+ "vulnerability",
42
+ "incident",
43
+ ]
44
+
5
45
  STIX_CYBER_OBSERVABLE_MAPPING = {
6
46
  "autonomous-system": "Autonomous-System",
7
47
  "directory": "Directory",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycti
3
- Version: 6.3.0
3
+ Version: 6.3.2
4
4
  Summary: Python API client for OpenCTI.
5
5
  Home-page: https://github.com/OpenCTI-Platform/client-python
6
6
  Author: Filigran
@@ -1,4 +1,4 @@
1
- pycti/__init__.py,sha256=fgdgvN6RAYMan3BD5R61Xtkq0QzLc4bpDVgjw7qVPFg,5218
1
+ pycti/__init__.py,sha256=LVpY_roD_1fmPLEZf7X3CaxCNrE50zxcv1fJd30PbcE,5218
2
2
  pycti/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  pycti/api/opencti_api_client.py,sha256=WpJs3GtEO0kV29KXmKY-2JmtiL6JSPD-746-FbnIcik,31027
4
4
  pycti/api/opencti_api_connector.py,sha256=ubM_zPjTD8L33TEugCQgf_YF9zugDFg_7FgNubGlwJw,5447
@@ -6,14 +6,14 @@ pycti/api/opencti_api_playbook.py,sha256=456We78vESukfSOi_CctfZ9dbBJEi76EHClRc2f
6
6
  pycti/api/opencti_api_work.py,sha256=JLfl7oy6Cq9IrYW_kUrqwzN46FoVzyIn1JJQKyK0h_w,7615
7
7
  pycti/connector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  pycti/connector/opencti_connector.py,sha256=5oVvS27KWhzRiofJAeQPDtba-EP83FziSistyEd5l-U,2561
9
- pycti/connector/opencti_connector_helper.py,sha256=AVrVT-DVfPz3mL6fYtURo4hYMYB8MDOjlbNpx2gd9hY,79261
9
+ pycti/connector/opencti_connector_helper.py,sha256=KUir7ioe-5dhh9E8weZ_dRHu2j_lCpDsc0ORZJgZhz4,79371
10
10
  pycti/connector/opencti_metric_handler.py,sha256=4jXHeJflomtHjuQ_YU0b36TG7o26vOWbY_jvU8Ezobs,3725
11
11
  pycti/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  pycti/entities/opencti_attack_pattern.py,sha256=AP_lTsHk0NscvFsXdxjzXWLCpg0ZaHTUT-Yg2JyB4YU,22047
13
13
  pycti/entities/opencti_campaign.py,sha256=WXY9wOJYqmW7tbRHQPlFX-vNYsx5w9Gz_olS4vJ0MDM,17683
14
14
  pycti/entities/opencti_case_incident.py,sha256=BEP22Itt7-ZxMBwMNMHO7sbS8XfNSfiy0Y7chuOgWJ4,33699
15
- pycti/entities/opencti_case_rfi.py,sha256=1j_v7iyj8o6JEMZDI9a0xRhjAO1I_6KCrED0YfScuj0,32452
16
- pycti/entities/opencti_case_rft.py,sha256=WoY9d0MdPezJx7NSfR_33jZpixtVDlWQSlVFGY79_Bs,33336
15
+ pycti/entities/opencti_case_rfi.py,sha256=3coAKmkyc6rmk6D9Co3JvggtpOcOCFJJRgR4TuGSpcI,32453
16
+ pycti/entities/opencti_case_rft.py,sha256=cO-DJAJThKHMYAMvKH8yGGIPXu1C40h9qZaNbwVXfzo,33337
17
17
  pycti/entities/opencti_channel.py,sha256=cA8ltYJpB43rUSKvCPyLUJvtdb_RSJ4tuuUdi_EMF2Q,16608
18
18
  pycti/entities/opencti_course_of_action.py,sha256=j_yZqvfeCba2FBSf0Pf2ZoDYUL_qpntMAUwpc_AJ4ow,18577
19
19
  pycti/entities/opencti_data_component.py,sha256=081y2bc4lz5E8esNloLNrZnIUCDicD3vKycIETwsyuE,19158
@@ -27,7 +27,7 @@ pycti/entities/opencti_incident.py,sha256=KAaqn0mnlyIKJ2whtbK0Eg8AbfQfxKvppS9hyf
27
27
  pycti/entities/opencti_indicator.py,sha256=gh69C4Wu2Z08PcI2LC9p_FtKC1Qq8I1DjVsukz17kGI,20842
28
28
  pycti/entities/opencti_infrastructure.py,sha256=-hgDXR3ld2B6Man9WkFFuXOY8ELprLgNIUcyE03TSDA,19929
29
29
  pycti/entities/opencti_intrusion_set.py,sha256=MXubQhDZ6LE69z1Wj8agAZNOrGeKiXU4IZs_9B0Expg,18957
30
- pycti/entities/opencti_kill_chain_phase.py,sha256=a509rFeIchPRlO5rMHPVxrxfUuTbV4znh6e_NJHC66I,8062
30
+ pycti/entities/opencti_kill_chain_phase.py,sha256=643ffNdq-ZaVZPUqqLm1S6ITgKEf7N3XVAJxJM6bbbQ,7938
31
31
  pycti/entities/opencti_label.py,sha256=6RZJPIa_dXf_YNNU4xXKghfBnpNjhU5YXOaSIcB4YrM,8800
32
32
  pycti/entities/opencti_language.py,sha256=eHB7qzf_l2Mno_Wy9kF0QUdcBktWgr4kRHhb9AxT0c0,16176
33
33
  pycti/entities/opencti_location.py,sha256=QSC8klDklTcXziulPFCpn8-UqeSIzPX287vfUYVDVbY,17776
@@ -62,12 +62,13 @@ pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py
62
62
  pycti/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
63
  pycti/utils/constants.py,sha256=ZgOVxY5bnrHiNvPgOfZLWk16sSDnaE_tg8JVjZpw24Q,11831
64
64
  pycti/utils/opencti_logger.py,sha256=0dvB75V0SuPFGxL539dAQrxTt1N5Acx0A3Ogwl5WMJ8,2199
65
- pycti/utils/opencti_stix2.py,sha256=pYPvDJRkd9gTkC3__FYapxcSZdrAbRY-aSqDd0oKgUw,116521
66
- pycti/utils/opencti_stix2_splitter.py,sha256=A2GqoiFzEga8hslgA3mm4FDoObFsWgx4zK4DdcWTguc,4907
65
+ pycti/utils/opencti_stix2.py,sha256=FphDoilIGesw7XM5i-OCq_qi-IluNEOPajS8oBkD0vs,116480
66
+ pycti/utils/opencti_stix2_identifier.py,sha256=k8L1z4q1xdCBfxqUba4YS_kT-MmbJFxYh0RvfGOmrOs,837
67
+ pycti/utils/opencti_stix2_splitter.py,sha256=01fBdfVNKWhO0t34Z4ffZ5v4X5oWfBuPRjcu5FfaoRU,10233
67
68
  pycti/utils/opencti_stix2_update.py,sha256=CnMyqkeVA0jgyxEcgqna8sABU4YPMjkEJ228GVurIn4,14658
68
- pycti/utils/opencti_stix2_utils.py,sha256=4r9qglN3AIN8JH1B9Ts2o20Qn3K203M4c5-lIPzRpZ4,4138
69
- pycti-6.3.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
70
- pycti-6.3.0.dist-info/METADATA,sha256=17jAjLMFaCKuHZ-zvBherP032tMq7dhUL5ez4rUHbO0,5418
71
- pycti-6.3.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
72
- pycti-6.3.0.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
73
- pycti-6.3.0.dist-info/RECORD,,
69
+ pycti/utils/opencti_stix2_utils.py,sha256=c-Waz_4dMqSzc7sJXPALPMNvkMn2qC8eVGdGpB6n5ZM,4896
70
+ pycti-6.3.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
71
+ pycti-6.3.2.dist-info/METADATA,sha256=pSO_4H0MTWlVOrnO-6MOcCb2iNybMG4E9Pi5MqeVsQQ,5418
72
+ pycti-6.3.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
73
+ pycti-6.3.2.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
74
+ pycti-6.3.2.dist-info/RECORD,,
File without changes
File without changes