pymisp 2.5.2.dev2__py3-none-any.whl → 2.5.4__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 pymisp might be problematic. Click here for more details.

pymisp/api.py CHANGED
@@ -3541,6 +3541,14 @@ class PyMISP:
3541
3541
  response = self._prepare_request('POST', url, data=to_post)
3542
3542
  return response
3543
3543
 
3544
+ def sign_blob(self, blob: str) -> str:
3545
+ """Sign a blob
3546
+
3547
+ :param blob: blob to sign
3548
+ """
3549
+ response = self._prepare_request('POST', '/cryptographicKeys/serverSign', data=blob)
3550
+ return self._check_response(response, lenient_response_type=True)
3551
+
3544
3552
  # ## END Others ###
3545
3553
 
3546
3554
  # ## BEGIN Statistics ###
@@ -396,6 +396,7 @@ for a specific attribute. An optional **to_ids** boolean field to disable the ID
396
396
  - [objects/sigmf-recording](https://github.com/MISP/misp-objects/blob/main/objects/sigmf-recording/definition.json) - An object representing a single IQ/RF sample in the Signal Metadata Format Specification (SigMF).
397
397
  - [objects/social-media-group](https://github.com/MISP/misp-objects/blob/main/objects/social-media-group/definition.json) - Social media group object template describing a public or private group or channel.
398
398
  - [objects/software](https://github.com/MISP/misp-objects/blob/main/objects/software/definition.json) - The Software object represents high-level properties associated with software, including software products. STIX 2.1 - 6.14.
399
+ - [objects/spambee-report](https://github.com/MISP/misp-objects/main/objects/spambee-report/definition.json) - A Spambee analysis report.
399
400
  - [objects/spearphishing-attachment](https://github.com/MISP/misp-objects/blob/main/objects/spearphishing-attachment/definition.json) - Spearphishing Attachment.
400
401
  - [objects/spearphishing-link](https://github.com/MISP/misp-objects/blob/main/objects/spearphishing-link/definition.json) - Spearphishing Link.
401
402
  - [objects/splunk](https://github.com/MISP/misp-objects/blob/main/objects/splunk/definition.json) - Splunk / Splunk ES object.
@@ -7,11 +7,17 @@
7
7
  "ui-priority": 1
8
8
  },
9
9
  "certificate": {
10
- "description": "Android certificate",
10
+ "description": "Android certificate (SHA1)",
11
11
  "misp-attribute": "sha1",
12
12
  "multiple": true,
13
13
  "ui-priority": 1
14
14
  },
15
+ "certificate-sha256": {
16
+ "description": "Android certificate (SHA256)",
17
+ "misp-attribute": "sha256",
18
+ "multiple": true,
19
+ "ui-priority": 1
20
+ },
15
21
  "domain": {
16
22
  "description": "Domain used by the app",
17
23
  "misp-attribute": "domain",
@@ -39,5 +45,5 @@
39
45
  "sha256"
40
46
  ],
41
47
  "uuid": "92836f23-4730-4eae-82ac-9f00d5299735",
42
- "version": 1
48
+ "version": 2
43
49
  }
@@ -3,19 +3,25 @@
3
3
  "name": {
4
4
  "description": "Name of the OpenTIDE Object",
5
5
  "misp-attribute": "text",
6
- "ui-priority": 0
6
+ "ui-priority": 5
7
7
  },
8
8
  "opentide-object": {
9
9
  "description": "YAML Content of the Opentide Object",
10
10
  "misp-attribute": "text",
11
- "ui-priority": 3
11
+ "ui-priority": 0
12
+ },
13
+ "opentide-relation": {
14
+ "description": "UUID of other OpenTIDE Objects with a relation to this Object",
15
+ "misp-attribute": "text",
16
+ "multiple": true,
17
+ "ui-priority": 1
12
18
  },
13
19
  "opentide-type": {
14
20
  "description": "Type of the OpenTIDE Object",
15
21
  "disable_correlation": true,
16
22
  "misp-attribute": "text",
17
23
  "multiple": false,
18
- "ui-priority": 2,
24
+ "ui-priority": 1,
19
25
  "values_list": [
20
26
  "tvm",
21
27
  "cdm",
@@ -25,17 +31,28 @@
25
31
  "uuid": {
26
32
  "description": "UUID of the OpenTIDE Object",
27
33
  "misp-attribute": "text",
28
- "ui-priority": 1
34
+ "ui-priority": 4
35
+ },
36
+ "version": {
37
+ "description": "Version of the OpenTIDE Object",
38
+ "disable_correlation": true,
39
+ "misp-attribute": "text",
40
+ "sane_default": [
41
+ "1"
42
+ ],
43
+ "ui-priority": 3
29
44
  }
30
45
  },
31
46
  "description": "Object that is a container for threat or detection data, in accordance with the OpenTIDE Framework (https://code.europa.eu/ec-digit-s2/opentide)",
32
47
  "meta-category": "misc",
33
48
  "name": "opentide",
34
49
  "required": [
35
- "uuid",
50
+ "name",
36
51
  "opentide-object",
37
- "opentide-type"
52
+ "opentide-type",
53
+ "uuid",
54
+ "version"
38
55
  ],
39
56
  "uuid": "892fd46a-f69e-455c-8c4f-843a4b8f4295",
40
- "version": 1
57
+ "version": 3
41
58
  }
@@ -0,0 +1,54 @@
1
+ {
2
+ "attributes": {
3
+ "feedback-requested": {
4
+ "description": "User has requested feedback",
5
+ "disable_correlation": true,
6
+ "misp-attribute": "boolean",
7
+ "ui-priority": 0
8
+ },
9
+ "feedback-sent": {
10
+ "description": "Feedback has been sent to user",
11
+ "disable_correlation": true,
12
+ "misp-attribute": "boolean",
13
+ "ui-priority": 0
14
+ },
15
+ "feedback-time": {
16
+ "description": "Timestamp of the feedback",
17
+ "disable_correlation": true,
18
+ "misp-attribute": "datetime",
19
+ "ui-priority": 0
20
+ },
21
+ "privacy": {
22
+ "description": "User has requested privacy",
23
+ "disable_correlation": true,
24
+ "misp-attribute": "boolean",
25
+ "ui-priority": 0
26
+ },
27
+ "report-status": {
28
+ "categories": [
29
+ "External analysis"
30
+ ],
31
+ "description": "Result of the Spambee analysis for the submitted email",
32
+ "disable_correlation": true,
33
+ "misp-attribute": "text",
34
+ "ui-priority": 0
35
+ },
36
+ "report-uid": {
37
+ "categories": [
38
+ "Internal reference"
39
+ ],
40
+ "description": "Internal reference to the Spambee report",
41
+ "disable_correlation": true,
42
+ "misp-attribute": "text",
43
+ "ui-priority": 0
44
+ }
45
+ },
46
+ "description": "A Spambee analysis report",
47
+ "meta-category": "network",
48
+ "name": "spambee-report",
49
+ "requiredOneOf": [
50
+ "report-uid"
51
+ ],
52
+ "uuid": "305d6e6c-bb4d-4b9a-abf5-9f34d1322352",
53
+ "version": 3
54
+ }
@@ -14,13 +14,13 @@
14
14
  "ui-priority": 0
15
15
  },
16
16
  "cvss-score": {
17
- "description": "Score of the Common Vulnerability Scoring System (version 3).",
17
+ "description": "Score of the Common Vulnerability Scoring System.",
18
18
  "disable_correlation": true,
19
19
  "misp-attribute": "float",
20
20
  "ui-priority": 1
21
21
  },
22
22
  "cvss-string": {
23
- "description": "String of the Common Vulnerability Scoring System (version 3).",
23
+ "description": "String of the Common Vulnerability Scoring System.",
24
24
  "disable_correlation": true,
25
25
  "misp-attribute": "text",
26
26
  "ui-priority": 1
@@ -65,7 +65,8 @@
65
65
  "Reviewed",
66
66
  "Vulnerability ID Assigned",
67
67
  "Reported",
68
- "Fixed"
68
+ "Fixed",
69
+ "Encoded"
69
70
  ],
70
71
  "ui-priority": 0
71
72
  },
@@ -94,5 +95,5 @@
94
95
  "id"
95
96
  ],
96
97
  "uuid": "81650945-f186-437b-8945-9f31715d32da",
97
- "version": 8
98
+ "version": 9
98
99
  }
@@ -1907,7 +1907,23 @@
1907
1907
  "misp"
1908
1908
  ],
