pycti 6.6.11__py3-none-any.whl → 6.6.15__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.6.11"
2
+ __version__ = "6.6.15"
3
3
 
4
4
  from .api.opencti_api_client import OpenCTIApiClient
5
5
  from .api.opencti_api_connector import OpenCTIApiConnector
@@ -65,9 +65,11 @@ from .utils.constants import (
65
65
  CustomObservableBankAccount,
66
66
  CustomObservableCredential,
67
67
  CustomObservableCryptocurrencyWallet,
68
+ CustomObservableCryptographicKey,
68
69
  CustomObservableHostname,
69
70
  CustomObservableMediaContent,
70
71
  CustomObservablePaymentCard,
72
+ CustomObservablePersona,
71
73
  CustomObservablePhoneNumber,
72
74
  CustomObservableText,
73
75
  CustomObservableTrackingNumber,
@@ -149,8 +151,10 @@ __all__ = [
149
151
  "CustomObservableHostname",
150
152
  "CustomObservableUserAgent",
151
153
  "CustomObservableBankAccount",
154
+ "CustomObservableCryptographicKey",
152
155
  "CustomObservableCryptocurrencyWallet",
153
156
  "CustomObservablePaymentCard",
157
+ "CustomObservablePersona",
154
158
  "CustomObservablePhoneNumber",
155
159
  "CustomObservableTrackingNumber",
156
160
  "CustomObservableText",
@@ -264,13 +264,15 @@ class OpenCTIApiClient:
264
264
  "" if retry_number is None else str(retry_number)
265
265
  )
266
266
 
267
- def query(self, query, variables=None):
267
+ def query(self, query, variables=None, disable_impersonate=False):
268
268
  """submit a query to the OpenCTI GraphQL API
269
269
 
270
270
  :param query: GraphQL query string
271
271
  :type query: str
272
272
  :param variables: GraphQL query variables, defaults to {}
273
273
  :type variables: dict, optional
274
+ :param disable_impersonate: removes impersonate header if set to True, defaults to False
275
+ :type disable_impersonate: bool, optional
274
276
  :return: returns the response json content
275
277
  :rtype: Any
276
278
  """
@@ -295,6 +297,9 @@ class OpenCTIApiClient:
295
297
  else:
296
298
  query_var[key] = val
297
299
 
300
+ query_headers = self.request_headers.copy()
301
+ if disable_impersonate and "opencti-applicant-id" in query_headers:
302
+ del query_headers["opencti-applicant-id"]
298
303
  # If yes, transform variable (file to null) and create multipart query
299
304
  if len(files_vars) > 0:
300
305
  multipart_data = {
@@ -361,7 +366,7 @@ class OpenCTIApiClient:
361
366
  self.api_url,
362
367
  data=multipart_data,
363
368
  files=multipart_files,
364
- headers=self.request_headers,
369
+ headers=query_headers,
365
370
  verify=self.ssl_verify,
366
371
  cert=self.cert,
367
372
  proxies=self.proxies,
@@ -372,7 +377,7 @@ class OpenCTIApiClient:
372
377
  r = self.session.post(
373
378
  self.api_url,
374
379
  json={"query": query, "variables": variables},
375
- headers=self.request_headers,
380
+ headers=query_headers,
376
381
  verify=self.ssl_verify,
377
382
  cert=self.cert,
378
383
  proxies=self.proxies,
@@ -20,7 +20,7 @@ class OpenCTIApiWork:
20
20
  }
21
21
  }
22
22
  """
23
- self.api.query(query, {"id": work_id, "message": message})
23
+ self.api.query(query, {"id": work_id, "message": message}, True)
24
24
 
25
25
  def to_processed(self, work_id: str, message: str, in_error: bool = False):
26
26
  if self.api.bundle_send_to_queue:
@@ -35,7 +35,7 @@ class OpenCTIApiWork:
35
35
  }
36
36
  """
37
37
  self.api.query(
38
- query, {"id": work_id, "message": message, "inError": in_error}
38
+ query, {"id": work_id, "message": message, "inError": in_error}, True
39
39
  )
40
40
 
41
41
  def ping(self, work_id: str):
@@ -60,7 +60,7 @@ class OpenCTIApiWork:
60
60
  }
61
61
  """
62
62
  try:
63
- self.api.query(query, {"id": work_id, "error": error})
63
+ self.api.query(query, {"id": work_id, "error": error}, True)
64
64
  except:
65
65
  self.api.app_logger.error("Cannot report expectation")
66
66
 
@@ -78,7 +78,9 @@ class OpenCTIApiWork:
78
78
  }
79
79
  """
