pycti 6.8.6__py3-none-any.whl → 6.8.8__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 +1 -1
- pycti/api/opencti_api_connector.py +1 -0
- pycti/api/opencti_api_work.py +9 -0
- pycti/entities/opencti_case_incident.py +13 -0
- pycti/utils/opencti_stix2.py +30 -10
- pycti/utils/opencti_stix2_splitter.py +6 -1
- pycti/utils/opencti_stix2_utils.py +14 -0
- {pycti-6.8.6.dist-info → pycti-6.8.8.dist-info}/METADATA +1 -1
- {pycti-6.8.6.dist-info → pycti-6.8.8.dist-info}/RECORD +12 -12
- {pycti-6.8.6.dist-info → pycti-6.8.8.dist-info}/WHEEL +0 -0
- {pycti-6.8.6.dist-info → pycti-6.8.8.dist-info}/licenses/LICENSE +0 -0
- {pycti-6.8.6.dist-info → pycti-6.8.8.dist-info}/top_level.txt +0 -0
pycti/__init__.py
CHANGED
pycti/api/opencti_api_work.py
CHANGED
|
@@ -204,6 +204,15 @@ class OpenCTIApiWork:
|
|
|
204
204
|
result = self.api.query(query, {"id": work_id}, True)
|
|
205
205
|
return result["data"]["work"]
|
|
206
206
|
|
|
207
|
+
def get_is_work_alive(self, work_id: str) -> Dict:
|
|
208
|
+
query = """
|
|
209
|
+
query WorkAliveQuery($id: ID!) {
|
|
210
|
+
isWorkAlive(id: $id)
|
|
211
|
+
}
|
|
212
|
+
"""
|
|
213
|
+
result = self.api.query(query, {"id": work_id}, True)
|
|
214
|
+
return result["data"]["isWorkAlive"]
|
|
215
|
+
|
|
207
216
|
def get_connector_works(self, connector_id: str) -> List[Dict]:
|
|
208
217
|
query = """
|
|
209
218
|
query ConnectorWorksQuery(
|
|
@@ -707,6 +707,7 @@ class CaseIncident:
|
|
|
707
707
|
modified = kwargs.get("modified", None)
|
|
708
708
|
name = kwargs.get("name", None)
|
|
709
709
|
description = kwargs.get("description", None)
|
|
710
|
+
content = kwargs.get("content", None)
|
|
710
711
|
severity = kwargs.get("severity", None)
|
|
711
712
|
priority = kwargs.get("priority", None)
|
|
712
713
|
x_opencti_stix_ids = kwargs.get("x_opencti_stix_ids", None)
|
|
@@ -749,6 +750,7 @@ class CaseIncident:
|
|
|
749
750
|
"modified": modified,
|
|
750
751
|
"name": name,
|
|
751
752
|
"description": description,
|
|
753
|
+
"content": content,
|
|
752
754
|
"severity": severity,
|
|
753
755
|
"priority": priority,
|
|
754
756
|
"x_opencti_stix_ids": x_opencti_stix_ids,
|
|
@@ -884,6 +886,12 @@ class CaseIncident:
|
|
|
884
886
|
stix_object["x_opencti_workflow_id"] = (
|
|
885
887
|
self.opencti.get_attribute_in_extension("workflow_id", stix_object)
|
|
886
888
|
)
|
|
889
|
+
if "x_opencti_content" not in stix_object or "content" not in stix_object:
|
|
890
|
+
stix_object["content"] = self.opencti.get_attribute_in_extension(
|
|
891
|
+
"content", stix_object
|
|
892
|
+
)
|
|
893
|
+
if "x_opencti_content" in stix_object:
|
|
894
|
+
stix_object["content"] = stix_object["x_opencti_content"]
|
|
887
895
|
if "x_opencti_assignee_ids" not in stix_object:
|
|
888
896
|
stix_object["x_opencti_assignee_ids"] = (
|
|
889
897
|
self.opencti.get_attribute_in_extension("assignee_ids", stix_object)
|
|
@@ -926,6 +934,11 @@ class CaseIncident:
|
|
|
926
934
|
if "description" in stix_object
|
|
927
935
|
else None
|
|
928
936
|
),
|
|
937
|
+
content=(
|
|
938
|
+
self.opencti.stix2.convert_markdown(stix_object["content"])
|
|
939
|
+
if "content" in stix_object
|
|
940
|
+
else None
|
|
941
|
+
),
|
|
929
942
|
severity=stix_object["severity"] if "severity" in stix_object else None,
|
|
930
943
|
priority=stix_object["priority"] if "priority" in stix_object else None,
|
|
931
944
|
response_types=(
|
pycti/utils/opencti_stix2.py
CHANGED
|
@@ -8,7 +8,7 @@ import random
|
|
|
8
8
|
import time
|
|
9
9
|
import traceback
|
|
10
10
|
import uuid
|
|
11
|
-
from typing import Any, Dict, List, Optional, Union
|
|
11
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
12
12
|
|
|
13
13
|
import datefinder
|
|
14
14
|
import dateutil.parser
|
|
@@ -32,6 +32,7 @@ from pycti.utils.opencti_stix2_utils import (
|
|
|
32
32
|
STIX_CORE_OBJECTS,
|
|
33
33
|
STIX_CYBER_OBSERVABLE_MAPPING,
|
|
34
34
|
STIX_META_OBJECTS,
|
|
35
|
+
OpenCTIStix2Utils,
|
|
35
36
|
)
|
|
36
37
|
|
|
37
38
|
datefinder.ValueError = ValueError, OverflowError
|
|
@@ -196,7 +197,7 @@ class OpenCTIStix2:
|
|
|
196
197
|
file_path: str,
|
|
197
198
|
update: bool = False,
|
|
198
199
|
types: List = None,
|
|
199
|
-
) -> Optional[
|
|
200
|
+
) -> Optional[Tuple[list, list]]:
|
|
200
201
|
"""import a stix2 bundle from a file
|
|
201
202
|
|
|
202
203
|
:param file_path: valid path to the file
|
|
@@ -221,7 +222,8 @@ class OpenCTIStix2:
|
|
|
221
222
|
update: bool = False,
|
|
222
223
|
types: List = None,
|
|
223
224
|
work_id: str = None,
|
|
224
|
-
|
|
225
|
+
objects_max_refs: int = 0,
|
|
226
|
+
) -> Tuple[list, list]:
|
|
225
227
|
"""import a stix2 bundle from JSON data
|
|
226
228
|
|
|
227
229
|
:param json_data: JSON data
|
|
@@ -231,11 +233,13 @@ class OpenCTIStix2:
|
|
|
231
233
|
:param types: list of stix2 types, defaults to None
|
|
232
234
|
:type types: list, optional
|
|
233
235
|
:param work_id work_id: str, optional
|
|
234
|
-
:
|
|
235
|
-
:
|
|
236
|
+
:param objects_max_refs: max deps amount of objects, reject object import if larger than configured amount
|
|
237
|
+
:type objects_max_refs: int, optional
|
|
238
|
+
:return: list of imported stix2 objects and a list of stix2 objects with too many deps
|
|
239
|
+
:rtype: Tuple[List,List]
|
|
236
240
|
"""
|
|
237
241
|
data = json.loads(json_data)
|
|
238
|
-
return self.import_bundle(data, update, types, work_id)
|
|
242
|
+
return self.import_bundle(data, update, types, work_id, objects_max_refs)
|
|
239
243
|
|
|
240
244
|
def resolve_author(self, title: str) -> Optional[Identity]:
|
|
241
245
|
if "fireeye" in title.lower() or "mandiant" in title.lower():
|
|
@@ -3060,7 +3064,8 @@ class OpenCTIStix2:
|
|
|
3060
3064
|
update: bool = False,
|
|
3061
3065
|
types: List = None,
|
|
3062
3066
|
work_id: str = None,
|
|
3063
|
-
|
|
3067
|
+
objects_max_refs: int = 0,
|
|
3068
|
+
) -> Tuple[list, list]:
|
|
3064
3069
|
# Check if the bundle is correctly formatted
|
|
3065
3070
|
if "type" not in stix_bundle or stix_bundle["type"] != "bundle":
|
|
3066
3071
|
raise ValueError("JSON data type is not a STIX2 bundle")
|
|
@@ -3094,12 +3099,27 @@ class OpenCTIStix2:
|
|
|
3094
3099
|
|
|
3095
3100
|
# Import every element in a specific order
|
|
3096
3101
|
imported_elements = []
|
|
3102
|
+
too_large_elements_bundles = []
|
|
3097
3103
|
for bundle in bundles:
|
|
3098
3104
|
for item in bundle["objects"]:
|
|
3099
|
-
|
|
3100
|
-
|
|
3105
|
+
# If item is considered too large, meaning that it has a number of refs higher than inputted objects_max_refs, do not import it
|
|
3106
|
+
nb_refs = OpenCTIStix2Utils.compute_object_refs_number(item)
|
|
3107
|
+
if 0 < objects_max_refs <= nb_refs:
|
|
3108
|
+
self.opencti.work.report_expectation(
|
|
3109
|
+
work_id,
|
|
3110
|
+
{
|
|
3111
|
+
"error": "Too large element in bundle",
|
|
3112
|
+
"source": "Element "
|
|
3113
|
+
+ item["id"]
|
|
3114
|
+
+ " is too large and couldn't be processed",
|
|
3115
|
+
},
|
|
3116
|
+
)
|
|
3117
|
+
too_large_elements_bundles.append(item)
|
|
3118
|
+
else:
|
|
3119
|
+
self.import_item(item, update, types, 0, work_id)
|
|
3120
|
+
imported_elements.append({"id": item["id"], "type": item["type"]})
|
|
3101
3121
|
|
|
3102
|
-
return imported_elements
|
|
3122
|
+
return imported_elements, too_large_elements_bundles
|
|
3103
3123
|
|
|
3104
3124
|
@staticmethod
|
|
3105
3125
|
def put_attribute_in_extension(
|
|
@@ -196,6 +196,7 @@ class OpenCTIStix2Splitter:
|
|
|
196
196
|
)
|
|
197
197
|
else:
|
|
198
198
|
is_compatible = is_id_supported(item_id)
|
|
199
|
+
|
|
199
200
|
if is_compatible:
|
|
200
201
|
self.elements.append(item)
|
|
201
202
|
else:
|
|
@@ -262,7 +263,11 @@ class OpenCTIStix2Splitter:
|
|
|
262
263
|
)
|
|
263
264
|
)
|
|
264
265
|
|
|
265
|
-
return
|
|
266
|
+
return (
|
|
267
|
+
number_expectations,
|
|
268
|
+
self.incompatible_items,
|
|
269
|
+
bundles,
|
|
270
|
+
)
|
|
266
271
|
|
|
267
272
|
@deprecated("Use split_bundle_with_expectations instead")
|
|
268
273
|
def split_bundle(self, bundle, use_json=True, event_version=None) -> list:
|
|
@@ -233,3 +233,17 @@ class OpenCTIStix2Utils:
|
|
|
233
233
|
if hasattr(attribute, method):
|
|
234
234
|
return attribute
|
|
235
235
|
return None
|
|
236
|
+
|
|
237
|
+
@staticmethod
|
|
238
|
+
def compute_object_refs_number(entity: Dict):
|
|
239
|
+
refs_number = 0
|
|
240
|
+
for key in list(entity.keys()):
|
|
241
|
+
if key.endswith("_refs") and entity[key] is not None:
|
|
242
|
+
refs_number += len(entity[key])
|
|
243
|
+
elif key.endswith("_ref"):
|
|
244
|
+
refs_number += 1
|
|
245
|
+
elif key == "external_references" and entity[key] is not None:
|
|
246
|
+
refs_number += len(entity[key])
|
|
247
|
+
elif key == "kill_chain_phases" and entity[key] is not None:
|
|
248
|
+
refs_number += len(entity[key])
|
|
249
|
+
return refs_number
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
pycti/__init__.py,sha256=
|
|
1
|
+
pycti/__init__.py,sha256=5LvHzMfpp2PQ9_yBONK0Dcej_TnePHuDpK_uwzwt4S4,5676
|
|
2
2
|
pycti/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
pycti/api/opencti_api_client.py,sha256=lbygp2fOsmTKIrM-8Y7GxFzCZzdFStC0dhxyKYs0Wzo,35368
|
|
4
|
-
pycti/api/opencti_api_connector.py,sha256=
|
|
4
|
+
pycti/api/opencti_api_connector.py,sha256=MbOHtU9uQy6v_cI7bph9gZYGnpTaJlyTFnvP1bConuk,5626
|
|
5
5
|
pycti/api/opencti_api_draft.py,sha256=ZFrva6p7VZA7rCtIpyfyA-KTWvcTaWvpy51_Edi9rG4,428
|
|
6
6
|
pycti/api/opencti_api_internal_file.py,sha256=v_IFGZC3tngrZiaf9K64lnJbQgczgjym2NUECmdV_jk,802
|
|
7
7
|
pycti/api/opencti_api_notification.py,sha256=uTBSjym2RfSYHTnfBIVmWj5kATrzQ2lRQ178Jy5bsu0,1375
|
|
@@ -9,7 +9,7 @@ pycti/api/opencti_api_pir.py,sha256=3yDfUNVe9G_G9OrCcL3pBTE31kcstKXhXCiSrGhpUYY,
|
|
|
9
9
|
pycti/api/opencti_api_playbook.py,sha256=yKg54sRaE4gtmQURQ_7jFjcyQJqchWsn-Uepe6MZUfs,2183
|
|
10
10
|
pycti/api/opencti_api_public_dashboard.py,sha256=aa4trEuaf7WstmiS4WAHoe1qmYmaFWmbO0N4N_iXPGM,711
|
|
11
11
|
pycti/api/opencti_api_trash.py,sha256=r_zi57n5TfLw9LYs2UFg33Nvyy3Huc6CjpK2mRQsmao,1065
|
|
12
|
-
pycti/api/opencti_api_work.py,sha256=
|
|
12
|
+
pycti/api/opencti_api_work.py,sha256=IucltT8DcZtJV3NO4RbVi6tnGtjbyxD78_FIHAPYmK0,9261
|
|
13
13
|
pycti/api/opencti_api_workspace.py,sha256=ycqOTEXeUHF2k8H4jhoYDd1W6ijFcNUjYf4eSdLpH0k,611
|
|
14
14
|
pycti/connector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
pycti/connector/opencti_connector.py,sha256=8lCZFvcA9-S1x6vFl756hgWAlzKfrnq-C4AIdDJr-Kg,2715
|
|
@@ -19,7 +19,7 @@ pycti/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
19
19
|
pycti/entities/opencti_attack_pattern.py,sha256=Mf5ltnxG5XIgMdaplhSBFhuMBwsjGFZvkfhTX7jpTOw,23580
|
|
20
20
|
pycti/entities/opencti_campaign.py,sha256=MhkzqwMsu1w9VnOUHq4dQVViLh6KeAAI3YmLOAqJYhg,18969
|
|
21
21
|
pycti/entities/opencti_capability.py,sha256=mAR3AT__w6ULuAgc4T_QYxDwW9Jz8bsXQ8SDKF2BCL4,1515
|
|
22
|
-
pycti/entities/opencti_case_incident.py,sha256=
|
|
22
|
+
pycti/entities/opencti_case_incident.py,sha256=vM-MEdgPMOb-DRRSuf9buV71qr87gXSfiKxf5eemZrw,35585
|
|
23
23
|
pycti/entities/opencti_case_rfi.py,sha256=0pcujjHV5xbysASPXDceQVkuRS77Gl97HI6ron7XhkU,35251
|
|
24
24
|
pycti/entities/opencti_case_rft.py,sha256=eai_CkcEEl2NquhfJOhGoyUii92CITkQR8YfkDP6fgY,36171
|
|
25
25
|
pycti/entities/opencti_channel.py,sha256=zBb9YzpNCWrC1lx8b3q8X9Xif7ijlJXqwxoXge_Z-14,16891
|
|
@@ -74,13 +74,13 @@ pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py
|
|
|
74
74
|
pycti/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
75
|
pycti/utils/constants.py,sha256=VRYRvDm6hkTR0ZcHHWMzQBwqlPRskYnusBpgoX0S05A,12854
|
|
76
76
|
pycti/utils/opencti_logger.py,sha256=MApWthWJrSeBI0rumnhLhBtanjrtmfP6PJqOiQjcCOY,4091
|
|
77
|
-
pycti/utils/opencti_stix2.py,sha256=
|
|
77
|
+
pycti/utils/opencti_stix2.py,sha256=Pu7bGrlRVeYcp1Qtta6D6NHhxH5klJKALZKFrjps4hM,137042
|
|
78
78
|
pycti/utils/opencti_stix2_identifier.py,sha256=k8L1z4q1xdCBfxqUba4YS_kT-MmbJFxYh0RvfGOmrOs,837
|
|
79
|
-
pycti/utils/opencti_stix2_splitter.py,sha256=
|
|
79
|
+
pycti/utils/opencti_stix2_splitter.py,sha256=nMGbFPtGz2Vaeb6asWyPiOntHFNjREzJnbLEJHDV_T0,11539
|
|
80
80
|
pycti/utils/opencti_stix2_update.py,sha256=CnMyqkeVA0jgyxEcgqna8sABU4YPMjkEJ228GVurIn4,14658
|
|
81
|
-
pycti/utils/opencti_stix2_utils.py,sha256=
|
|
82
|
-
pycti-6.8.
|
|
83
|
-
pycti-6.8.
|
|
84
|
-
pycti-6.8.
|
|
85
|
-
pycti-6.8.
|
|
86
|
-
pycti-6.8.
|
|
81
|
+
pycti/utils/opencti_stix2_utils.py,sha256=fV-BHI55UF8tF6Ar9WHCqWy1mFPBZOph9bPlqHyA6W0,7545
|
|
82
|
+
pycti-6.8.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
83
|
+
pycti-6.8.8.dist-info/METADATA,sha256=gCpB8nxmgWc0e35p6rySTph_lBvk2MCyFogQko1bMaM,5808
|
|
84
|
+
pycti-6.8.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
85
|
+
pycti-6.8.8.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
|
|
86
|
+
pycti-6.8.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|