1909
1909
  "name": "releasable-to"
1910
+ },
1911
+ {
1912
+ "description": "The source object is weakened by the target weakness.",
1913
+ "format": [
1914
+ "misp"
1915
+ ],
1916
+ "name": "weakened-by",
1917
+ "opposite": "weakens"
1918
+ },
1919
+ {
1920
+ "description": "The source weakness weakens the target object.",
1921
+ "format": [
1922
+ "misp"
1923
+ ],
1924
+ "name": "weakens",
1925
+ "opposite": "weakened-by"
1910
1926
  }
1911
1927
  ],
1912
- "version": 50
1928
+ "version": 51
1913
1929
  }
pymisp/mispevent.py CHANGED
@@ -60,28 +60,37 @@ class AnalystDataBehaviorMixin(AbstractMISP):
60
60
 
61
61
  def add_note(self, note: str, language: str | None = None, **kwargs) -> MISPNote: # type: ignore[no-untyped-def]
62
62
  the_note = MISPNote()
63
- the_note.from_dict(note=note, language=language,
64
- object_uuid=self.uuid, object_type=self.analyst_data_object_type,
65
- **kwargs)
63
+ object_uuid = kwargs.pop('object_uuid', self.uuid)
64
+ object_type = kwargs.pop('object_type', self.analyst_data_object_type)
65
+ the_note.from_dict(
66
+ note=note, language=language, object_uuid=object_uuid,
67
+ object_type=object_type, contained=True, parent=self, **kwargs
68
+ )
66
69
  self.notes.append(the_note)
67
70
  self.edited = True
68
71
  return the_note
69
72
 
70
73
  def add_opinion(self, opinion: int, comment: str | None = None, **kwargs) -> MISPOpinion: # type: ignore[no-untyped-def]
71
74
  the_opinion = MISPOpinion()
72
- the_opinion.from_dict(opinion=opinion, comment=comment,
73
- object_uuid=self.uuid, object_type=self.analyst_data_object_type,
74
- **kwargs)
75
+ object_uuid = kwargs.pop('object_uuid', self.uuid)
76
+ object_type = kwargs.pop('object_type', self.analyst_data_object_type)
77
+ the_opinion.from_dict(
78
+ opinion=opinion, comment=comment, object_uuid=object_uuid,
79
+ object_type=object_type, contained=True, parent=self, **kwargs
80
+ )
75
81
  self.opinions.append(the_opinion)
76
82
  self.edited = True
77
83
  return the_opinion
78
84
 