80
80
  try:
81
- self.api.query(query, {"id": work_id, "expectations": expectations})
81
+ self.api.query(
82
+ query, {"id": work_id, "expectations": expectations}, True
83
+ )
82
84
  except:
83
85
  self.api.app_logger.error("Cannot report expectation")
84
86
 
@@ -96,7 +98,9 @@ class OpenCTIApiWork:
96
98
  }
97
99
  """
98
100
  try:
99
- self.api.query(query, {"id": work_id, "draftContext": draft_context})
101
+ self.api.query(
102
+ query, {"id": work_id, "draftContext": draft_context}, True
103
+ )
100
104
  except:
101
105
  self.api.app_logger.error("Cannot report draft context")
102
106
 
@@ -111,7 +115,9 @@ class OpenCTIApiWork:
111
115
  }
112
116
  """
113
117
  work = self.api.query(
114
- query, {"connectorId": connector_id, "friendlyName": friendly_name}
118
+ query,
119
+ {"connectorId": connector_id, "friendlyName": friendly_name},
120
+ True,
115
121
  )
116
122
  return work["data"]["workAdd"]["id"]
117
123
 
@@ -122,10 +128,7 @@ class OpenCTIApiWork:
122
128
  delete
123
129
  }
124
130
  }"""
125
- work = self.api.query(
126
- query,
127
- {"workId": work_id},
128
- )
131
+ work = self.api.query(query, {"workId": work_id}, True)
129
132
  return work["data"]
130
133
 
131
134
  def wait_for_work_to_finish(self, work_id: str):
@@ -179,10 +182,7 @@ class OpenCTIApiWork:
179
182
  }
180
183
  }
181
184
  """
182
- result = self.api.query(
183
- query,
184
- {"id": work_id},
185
- )
185
+ result = self.api.query(query, {"id": work_id}, True)
186
186
  return result["data"]["work"]
187
187
 
188
188
  def get_connector_works(self, connector_id: str) -> List[Dict]:
@@ -243,6 +243,7 @@ class OpenCTIApiWork:
243
243
  "filterGroups": [],
244
244
  },
245
245
  },
246
+ True,
246
247
  )
247
248
  result = result["data"]["works"]["edges"]
248
249
  return_value = []
@@ -239,7 +239,7 @@ class AttackPattern:
239
239
  @staticmethod
240
240
  def generate_id(name, x_mitre_id=None):
241
241
  if x_mitre_id is not None:
242
- data = {"x_mitre_id": x_mitre_id}
242
+ data = {"x_mitre_id": x_mitre_id.strip()}
243
243
  else:
244
244
  data = {"name": name.lower().strip()}
245
245
  data = canonicalize(data, utf8=False)
@@ -24,7 +24,7 @@ class Indicator:
24
24
 
25
25
  @staticmethod
26
26
  def generate_id(pattern):
27
- data = {"pattern": pattern}
27
+ data = {"pattern": pattern.strip()}
28
28
  data = canonicalize(data, utf8=False)