79
85
  def add_relationship(self, related_object_type: AbstractMISP | str, related_object_uuid: str | None, relationship_type: str, **kwargs) -> MISPRelationship: # type: ignore[no-untyped-def]
80
86
  the_relationship = MISPRelationship()
81
- the_relationship.from_dict(related_object_type=related_object_type, related_object_uuid=related_object_uuid,
82
- relationship_type=relationship_type,
83
- object_uuid=self.uuid, object_type=self.analyst_data_object_type,
84
- **kwargs)
87
+ the_relationship.from_dict(
88
+ related_object_type=related_object_type,
89
+ related_object_uuid=related_object_uuid,
90
+ relationship_type=relationship_type, object_uuid=self.uuid,
91
+ object_type=self.analyst_data_object_type, contained=True,
92
+ parent=self, **kwargs
93
+ )
85
94
  self.relationships.append(the_relationship)
86
95
  self.edited = True
87
96
  return the_relationship
@@ -93,12 +102,8 @@ class AnalystDataBehaviorMixin(AbstractMISP):
93
102
  relationships = kwargs.pop('Relationship', [])
94
103
  super().from_dict(**kwargs)
95
104
  for note in notes:
96
- note.pop('object_uuid', None)
97
- note.pop('object_type', None)
98
105
  self.add_note(**note)
99
106
  for opinion in opinions:
100
- opinion.pop('object_uuid', None)
101
- opinion.pop('object_type', None)
102
107
  self.add_opinion(**opinion)
103
108
  for relationship in relationships:
104
109
  relationship.pop('object_uuid', None)
@@ -1559,7 +1564,8 @@ class MISPGalaxy(AbstractMISP):
1559
1564
  class MISPEvent(AnalystDataBehaviorMixin):
1560
1565
 
1561
1566
  _fields_for_feed: set[str] = {'uuid', 'info', 'threat_level_id', 'analysis', 'timestamp',
1562
- 'publish_timestamp', 'published', 'date', 'extends_uuid'}
1567
+ 'publish_timestamp', 'published', 'date', 'extends_uuid',
1568
+ 'protected'}
1563
1569
 
1564
1570
  _analyst_data_object_type = 'Event'
1565
1571
 
@@ -1581,6 +1587,7 @@ class MISPEvent(AnalystDataBehaviorMixin):
1581
1587
  self.EventReport: list[MISPEventReport] = []
1582
1588
  self.Tag: list[MISPTag] = []
1583
1589
  self.Galaxy: list[MISPGalaxy] = []
1590
+ self.CryptographicKey: list[MISPCryptographicKey] = []
1584
1591
 
1585
1592
  self.publish_timestamp: float | int | datetime
1586
1593
  self.timestamp: float | int | datetime
@@ -1600,6 +1607,8 @@ class MISPEvent(AnalystDataBehaviorMixin):
1600
1607
 
1601
1608
  def _set_default(self) -> None:
1602
1609
  """There are a few keys that could, or need to be set by default for the feed generator"""
1610
+ if not hasattr(self, 'protected'):
1611
+ self.protected = False
1603
1612
  if not hasattr(self, 'published'):
1604
1613
  self.published = True
1605
1614
  if not hasattr(self, 'uuid'):
@@ -1649,13 +1658,14 @@ class MISPEvent(AnalystDataBehaviorMixin):
1649
1658
  to_return += attribute.hash_values(algorithm)
1650
1659
  return to_return
1651
1660
 
1652
- def to_feed(self, valid_distributions: list[int] = [0, 1, 2, 3, 4, 5], with_meta: bool = False, with_distribution: bool=False, with_local_tags: bool = True, with_event_reports: bool = True) -> dict[str, Any]:
1661
+ def to_feed(self, valid_distributions: list[int] = [0, 1, 2, 3, 4, 5], with_meta: bool = False, with_distribution: bool=False, with_local_tags: bool = True, with_event_reports: bool = True, with_cryptographic_keys: bool = True) -> dict[str, Any]:
1653
1662
  """ Generate a json output for MISP Feed.
1654
1663
 
1655
1664
  :param valid_distributions: only makes sense if the distribution key is set; i.e., the event is exported from a MISP instance.
1656
1665
  :param with_distribution: exports distribution and Sharing Group info; otherwise all SharingGroup information is discarded (protecting privacy)
1657
1666
  :param with_local_tags: tag export includes local exportable tags along with global exportable tags
1658
1667
  :param with_event_reports: include event reports in the returned MISP event
1668
+ :param with_cryptographic_keys: include the associated cryptographic keys in the returned protected MISP event
1659
1669
  """
1660
1670
  required = ['info', 'Orgc']
1661
1671
  for r in required:
@@ -1720,6 +1730,13 @@ class MISPEvent(AnalystDataBehaviorMixin):
1720
1730
  event_report.pop('sharing_group_id', None)
1721
1731
  to_return['EventReport'].append(event_report.to_dict())
1722
1732
 
1733
+ if with_cryptographic_keys and self.cryptographic_keys:
1734
+ to_return['CryptographicKey'] = []
1735
+ for cryptographic_key in self.cryptographic_keys:
1736
+ cryptographic_key.pop('parent_id', None)
1737
+ cryptographic_key.pop('id', None)
1738
+ to_return['CryptographicKey'].append(cryptographic_key.to_dict())
1739
+
1723
1740
  return {'Event': to_return}
1724
1741
 
1725
1742
  @property
@@ -1756,6 +1773,10 @@ class MISPEvent(AnalystDataBehaviorMixin):
1756
1773
  def event_reports(self) -> list[MISPEventReport]:
1757
1774
  return self.EventReport
1758
1775
 
1776
+ @property
1777
+ def cryptographic_keys(self) -> list[MISPCryptographicKey]:
1778
+ return self.CryptographicKey
1779
+
1759
1780
  @property
1760
1781
  def shadow_attributes(self) -> list[MISPShadowAttribute]:
1761
1782
  return self.ShadowAttribute
@@ -1891,6 +1912,8 @@ class MISPEvent(AnalystDataBehaviorMixin):
1891
1912
  [self.add_galaxy(**e) for e in kwargs.pop('Galaxy')]
1892
1913
  if kwargs.get('EventReport'):
1893
1914
  [self.add_event_report(**e) for e in kwargs.pop('EventReport')]
1915
+ if kwargs.get('CryptographicKey'):
1916
+ [self.add_cryprographic_key(**e) for e in kwargs.pop('CryptographicKey')]
1894
1917
 
1895
1918
  # All other keys
1896
1919
  if kwargs.get('id'):
@@ -2041,6 +2064,15 @@ class MISPEvent(AnalystDataBehaviorMixin):
2041
2064
  self.edited = True
2042
2065
  return event_report
2043
2066
 
2067
+ def add_cryprographic_key(self, parent_type: str, key_data: str, type: str, uuid: str, fingerprint: str, timestamp: str, **kwargs) -> MISPCryptographicKey: # type: ignore[no-untyped-def]
2068
+ """Add a Cryptographic Key. parent_type, key_data, type, uuid, fingerprint, timestamp are required but you can pass all
2069
+ other parameters supported by MISPEventReport"""
2070
+ cryptographic_key = MISPCryptographicKey()
2071
+ cryptographic_key.from_dict(parent_type=parent_type, key_data=key_data, type=type, uuid=uuid, fingerprint=fingerprint, timestamp=timestamp, **kwargs)
2072
+ self.cryptographic_keys.append(cryptographic_key)
2073
+ self.edited = True
2074
+ return cryptographic_key
2075
+
2044
2076
  def add_galaxy(self, galaxy: MISPGalaxy | dict[str, Any] | None = None, **kwargs) -> MISPGalaxy: # type: ignore[no-untyped-def]