29
29
  id = str(uuid.uuid5(uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7"), data))
30
30
  return "indicator--" + id
@@ -457,9 +457,9 @@ class Note:
457
457
  if created is not None:
458
458
  if isinstance(created, datetime.datetime):
459
459
  created = created.isoformat()
460
- data = {"content": content, "created": created}
460
+ data = {"content": content.strip(), "created": created}
461
461
  else:
462
- data = {"content": content}
462
+ data = {"content": content.strip()}
463
463
  data = canonicalize(data, utf8=False)
464
464
  id = str(uuid.uuid5(uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7"), data))
465
465
  return "note--" + id
@@ -227,9 +227,9 @@ class Opinion:
227
227
  if created is not None:
228
228
  if isinstance(created, datetime.datetime):
229
229
  created = created.isoformat()
230
- data = {"opinion": opinion, "created": created}
230
+ data = {"opinion": opinion.strip(), "created": created}
231
231
  else:
232
- data = {"opinion": opinion}
232
+ data = {"opinion": opinion.strip()}
233
233
  data = canonicalize(data, utf8=False)
234
234
  id = str(uuid.uuid5(uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7"), data))
235
235
  return "opinion--" + id
@@ -747,6 +747,16 @@ class StixCyberObservable(StixCyberObservableDeprecatedMixin):
747
747
  if "dst_port" in observable_data
748
748
  else None
749
749
  ),
750
+ "networkSrc": (
751
+ observable_data["src_ref"]
752
+ if "src_ref" in observable_data
753
+ else None
754
+ ),
755
+ "networkDst": (
756
+ observable_data["dst_ref"]
757
+ if "dst_ref" in observable_data
758
+ else None
759
+ ),
750
760
  "protocols": (
751
761
  observable_data["protocols"]
752
762
  if "protocols" in observable_data
pycti/utils/constants.py CHANGED
@@ -453,3 +453,44 @@ class CustomObservableMediaContent:
453
453
  """Media-Content observable."""
454
454
 
455
455
  pass
456
+
457
+
458
+ @CustomObservable(
459
+ "persona",
460
+ [
461
+ ("persona_name", StringProperty(required=True)),
462
+ ("persona_type", StringProperty(required=True)),
463
+ ("spec_version", StringProperty(fixed="2.1")),
464
+ (
465
+ "object_marking_refs",
466
+ ListProperty(
467
+ ReferenceProperty(valid_types="marking-definition", spec_version="2.1")
468
+ ),
469
+ ),
470
+ ],
471
+ ["persona_name", "persona_type"],
472
+ )
473
+ class CustomObservablePersona:
474
+ """Persona observable."""
475
+
476
+ pass
477
+
478
+
479
+ @CustomObservable(
480
+ "cryptographic-key",
481
+ [
482
+ ("value", StringProperty(required=True)),
483
+ ("spec_version", StringProperty(fixed="2.1")),
484
+ (
485
+ "object_marking_refs",
486
+ ListProperty(
487
+ ReferenceProperty(valid_types="marking-definition", spec_version="2.1")
488
+ ),
489
+ ),
490
+ ],
491
+ ["value"],
492
+ )
493
+ class CustomObservableCryptographicKey:
494
+ """Cryptographic-Key observable."""
495
+
496
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycti
3
- Version: 6.6.11
3
+ Version: 6.6.15
4
4
  Summary: Python API client for OpenCTI.
5
5
  Home-page: https://github.com/OpenCTI-Platform/client-python
6
6
  Author: Filigran
@@ -53,7 +53,7 @@ Requires-Dist: types-python-dateutil~=2.9.0; extra == "dev"
53
53
  Requires-Dist: wheel~=0.45.1; extra == "dev"
54
54
  Provides-Extra: doc
55
55
  Requires-Dist: autoapi~=2.0.1; extra == "doc"
56
- Requires-Dist: sphinx-autodoc-typehints~=3.1.0; extra == "doc"
56
+ Requires-Dist: sphinx-autodoc-typehints~=3.2.0; extra == "doc"
57
57
  Requires-Dist: sphinx-rtd-theme~=3.0.2; extra == "doc"
58
58
  Dynamic: license-file
59
59
 
@@ -1,15 +1,15 @@
1
- pycti/__init__.py,sha256=QOpKHKU-Lb0LzYXDDpkUKt8QxmTSLvgle6BdIoZhrCo,5539
1
+ pycti/__init__.py,sha256=BHiX31DCegXtP42RaXqDjFXgTcQ-mLrYGmwUwbxTA-k,5677
2
2
  pycti/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- pycti/api/opencti_api_client.py,sha256=MWswVagpg_0giX-XnhfmsTO06UGLIYfsDCAaRavPhds,34225
3
+ pycti/api/opencti_api_client.py,sha256=yV8noIFiy-wtMbJ64KKZ7G7wUFZ10L6tYInmL_fKkMw,34567
4
4
  pycti/api/opencti_api_connector.py,sha256=8xwHuLINP3ZCImzE9_K_iCR9QEA3K6aHpK4bJhcZf20,5582
5
5
  pycti/api/opencti_api_playbook.py,sha256=456We78vESukfSOi_CctfZ9dbBJEi76EHClRc2f21Js,1628
6
- pycti/api/opencti_api_work.py,sha256=qIRJMCfyC9odXf7LMRg9ImYizqF2WHUOU7Ty5IUFGg8,8351
6
+ pycti/api/opencti_api_work.py,sha256=V8n8KaLNiOUYTXYE251bC-yHMHiXSR_sf_0jk2RgANY,8456
7
7
  pycti/connector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  pycti/connector/opencti_connector.py,sha256=8lCZFvcA9-S1x6vFl756hgWAlzKfrnq-C4AIdDJr-Kg,2715
9
9
  pycti/connector/opencti_connector_helper.py,sha256=7LXAEIvEcStXK0tr199EBU4grn-ejf93ogbMU3tiyq8,88534
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
- pycti/entities/opencti_attack_pattern.py,sha256=IQ238VBSLKhROQRdYrxuJMBEDdbAWe0-xi9DiexbpJ4,22527
12
+ pycti/entities/opencti_attack_pattern.py,sha256=HVfLhtd8rlT42xutRS8qOkDsG5_Ws4EoGfObLW5mQl4,22535
13
13
  pycti/entities/opencti_campaign.py,sha256=FIweLdt2oL70m2meamV-9NDheihL8EofjQ6G1oLLqfY,18079
14
14
  pycti/entities/opencti_capability.py,sha256=mAR3AT__w6ULuAgc4T_QYxDwW9Jz8bsXQ8SDKF2BCL4,1515
15
15
  pycti/entities/opencti_case_incident.py,sha256=N-9fSJawE7cK-AW2mE1wvB3oXjzJrim6G_UIioIAI7M,34731
@@ -26,7 +26,7 @@ pycti/entities/opencti_group.py,sha256=X7NfJ7-0Nwzggh9BqlA0GiKHc7v2PhmJnNQsffAeV
26
26
  pycti/entities/opencti_grouping.py,sha256=cjXfgmRma0laGAP5j1oYMtZzVsQxrNvZ0o0-MsToufg,30569
27
27
  pycti/entities/opencti_identity.py,sha256=1OveaX1uFOzMPBWbMqK0a_Bz3FT77GzOmanmQALArpg,24093
28
28
  pycti/entities/opencti_incident.py,sha256=mQn2PN2enf9CYoM2vFD3f8S2hIZj8pbiBUZOQ4cMT7Q,18966
29
- pycti/entities/opencti_indicator.py,sha256=BcfuS9zfdjDEtbW_nKGLU_nK9KCnObsLnQiEONqvTRM,21444
29
+ pycti/entities/opencti_indicator.py,sha256=8-ZJRJvHZ387s5CZtSBGCROtZm_5vhJpvIDP8cGVb-8,21452
30
30
  pycti/entities/opencti_infrastructure.py,sha256=-vuGCDiwWH60GmLOpUelVDPtvM9XB9DhfGDwM0S2OpI,20331
31
31
  pycti/entities/opencti_intrusion_set.py,sha256=Jg-kkh6_kfyUIL6XsRYWg_d7Nejrp9kniJlI-SlAph0,19357
32
32
  pycti/entities/opencti_kill_chain_phase.py,sha256=acNzuFdxhwI_8fvZOTEHhP8fC6EGY_r6jcKpA-nKa8Q,7991
@@ -37,16 +37,16 @@ pycti/entities/opencti_malware.py,sha256=dRol60QdZMmxcMLeG48r2fq2-mpplAwQ8K5hhxT
37
37
  pycti/entities/opencti_malware_analysis.py,sha256=xC-sF1emTx5ym9Tq_iBTgVn6Rkx6PKZCX7LPdog2GQs,22088
38
38
  pycti/entities/opencti_marking_definition.py,sha256=JYNodKOe94a22NbNf8YNI3xhh2q-D-5JuohLMM1njlE,13695
39
39
  pycti/entities/opencti_narrative.py,sha256=LtUI2g8Hle3pTGDDopt4evnRlL7ZFVyWH1JC9Z6kjmI,17441
40
- pycti/entities/opencti_note.py,sha256=ze4tAY-XyCApnBiZl1NDfkOcd2XXXh8AjlyuGjPbWmU,31066
40
+ pycti/entities/opencti_note.py,sha256=MzCGSSNz-UXiiPPYbOASyfCjLr5c6k-I8Fx-HxqU3Z8,31082
41
41
  pycti/entities/opencti_observed_data.py,sha256=7k8g2gopNUDKqjUa6PWZH0md9D4juOGOHeUy4q4Pmn8,31377
42
- pycti/entities/opencti_opinion.py,sha256=cTT0fuzBC9xdFGquwYSK47_Hdm5WW1ZeYFGICuKHKT8,22626
42
+ pycti/entities/opencti_opinion.py,sha256=QwYIcRemOmFVmoVHRnCEUGzSt4NoIHufCU_qh0Djexs,22642
43
43
  pycti/entities/opencti_report.py,sha256=LY2wB6zcdchBD8URYoNqGWENMqnalOrmxoNKz306EDM,35303
44
44
  pycti/entities/opencti_role.py,sha256=ryfPmZ_ch2sRGgqEr6_qxChTcGoeqvHW0MvlGHkLgdw,14039
45
45
  pycti/entities/opencti_settings.py,sha256=3dArFaPPdcFTV44uGRffjHpnDE-MKIXgd496QZcH6Bw,13547
46
46
  pycti/entities/opencti_stix.py,sha256=uMheSg8i1f2Ozx2Mk0iShWzHHjj6MMWDtV5nDjVxKEE,2275
47
47
  pycti/entities/opencti_stix_core_object.py,sha256=eyhsNAWaQO5X55Wn91b21j_d6bydBxfN29s2eQHrXkI,51639
48
48
  pycti/entities/opencti_stix_core_relationship.py,sha256=xHyJSW89ef9OV0PJhQRynm-c1MSO0tUFPPzQiXYeukk,44909
49
- pycti/entities/opencti_stix_cyber_observable.py,sha256=W_vs-VmO7HMVu7kGcL9NPuHXhioCeEwDJRBB8Q3XsBI,92049
49
+ pycti/entities/opencti_stix_cyber_observable.py,sha256=ZbJ4XXXTlCP34hrgC9Jfov_9m1bPUiTj_s2tUjSauEA,92449
50
50
  pycti/entities/opencti_stix_domain_object.py,sha256=-7Dec8kTqeJA_sr1KrRohgQzitOC51dOd4035EXRALw,78850
51
51
  pycti/entities/opencti_stix_nested_ref_relationship.py,sha256=7USJlfTanPFY16aFIH2YONdRakrfoBuIbB0d0I52PSM,12479
52
52
  pycti/entities/opencti_stix_object_or_stix_relationship.py,sha256=5qutzML6SyYzDhZ-QpI9Vh23hzLEs-xeFAAZOpGHZ2g,18049
@@ -65,15 +65,15 @@ pycti/entities/stix_cyber_observable/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
65
65
  pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_deprecated.py,sha256=q-2G6OOqvUC1U2hSKxD8uT5T18M_IDkl72Tn1KoumQI,1847
66
66
  pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py,sha256=MN56CW8RWZwB0Pr8UiHZy_4nSzbgFbwdhSFKpsZ_d1Y,11293
67
67
  pycti/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- pycti/utils/constants.py,sha256=zlt4nPytB-PIVd91X0RGh3bY6qWcCOn3hnuM9TuDWEw,11829
68
+ pycti/utils/constants.py,sha256=AfECYKzdwos6Z6yUGXaUGtip_bRsVQaCKBw6nwSmNqE,12799
69
69
  pycti/utils/opencti_logger.py,sha256=BHNy9fJuTUTn_JEYSCmyvVwd6y-9ZJKxO40mY4iZ0bc,2226
70
70
  pycti/utils/opencti_stix2.py,sha256=Fg7xPAqek4lJrfYh2LLQkdsmTCJHM-uwCS4Mye12khw,121492
71
71
  pycti/utils/opencti_stix2_identifier.py,sha256=k8L1z4q1xdCBfxqUba4YS_kT-MmbJFxYh0RvfGOmrOs,837
72
72
  pycti/utils/opencti_stix2_splitter.py,sha256=etnAWMDzNi2JCovSUJ5Td-XLVdzgKRdsV1XfpXOGols,11070
73
73
  pycti/utils/opencti_stix2_update.py,sha256=CnMyqkeVA0jgyxEcgqna8sABU4YPMjkEJ228GVurIn4,14658
74
74
  pycti/utils/opencti_stix2_utils.py,sha256=xgBZzm7HC76rLQYwTKkaUd_w9jJnVMoryHx7KDDIB_g,5065
75
- pycti-6.6.11.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
76
- pycti-6.6.11.dist-info/METADATA,sha256=eXRgs2FSzjhuC2tJ0ZSr9tFw1cyfjhnZRFiIVLyktpQ,5531
77
- pycti-6.6.11.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
78
- pycti-6.6.11.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
79
- pycti-6.6.11.dist-info/RECORD,,
75
+ pycti-6.6.15.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
76
+ pycti-6.6.15.dist-info/METADATA,sha256=7Af10YSevhbl-AUeqtvjkQetbzqWZaTmSZhSyVck2Sw,5531
77
+ pycti-6.6.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
78
+ pycti-6.6.15.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
79
+ pycti-6.6.15.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.4.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5