2045
2077
  """Add a galaxy and sub-clusters into an event, either by passing
2046
2078
  a MISPGalaxy or a dictionary.
@@ -2226,6 +2258,13 @@ class MISPWarninglist(AbstractMISP):
2226
2258
  super().from_dict(**kwargs)
2227
2259
 
2228
2260
 
2261
+ class MISPCryptographicKey(AbstractMISP):
2262
+ def from_dict(self, **kwargs) -> None: # type: ignore[no-untyped-def]
2263
+ if 'CryptographicKey' in kwargs:
2264
+ kwargs = kwargs['CryptographicKey']
2265
+ super().from_dict(**kwargs)
2266
+
2267
+
2229
2268
  class MISPTaxonomy(AbstractMISP):
2230
2269
 
2231
2270
  enabled: bool
@@ -2489,6 +2528,10 @@ class MISPAnalystData(AbstractMISP):
2489
2528
  'Object', 'Note', 'Opinion', 'Relationship', 'Organisation',
2490
2529
  'SharingGroup'}
2491
2530
 
2531
+ @property
2532
+ def analyst_data_object_type(self) -> str:
2533
+ return self._analyst_data_object_type
2534
+
2492
2535
  @property
2493
2536
  def org(self) -> MISPOrganisation:
2494
2537
  return self.Org
@@ -2504,6 +2547,10 @@ class MISPAnalystData(AbstractMISP):
2504
2547
  else:
2505
2548
  raise PyMISPError('Orgc must be of type MISPOrganisation.')
2506
2549
 
2550
+ @property
2551
+ def parent(self) -> MISPAttribute | MISPEvent | MISPEventReport | MISPObject:
2552
+ return self.__parent
2553
+
2507
2554
  def __new__(cls, *args, **kwargs):
2508
2555
  if cls is MISPAnalystData:
2509
2556
  raise TypeError(f"only children of '{cls.__name__}' may be instantiated")
@@ -2518,8 +2565,54 @@ class MISPAnalystData(AbstractMISP):
2518
2565
  self.created: float | int | datetime
2519
2566
  self.modified: float | int | datetime
2520
2567
  self.SharingGroup: MISPSharingGroup
2568
+ self._analyst_data_object_type: str # Must be defined in the child class
2569
+
2570
+ def add_note(self, note: str, language: str | None = None, object_uuid: str | None = None, object_type: str | None = None, parent: MISPEvent | MISPAttribute | MISPObject | MISPEventReport | None = None, **kwargs: dict[str, Any]) -> MISPNote:
2571
+ misp_note = MISPNote()
2572
+ if object_uuid is None:
2573
+ object_uuid = self.uuid
2574
+ if object_type is None:
2575
+ object_type = self.analyst_data_object_type
2576
+ if parent is None and hasattr(self, 'parent'):
2577
+ parent = self.parent
2578
+ misp_note.from_dict(
2579
+ note=note, language=language, object_uuid=object_uuid,
2580
+ object_type=object_type, parent=parent, contained=True, **kwargs
2581
+ )
2582
+ if parent is None:
2583
+ if not hasattr(self, 'Note'):
2584
+ self.Note: list[MISPNote] = []
2585
+ self.Note.append(misp_note)
2586
+ else:
2587
+ self.parent.notes.append(misp_note)
2588
+ self.edited = True
2589
+ return misp_note
2590
+
2591
+ def add_opinion(self, opinion: int, comment: str | None = None, object_uuid: str | None = None, object_type: str | None = None, parent: MISPEvent | MISPAttribute | MISPObject | MISPEventReport | None = None, **kwargs: dict[str, Any]) -> MISPOpinion:
2592
+ misp_opinion = MISPOpinion()
2593
+ if object_uuid is None:
2594
+ object_uuid = self.uuid
2595
+ if object_type is None:
2596
+ object_type = self.analyst_data_object_type
2597
+ if parent is None and hasattr(self, 'parent'):
2598
+ parent = self.parent
2599
+ misp_opinion.from_dict(
2600
+ opinion=opinion, comment=comment, object_uuid=object_uuid,
2601
+ object_type=object_type, parent=parent, contained=True, **kwargs
2602
+ )
2603
+ if parent is None:
2604
+ if not hasattr(self, 'Opinion'):
2605
+ self.Opinion: list[MISPOpinion] = []
2606
+ self.Opinion.append(misp_opinion)
2607
+ else:
2608
+ self.parent.opinions.append(misp_opinion)
2609
+ self.edited = True
2610
+ return misp_opinion
2521
2611
 
2522
2612
  def from_dict(self, **kwargs) -> None: # type: ignore[no-untyped-def]
2613
+ notes = kwargs.pop('Note', [])
2614
+ opinions = kwargs.pop('Opinion', [])
2615
+ self.__parent = kwargs.pop('parent', None)
2523
2616
  self.distribution = kwargs.pop('distribution', None)
2524
2617
  if self.distribution is not None:
2525
2618
  self.distribution = int(self.distribution)
@@ -2573,6 +2666,11 @@ class MISPAnalystData(AbstractMISP):
2573
2666
 
2574
2667
  super().from_dict(**kwargs)
2575
2668
 
2669
+ for note in notes:
2670
+ self.add_note(**note)
2671
+ for opinion in opinions:
2672
+ self.add_opinion(**opinion)
2673
+
2576
2674
  def _set_default(self) -> None:
2577
2675
  if not hasattr(self, 'created'):
2578
2676
  self.created = datetime.timestamp(datetime.now())
@@ -2580,7 +2678,7 @@ class MISPAnalystData(AbstractMISP):
2580
2678
  self.modified = self.created
2581
2679
 
2582
2680
 
2583
- class MISPNote(AnalystDataBehaviorMixin, MISPAnalystData):
2681
+ class MISPNote(MISPAnalystData):
2584
2682
 
2585
2683
  _fields_for_feed: set[str] = MISPAnalystData._fields_for_feed.union({'note', 'language'})
2586
2684
 
@@ -2591,8 +2689,8 @@ class MISPNote(AnalystDataBehaviorMixin, MISPAnalystData):
2591
2689
  self.language: str
2592
2690
  super().__init__(**kwargs)
2593
2691
 
2594
- def from_dict(self, **kwargs) -> None: # type: ignore[no-untyped-def]
2595
- if 'Note' in kwargs:
2692
+ def from_dict(self, contained=False, **kwargs) -> None: # type: ignore[no-untyped-def]
2693
+ if not contained and 'Note' in kwargs:
2596
2694
  kwargs = kwargs['Note']
2597
2695
  self.note = kwargs.pop('note', None)
2598
2696
  if self.note is None:
@@ -2605,7 +2703,7 @@ class MISPNote(AnalystDataBehaviorMixin, MISPAnalystData):
2605
2703
  return f'<{self.__class__.__name__}(NotInitialized)'
2606
2704
 
2607
2705
 
2608
- class MISPOpinion(AnalystDataBehaviorMixin, MISPAnalystData):
2706
+ class MISPOpinion(MISPAnalystData):
2609
2707
 
2610
2708
  _fields_for_feed: set[str] = MISPAnalystData._fields_for_feed.union({'opinion', 'comment'})
2611
2709
 
@@ -2616,8 +2714,8 @@ class MISPOpinion(AnalystDataBehaviorMixin, MISPAnalystData):
2616
2714
  self.comment: str
2617
2715
  super().__init__(**kwargs)
2618
2716
 
2619
- def from_dict(self, **kwargs) -> None: # type: ignore[no-untyped-def]
2620
- if 'Opinion' in kwargs:
2717
+ def from_dict(self, contained=False, **kwargs) -> None: # type: ignore[no-untyped-def]
2718
+ if not contained and 'Opinion' in kwargs:
2621
2719
  kwargs = kwargs['Opinion']
2622
2720
  self.opinion = kwargs.pop('opinion', None)
2623
2721
  if self.opinion is not None:
@@ -2639,7 +2737,7 @@ class MISPOpinion(AnalystDataBehaviorMixin, MISPAnalystData):
2639
2737
  return f'<{self.__class__.__name__}(NotInitialized)'
2640
2738
 
2641
2739
 
2642
- class MISPRelationship(AnalystDataBehaviorMixin, MISPAnalystData):
2740
+ class MISPRelationship(MISPAnalystData):
2643
2741
 
2644
2742
  _fields_for_feed: set[str] = MISPAnalystData._fields_for_feed.union({'related_object_uuid', 'related_object_type', 'relationship_type'})
2645
2743
 
@@ -2651,8 +2749,8 @@ class MISPRelationship(AnalystDataBehaviorMixin, MISPAnalystData):
2651
2749
  self.relationship_type: str
2652
2750
  super().__init__(**kwargs)
2653
2751
 
2654
- def from_dict(self, **kwargs) -> None: # type: ignore[no-untyped-def]
2655
- if 'Relationship' in kwargs:
2752
+ def from_dict(self, contained=False, **kwargs) -> None: # type: ignore[no-untyped-def]
2753
+ if not contained and 'Relationship' in kwargs:
2656
2754
  kwargs = kwargs['Relationship']
2657
2755
  self.related_object_type = kwargs.pop('related_object_type', None)
2658
2756
  if self.related_object_type is None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pymisp
3
- Version: 2.5.2.dev2
3
+ Version: 2.5.4
4
4
  Summary: Python API for MISP.
5
5
  Home-page: https://github.com/MISP/PyMISP
6
6
  License: BSD-2-Clause
@@ -33,12 +33,12 @@ Provides-Extra: virustotal
33
33
  Requires-Dist: RTFDE (>=0.1.1,<0.2.0) ; extra == "email"
34
34
  Requires-Dist: Sphinx (>=8,<9) ; (python_version >= "3.10") and (extra == "docs")
35
35
  Requires-Dist: beautifulsoup4 (>=4.12.3,<5.0.0) ; extra == "openioc"
36
- Requires-Dist: deprecated (>=1.2.14,<2.0.0)
36
+ Requires-Dist: deprecated (>=1.2.15,<2.0.0)
37
37
  Requires-Dist: docutils (>=0.21.1,<0.22.0) ; (python_version >= "3.10") and (extra == "docs")
38
38
  Requires-Dist: extract_msg (>=0.52,<0.53) ; extra == "email"
39
- Requires-Dist: lief (>=0.15.0,<0.16.0) ; extra == "fileobjects"
39
+ Requires-Dist: lief (>=0.16.0,<0.17.0) ; extra == "fileobjects"
40
40
  Requires-Dist: oletools (>=0.60.1,<0.61.0) ; extra == "email"
41
- Requires-Dist: publicsuffixlist (>=1.0.2.20241113,<2.0.0.0)
41
+ Requires-Dist: publicsuffixlist (>=1.0.2.20241218,<2.0.0.0)
42
42
  Requires-Dist: pydeep2 (>=0.5.1,<0.6.0) ; extra == "fileobjects"
43
43
  Requires-Dist: pyfaup (>=1.2,<2.0) ; extra == "url"
44
44
  Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
@@ -1,6 +1,6 @@
1
1
  pymisp/__init__.py,sha256=NxD9URYrwmEvYsZdUDTtBqBuIsvzRjXnRr8QVPsuOGE,4004
2
2
  pymisp/abstract.py,sha256=hdf3heAGnEi3rFIxaAsCOKfO4Y1kT_UoDNpr564GiIk,15745
3
- pymisp/api.py,sha256=WIPtuepWtmyfXdi0zsLwKSXpXNhoM6QSnh7_n2nAYMY,207823
3
+ pymisp/api.py,sha256=ocZXH-sgLy-q0g7dlxV6TZu0uKo5ZAdwEIja33ZSQ68,208104
4
4
  pymisp/data/describeTypes.json,sha256=hoOy6U_FDVmfk9EdaFgGfEe_GMifmRnIrW8FAJ1ylJ4,45889
5
5
  pymisp/data/misp-objects/.git,sha256=NZIIWPWRiUFN6wy7MhT0zLzu8WP8PKqbMxWaO0by0dY,55
6
6
  pymisp/data/misp-objects/.gitchangelog.rc,sha256=27iB5X06HaLaMpDdZWMkg_YWLyZRm9H1qBOsqFntuV0,10009
@@ -9,7 +9,7 @@ pymisp/data/misp-objects/.github/workflows/nosetests.yml,sha256=7D2o7SKN_PFkx2AN
9
9
  pymisp/data/misp-objects/.travis.yml,sha256=ZzmVFWiNEr_hneN0OOX4ba1M9ivJAzn6umPe4KIsOiM,215
10
10
  pymisp/data/misp-objects/LICENSE-software-only.md,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
11
11
  pymisp/data/misp-objects/LICENSE.md,sha256=f6xQZQL7dWr4tRnO_khZlVegmj7jyIJhf7pu6M0VeuE,1860
12
- pymisp/data/misp-objects/README.md,sha256=PRnpp4FsvTZLwVlkOUwh9E7Dj2BxOePiDNF-_dhaGYM,78749
12
+ pymisp/data/misp-objects/README.md,sha256=rozuXu-Em7ohTbyZoRIq4289YuguWeToZfdkcniMOFw,78887
13
13
  pymisp/data/misp-objects/docs/time-related-objects.ods,sha256=fFZD3OhiC5VonsSfI0YFv5uHXLvbLG2nrNo0D89jmYA,19977
14
14
  pymisp/data/misp-objects/docs/time-related-objects.pdf,sha256=IArPOumDuXIIliuTkEP9uCT693dginC1nUA3WGV5PDA,23583
15
15
  pymisp/data/misp-objects/jq_all_the_things.sh,sha256=MOSjYD01hmCRTlZ5p-GkkemX8FR85fn2_tAja7kfTYc,818
@@ -19,7 +19,7 @@ pymisp/data/misp-objects/objects/ai-chat-prompt/definition.json,sha256=0hTBTI8aV
19
19
  pymisp/data/misp-objects/objects/ail-leak/definition.json,sha256=I79pga1sxHU4s4T1X3OK14Mk8gsDjzbSZW4L5ofQYOA,2181
20
20
  pymisp/data/misp-objects/objects/ais/definition.json,sha256=_ZHH8PDKvFcq1JPbp30hhJNNawqDH9var7LcrSo5hA8,4448
21
21
  pymisp/data/misp-objects/objects/ais-info/definition.json,sha256=1Pj9Eu9eoopk60iEeO9vjolqOQVTGDfBY6OCpRdnVFE,1590
22
- pymisp/data/misp-objects/objects/android-app/definition.json,sha256=KH_tTkASxLioI6Jr2XoeoEhTPOis9m-eMLtSmVmbAfQ,984
22
+ pymisp/data/misp-objects/objects/android-app/definition.json,sha256=pXYC4W11ikLEOk3s0mQh7nQ-P5nTq1qCCDYCByZX6UA,1160
23
23
  pymisp/data/misp-objects/objects/android-permission/definition.json,sha256=1XHNGCTgqM6bPdeiCQHfyg6NtzgmFXKNVWZbc7TXqZk,5019
24
24
  pymisp/data/misp-objects/objects/annotation/definition.json,sha256=rzISiChqHWyT6ecHBfv3unEU0Y8hAzOzARUHh1sgwCM,1946
25
25
  pymisp/data/misp-objects/objects/anonymisation/definition.json,sha256=fY1lFoW0TvH0hYM65ww2r4RQYaqniLk5syTGf9pqSmc,5985
@@ -222,7 +222,7 @@ pymisp/data/misp-objects/objects/network-traffic/definition.json,sha256=jZSGhItw
222
222
  pymisp/data/misp-objects/objects/news-agency/definition.json,sha256=yo-x2a7rei3tFIwHEisW2Hf3cGAQieEAs1QRGOQjSYE,2090
223
223
  pymisp/data/misp-objects/objects/news-media/definition.json,sha256=Mb4TQz-Cj035HtfyuhVyRTCUlxkzCizBZghLxgD6rGA,4024
224
224
  pymisp/data/misp-objects/objects/open-data-security/definition.json,sha256=fNTNdk-Hjd83DkmhbhGst6PJv09ZJzuXC6RitsEinZg,3052
225
- pymisp/data/misp-objects/objects/opentide/definition.json,sha256=vZi8fwy2yiEZ8aLV0UDodxLENeqZoaOMzafyelSYiQI,1056
225
+ pymisp/data/misp-objects/objects/opentide/definition.json,sha256=KAhBYWYMp_PF0lTMjanOBKZirdju2120Y9tNOlpMzy8,1496
226
226
  pymisp/data/misp-objects/objects/organization/definition.json,sha256=2Dq4Gs4ynlcaP1rnxfvDCU8cCARO39_Z3azkHYJjhh4,3956
227
227
  pymisp/data/misp-objects/objects/original-imported-file/definition.json,sha256=lip2yP3wdLoCGxsiCrNMcBC6nyQJUPcJFZYzlkpxeOA,921
228
228
  pymisp/data/misp-objects/objects/paloalto-threat-event/definition.json,sha256=F1qMo6LN32i3e7ODjv38twX3BEzrgdLIqXN9PqL-3x4,2597
@@ -307,6 +307,7 @@ pymisp/data/misp-objects/objects/sigmf-expanded-recording/definition.json,sha256
307
307
  pymisp/data/misp-objects/objects/sigmf-recording/definition.json,sha256=cJqnh3hUIBfMC0jyDqh1Ks1jMNyh3DbMTIn0o4zR_iE,685
308
308
  pymisp/data/misp-objects/objects/social-media-group/definition.json,sha256=RyUgIMe8wxqaX5WfHfX4oDuVkvw_kMa7NX7TSQvWxNg,2951
309
309
  pymisp/data/misp-objects/objects/software/definition.json,sha256=vx_qg2KBLCM6HJfhH_1WbfXFxpC755aWGVGBi7U6UuU,1930
310
+ pymisp/data/misp-objects/objects/spambee-report/definition.json,sha256=Ps73IJyEfUiOGR1uh_3Rs5v0ISHgAtW_2tXWg3cYVMQ,1437
310
311
  pymisp/data/misp-objects/objects/spearphishing-attachment/definition.json,sha256=vtFQBw04jZp1vOWpjE8czGjc4jHr9t8bk08qRjLjahI,3849
311
312
  pymisp/data/misp-objects/objects/spearphishing-link/definition.json,sha256=Bj3tjqq9WDULRyJEPKBtBXQvmmWyUwx0rVB4jinSvAU,1681
312
313
  pymisp/data/misp-objects/objects/splunk/definition.json,sha256=okI3cfABE4NYBNVskjroZqsbOgtrhuBx9PAfZ08a8Ys,1442
@@ -356,7 +357,7 @@ pymisp/data/misp-objects/objects/victim/definition.json,sha256=YRuufTMqfbzs_7y2f
356
357
  pymisp/data/misp-objects/objects/virustotal-graph/definition.json,sha256=Ls9rs3YOuf6FKSUuzUn55Rly57k0HsTaPVc81zhqTME,1227
357
358
  pymisp/data/misp-objects/objects/virustotal-report/definition.json,sha256=7tRlsF-JTGij0XKqgS8zMUojDQkkmz6bbwXk0LkKQCU,1562
358
359
  pymisp/data/misp-objects/objects/virustotal-submission/definition.json,sha256=ylxitcnBlvglTsWmv_p8iuNC0WsatIbdyzUWUNSwqdw,1796
359
- pymisp/data/misp-objects/objects/vulnerability/definition.json,sha256=zoIZpxalsku0ePQTR00zLJNRPrx1AaQ-ePi5HiBnYiA,3039
360
+ pymisp/data/misp-objects/objects/vulnerability/definition.json,sha256=CqalJLJWawkrWIoRpzC8TogX7MYg251M6pRK0UgjmVA,3034
360
361
  pymisp/data/misp-objects/objects/weakness/definition.json,sha256=ZaHctdCL5-ckkNgaFYdAF7uGtYfplDaJCrYNRW3yKKU,1313
361
362
  pymisp/data/misp-objects/objects/whois/definition.json,sha256=s_sJ_496vRbFmgklugF0j6aO1--THhPdx_X-O2G5_9w,2583
362
363
  pymisp/data/misp-objects/objects/windows-service/definition.json,sha256=Ya0hFjuw1CXMBKapRIvJRavfOSsWSl4N7KrbJY7rNGs,2318
@@ -368,7 +369,7 @@ pymisp/data/misp-objects/objects/youtube-channel/definition.json,sha256=R35mGTp8
368
369
  pymisp/data/misp-objects/objects/youtube-comment/definition.json,sha256=3cVid4QJB28CowczKiXb4s8-1Ald1MvehL7qUaBqIGI,2470
369
370
  pymisp/data/misp-objects/objects/youtube-playlist/definition.json,sha256=oDlL__sYqBVOJPJllxW4wW3ElUhz6cKM0UAruPO2BTw,1576
370
371
  pymisp/data/misp-objects/objects/youtube-video/definition.json,sha256=VQsamCqE-C3OIR-DFp8Rvn-gGxQ_k8hUTnqwyLkk1o4,2581
371
- pymisp/data/misp-objects/relationships/definition.json,sha256=LbCK1DpKIGlzx2-ru_FTdYfj0cQhIfRASYM96J5o53Y,47845
372
+ pymisp/data/misp-objects/relationships/definition.json,sha256=J6d5qzEklS9PHQda1qHE9eIeMQZw94sVCCGTN_mVa9Q,48218
372
373
  pymisp/data/misp-objects/schema_objects.json,sha256=uwRHHv4mvNkg0A9Kdeb3Y80_IUhJglsIn-gN88Kh65g,8346
373
374
  pymisp/data/misp-objects/schema_relationships.json,sha256=MCusp9GAyuHTo3lLyBrsvl5WJC-OHjXYHlEHW6fNv8M,1181
374
375
  pymisp/data/misp-objects/tools/adoc_objects.py,sha256=Mv9pibT7-GCkj8WjBJf8Yo8iJ23zA2I8uqOYQODX1pI,7662
@@ -381,7 +382,7 @@ pymisp/data/misp-objects/validate_all.sh,sha256=0wWn-qZS9Pp0voEHK2QBCUxjvlaYj_kb
381
382
  pymisp/data/schema-lax.json,sha256=2QICdCbtfXRJkTVjwb7xjF3ypys2wOtrUyE1ZDz_qes,8561
382
383
  pymisp/data/schema.json,sha256=79N2hObemthb_syUHksDqM4djFttsWZQDg1sTYZYxys,9178
383
384
  pymisp/exceptions.py,sha256=IgGGadv5lnLAvO7Q6AjF0vEbjoWwwDWLYwMn-8pkU_k,1965
384
- pymisp/mispevent.py,sha256=RF4KJ6-L5x7qLA9glQiQ1FhuYDyFNPu1GXmBRbxntQE,116601
385
+ pymisp/mispevent.py,sha256=U2Tu1U80GRqKnagpkQJmz2hHjH_twq72nKN5K5VjzWk,121187
385
386
  pymisp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
386
387
  pymisp/tools/__init__.py,sha256=_KCihYo82e8G5cHV321ak2sgbao2GyFjf4sSTMiN_IM,2233
387
388
  pymisp/tools/_psl_faup.py,sha256=JyK8RQm8DPWvNuoF4rQpiE0rBm-Az-sr38Kl46dmWcs,7034
@@ -412,7 +413,7 @@ pymisp/tools/update_objects.py,sha256=sp_XshzgtRjAU0Mqg8FgRTaokjVKLImyQ02xIcPSrH
412
413
  pymisp/tools/urlobject.py,sha256=PIucy1356zaljUm1NbeKmEpHpAUK9yiK2lAugcMp2t8,2489
413
414
  pymisp/tools/vehicleobject.py,sha256=bs7f4d47IBi2-VumssSM3HlqkH0viyHTLmIHQxe8Iz8,3687
414
415
  pymisp/tools/vtreportobject.py,sha256=NsdYzgqm47dywYeW8UnWmEDeIsf07xZreD2iJzFm2wg,3217
415
- pymisp-2.5.2.dev2.dist-info/LICENSE,sha256=1oPSVvs96qLjbJVi3mPn0yvWs-6aoIF6BNXi6pVlFmY,1615
416
- pymisp-2.5.2.dev2.dist-info/METADATA,sha256=2hE8KJk5K9nOvJAu2KIjv2LLAa0Y1LERtiDzNEIrc2c,9171
417
- pymisp-2.5.2.dev2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
418
- pymisp-2.5.2.dev2.dist-info/RECORD,,
416
+ pymisp-2.5.4.dist-info/LICENSE,sha256=1oPSVvs96qLjbJVi3mPn0yvWs-6aoIF6BNXi6pVlFmY,1615
417
+ pymisp-2.5.4.dist-info/METADATA,sha256=2xiY-iIVYNriRJZJ_GVTvxPYOKOAr5MjQloPa8ApVrw,9166
418
+ pymisp-2.5.4.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
419
+ pymisp-2.5.4.dist-info/RECORD,,