pymisp 2.5.4__py3-none-any.whl → 2.5.7__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.

Files changed (158) hide show
  1. CHANGELOG.txt +5380 -0
  2. examples/__init__.py +0 -0
  3. examples/add_attributes_from_csv.py +74 -0
  4. examples/add_email_object.py +29 -0
  5. examples/add_fail2ban_object.py +86 -0
  6. examples/add_feed.py +25 -0
  7. examples/add_file_object.py +47 -0
  8. examples/add_filetype_object_from_csv.py +53 -0
  9. examples/add_generic_object.py +26 -0
  10. examples/add_github_user.py +65 -0
  11. examples/add_gitlab_user.py +56 -0
  12. examples/add_named_attribute.py +25 -0
  13. examples/add_organisations.py +57 -0
  14. examples/add_ssh_authorized_keys.py +29 -0
  15. examples/add_user.py +22 -0
  16. examples/add_vehicle_object.py +22 -0
  17. examples/addtag2.py +45 -0
  18. examples/asciidoc_generator.py +114 -0
  19. examples/cache_all.py +10 -0
  20. examples/copyTagsFromAttributesToEvent.py +68 -0
  21. examples/copy_list.py +93 -0
  22. examples/create_events.py +26 -0
  23. examples/cytomic_orion.py +549 -0
  24. examples/del.py +22 -0
  25. examples/delete_user.py +16 -0
  26. examples/edit_organisation.py +20 -0
  27. examples/edit_user.py +20 -0
  28. examples/falsepositive_disabletoids.py +136 -0
  29. examples/fetch_events_feed.py +15 -0
  30. examples/fetch_warninglist_hits.py +38 -0
  31. examples/freetext.py +22 -0
  32. examples/generate_file_objects.py +78 -0
  33. examples/generate_meta_feed.py +15 -0
  34. examples/get.py +37 -0
  35. examples/get_csv.py +37 -0
  36. examples/get_network_activity.py +187 -0
  37. examples/last.py +48 -0
  38. examples/load_csv.py +94 -0
  39. examples/lookup.py +28 -0
  40. examples/misp2cef.py +71 -0
  41. examples/misp2clamav.py +52 -0
  42. examples/openioc_to_misp.py +27 -0
  43. examples/proofpoint_tap.py +203 -0
  44. examples/proofpoint_vap.py +65 -0
  45. examples/search.py +48 -0
  46. examples/search_attributes_yara.py +40 -0
  47. examples/search_sighting.py +42 -0
  48. examples/server_sync_check_conn.py +32 -0
  49. examples/sharing_groups.py +15 -0
  50. examples/show_sightings.py +168 -0
  51. examples/stats_report.py +405 -0
  52. examples/sync_sighting.py +171 -0
  53. examples/tags.py +25 -0
  54. examples/test_sign.py +19 -0
  55. examples/trustar_misp.py +59 -0
  56. examples/up.py +21 -0
  57. examples/upload.py +60 -0
  58. examples/users_list.py +15 -0
  59. examples/vmray_automation.py +281 -0
  60. examples/vt_to_misp.py +182 -0
  61. examples/warninglists.py +22 -0
  62. examples/yara.py +38 -0
  63. examples/yara_dump.py +98 -0
  64. pymisp/api.py +33 -5
  65. pymisp/data/misp-objects/objects/instagram-account/definition.json +66 -0
  66. pymisp/data/misp-objects/objects/lnk/definition.json +13 -1
  67. pymisp/data/misp-objects/objects/rmm/definition.json +88 -0
  68. pymisp/data/misp-objects/objects/target-system/definition.json +2 -2
  69. pymisp/data/misp-objects/schema_objects.json +1 -1
  70. pymisp/mispevent.py +8 -0
  71. {pymisp-2.5.4.dist-info → pymisp-2.5.7.dist-info}/METADATA +23 -28
  72. {pymisp-2.5.4.dist-info → pymisp-2.5.7.dist-info}/RECORD +140 -27
  73. {pymisp-2.5.4.dist-info → pymisp-2.5.7.dist-info}/WHEEL +1 -1
  74. tests/57c4445b-c548-4654-af0b-4be3950d210f.json +1 -0
  75. tests/__init__.py +0 -0
  76. tests/csv_testfiles/invalid_fieldnames.csv +11 -0
  77. tests/csv_testfiles/valid_fieldnames.csv +4 -0
  78. tests/email_testfiles/mail_1.eml.zip +0 -0
  79. tests/email_testfiles/mail_1.msg +0 -0
  80. tests/email_testfiles/mail_1_bom.eml +858 -0
  81. tests/email_testfiles/mail_1_headers_only.eml +28 -0
  82. tests/email_testfiles/mail_2.eml +32 -0
  83. tests/email_testfiles/mail_3.eml +170 -0
  84. tests/email_testfiles/mail_3.msg +0 -0
  85. tests/email_testfiles/mail_4.msg +0 -0
  86. tests/email_testfiles/mail_5.msg +0 -0
  87. tests/email_testfiles/mail_multiple_to.eml +15 -0
  88. tests/email_testfiles/source +1 -0
  89. tests/git-vuln-finder-quagga.json +1493 -0
  90. tests/misp_event.json +76 -0
  91. tests/mispevent_testfiles/attribute.json +21 -0
  92. tests/mispevent_testfiles/attribute_del.json +23 -0
  93. tests/mispevent_testfiles/def_param.json +53 -0
  94. tests/mispevent_testfiles/event.json +8 -0
  95. tests/mispevent_testfiles/event_obj_attr_tag.json +57 -0
  96. tests/mispevent_testfiles/event_obj_def_param.json +62 -0
  97. tests/mispevent_testfiles/event_obj_tag.json +29 -0
  98. tests/mispevent_testfiles/event_tags.json +18 -0
  99. tests/mispevent_testfiles/existing_event.json +4599 -0
  100. tests/mispevent_testfiles/existing_event_edited.json +4601 -0
  101. tests/mispevent_testfiles/galaxy.json +25 -0
  102. tests/mispevent_testfiles/malware.json +19 -0
  103. tests/mispevent_testfiles/malware_exist.json +163 -0
  104. tests/mispevent_testfiles/misp_custom_obj.json +38 -0
  105. tests/mispevent_testfiles/overwrite_file/definition.json +457 -0
  106. tests/mispevent_testfiles/proposals.json +35 -0
  107. tests/mispevent_testfiles/shadow.json +148 -0
  108. tests/mispevent_testfiles/sighting.json +5 -0
  109. tests/mispevent_testfiles/simple.json +2 -0
  110. tests/mispevent_testfiles/test_object_template/definition.json +29 -0
  111. tests/new_misp_event.json +34 -0
  112. tests/reportlab_testfiles/HTML_event.json +1 -0
  113. tests/reportlab_testfiles/galaxy_1.json +1250 -0
  114. tests/reportlab_testfiles/image_event.json +2490 -0
  115. tests/reportlab_testfiles/japanese_test.json +156 -0
  116. tests/reportlab_testfiles/japanese_test_heavy.json +318 -0
  117. tests/reportlab_testfiles/long_event.json +3730 -0
  118. tests/reportlab_testfiles/mainly_objects_1.json +1092 -0
  119. tests/reportlab_testfiles/mainly_objects_2.json +977 -0
  120. tests/reportlab_testfiles/sighting_1.json +305 -0
  121. tests/reportlab_testfiles/sighting_2.json +221 -0
  122. tests/reportlab_testfiles/to_delete1.json +804 -0
  123. tests/reportlab_testfiles/to_delete2.json +1 -0
  124. tests/reportlab_testfiles/to_delete3.json +1 -0
  125. tests/reportlab_testfiles/very_long_event.json +1006 -0
  126. tests/reportlab_testoutputs/to_delete1.json.pdf +391 -0
  127. tests/reportlab_testoutputs/to_delete2.json.pdf +506 -0
  128. tests/reportlab_testoutputs/to_delete3.json.pdf +277 -0
  129. tests/search_index_result.json +69 -0
  130. tests/sharing_groups.json +98 -0
  131. tests/stix1.xml-utf8 +110 -0
  132. tests/stix2.json +1 -0
  133. tests/test_analyst_data.py +123 -0
  134. tests/test_emailobject.py +157 -0
  135. tests/test_fileobject.py +20 -0
  136. tests/test_mispevent.py +473 -0
  137. tests/test_reportlab.py +431 -0
  138. tests/testlive_comprehensive.py +3734 -0
  139. tests/testlive_sync.py +474 -0
  140. pymisp/data/misp-objects/.git +0 -1
  141. pymisp/data/misp-objects/.gitchangelog.rc +0 -289
  142. pymisp/data/misp-objects/.github/workflows/codeql.yml +0 -41
  143. pymisp/data/misp-objects/.github/workflows/nosetests.yml +0 -39
  144. pymisp/data/misp-objects/.travis.yml +0 -16
  145. pymisp/data/misp-objects/LICENSE-software-only.md +0 -661
  146. pymisp/data/misp-objects/LICENSE.md +0 -36
  147. pymisp/data/misp-objects/README.md +0 -567
  148. pymisp/data/misp-objects/docs/time-related-objects.ods +0 -0
  149. pymisp/data/misp-objects/docs/time-related-objects.pdf +0 -0
  150. pymisp/data/misp-objects/jq_all_the_things.sh +0 -29
  151. pymisp/data/misp-objects/tools/adoc_objects.py +0 -145
  152. pymisp/data/misp-objects/tools/alfred_links_to_relarelationships.py +0 -48
  153. pymisp/data/misp-objects/tools/list_of_objects.py +0 -50
  154. pymisp/data/misp-objects/tools/updated.sh +0 -6
  155. pymisp/data/misp-objects/tools/validate_opposites.sh +0 -17
  156. pymisp/data/misp-objects/unique_uuid.py +0 -16
  157. pymisp/data/misp-objects/validate_all.sh +0 -38
  158. {pymisp-2.5.4.dist-info → pymisp-2.5.7.dist-info}/LICENSE +0 -0
@@ -0,0 +1,473 @@
1
+ #!/usr/bin/env python
2
+
3
+ from __future__ import annotations
4
+
5
+ import unittest
6
+ import json
7
+ from io import BytesIO
8
+ import glob
9
+ import hashlib
10
+ from datetime import date, datetime
11
+
12
+ from pymisp import (MISPAttribute, MISPEvent, MISPGalaxy, MISPObject, MISPOrganisation,
13
+ MISPSighting, MISPTag)
14
+ from pymisp.exceptions import InvalidMISPObject
15
+ from pymisp.tools import GitVulnFinderObject
16
+
17
+
18
+ class TestMISPEvent(unittest.TestCase):
19
+
20
+ def setUp(self) -> None:
21
+ self.maxDiff = None
22
+ self.mispevent = MISPEvent()
23
+
24
+ def init_event(self) -> None:
25
+ self.mispevent.info = 'This is a test'
26
+ self.mispevent.distribution = 1
27
+ self.mispevent.threat_level_id = 1
28
+ self.mispevent.analysis = 1
29
+ self.mispevent.set_date("2017-12-31") # test the set date method
30
+
31
+ def test_simple(self) -> None:
32
+ with open('tests/mispevent_testfiles/simple.json') as f:
33
+ ref_json = json.load(f)
34
+ del self.mispevent.uuid
35
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
36
+
37
+ def test_event(self) -> None:
38
+ self.init_event()
39
+ self.mispevent.publish()
40
+ with open('tests/mispevent_testfiles/event.json') as f:
41
+ ref_json = json.load(f)
42
+ del self.mispevent.uuid
43
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
44
+
45
+ def test_loadfile(self) -> None:
46
+ self.mispevent.load_file('tests/mispevent_testfiles/event.json')
47
+ with open('tests/mispevent_testfiles/event.json') as f:
48
+ ref_json = json.load(f)
49
+ del self.mispevent.uuid
50
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
51
+
52
+ def test_loadfile_validate(self) -> None:
53
+ misp_event = MISPEvent()
54
+ misp_event.load_file('tests/mispevent_testfiles/event.json', validate=True)
55
+
56
+ def test_loadfile_validate_strict(self) -> None:
57
+ misp_event = MISPEvent(strict_validation=True)
58
+ misp_event.load_file('tests/mispevent_testfiles/event.json', validate=True)
59
+
60
+ def test_event_tag(self) -> None:
61
+ self.init_event()
62
+ self.mispevent.add_tag('bar')
63
+ self.mispevent.add_tag(name='baz')
64
+ new_tag = MISPTag()
65
+ new_tag.from_dict(name='foo')
66
+ self.mispevent.add_tag(new_tag)
67
+ with open('tests/mispevent_testfiles/event_tags.json') as f:
68
+ ref_json = json.load(f)
69
+ del self.mispevent.uuid
70
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
71
+
72
+ def test_event_galaxy(self) -> None:
73
+ self.init_event()
74
+ with open('tests/mispevent_testfiles/galaxy.json') as f:
75
+ galaxy = json.load(f)
76
+ misp_galaxy = MISPGalaxy()
77
+ misp_galaxy.from_dict(**galaxy)
78
+ self.mispevent.add_galaxy(misp_galaxy)
79
+ self.assertEqual(self.mispevent.galaxies[0].to_json(sort_keys=True, indent=2), json.dumps(galaxy, sort_keys=True, indent=2))
80
+
81
+ def test_attribute(self) -> None:
82
+ self.init_event()
83
+ a: MISPAttribute = self.mispevent.add_attribute('filename', 'bar.exe') # type: ignore[assignment]
84
+ del a.uuid
85
+ a = self.mispevent.add_attribute_tag('osint', 'bar.exe') # type: ignore[assignment]
86
+ attr_tags = self.mispevent.get_attribute_tag('bar.exe')
87
+ self.assertEqual(self.mispevent.attributes[0].tags[0].name, 'osint')
88
+ self.assertEqual(attr_tags[0].name, 'osint')
89
+ with open('tests/mispevent_testfiles/attribute.json') as f:
90
+ ref_json = json.load(f)
91
+ del self.mispevent.uuid
92
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
93
+ # Fake setting an attribute ID for testing
94
+ self.mispevent.attributes[0].id = 42
95
+ self.mispevent.delete_attribute('42')
96
+ with open('tests/mispevent_testfiles/attribute_del.json') as f:
97
+ ref_json = json.load(f)
98
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
99
+
100
+ def test_attribute_galaxy(self) -> None:
101
+ self.init_event()
102
+ with open('tests/mispevent_testfiles/galaxy.json') as f:
103
+ galaxy = json.load(f)
104
+ misp_galaxy = MISPGalaxy()
105
+ misp_galaxy.from_dict(**galaxy)
106
+ attribute = MISPAttribute()
107
+ attribute.from_dict(**{'type': 'github-username', 'value': 'adulau'})
108
+ attribute.add_galaxy(misp_galaxy)
109
+ self.mispevent.add_attribute(**attribute)
110
+ self.assertEqual(
111
+ self.mispevent.attributes[0].galaxies[0].to_json(sort_keys=True, indent=2),
112
+ json.dumps(galaxy, sort_keys=True, indent=2)
113
+ )
114
+
115
+ def test_to_dict_json_format(self) -> None:
116
+ misp_event = MISPEvent()
117
+ av_signature_object = MISPObject("av-signature")
118
+ av_signature_object.add_attribute("signature", "EICAR")
119
+ av_signature_object.add_attribute("software", "ClamAv")
120
+ misp_event.add_object(av_signature_object)
121
+
122
+ self.assertEqual(json.loads(misp_event.to_json()), misp_event.to_dict(json_format=True))
123
+
124
+ def test_object_tag(self) -> None:
125
+ self.mispevent.add_object(name='file', strict=True)
126
+ a: MISPAttribute = self.mispevent.objects[0].add_attribute('filename', value='') # type: ignore[assignment]
127
+ self.assertEqual(a, None)
128
+ a = self.mispevent.objects[0].add_attribute('filename', value=None) # type: ignore[assignment]
129
+ self.assertEqual(a, None)
130
+ a = self.mispevent.objects[0].add_attribute('filename', value='bar', Tag=[{'name': 'blah'}]) # type: ignore[assignment]
131
+ del a.uuid
132
+ self.assertEqual(self.mispevent.objects[0].attributes[0].tags[0].name, 'blah')
133
+ self.assertTrue(self.mispevent.objects[0].has_attributes_by_relation(['filename']))
134
+ self.assertEqual(len(self.mispevent.objects[0].get_attributes_by_relation('filename')), 1)
135
+ self.mispevent.add_object(name='url', strict=True)
136
+ a = self.mispevent.objects[1].add_attribute('url', value='https://www.circl.lu') # type: ignore[assignment]
137
+ del a.uuid
138
+ self.mispevent.objects[0].uuid = 'a'
139
+ self.mispevent.objects[1].uuid = 'b'
140
+ reference = self.mispevent.objects[0].add_reference(self.mispevent.objects[1], 'baz', comment='foo')
141
+ del reference.uuid
142
+ self.assertEqual(self.mispevent.objects[0].references[0].relationship_type, 'baz')
143
+ with open('tests/mispevent_testfiles/event_obj_attr_tag.json') as f:
144
+ ref_json = json.load(f)
145
+ del self.mispevent.uuid
146
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
147
+
148
+ @unittest.skip("Not supported on MISP: https://github.com/MISP/MISP/issues/2638 - https://github.com/MISP/PyMISP/issues/168")
149
+ def test_object_level_tag(self) -> None:
150
+ self.mispevent.add_object(name='file', strict=True)
151
+ self.mispevent.objects[0].add_attribute('filename', value='bar')
152
+ self.mispevent.objects[0].add_tag('osint') # type: ignore[attr-defined]
153
+ self.mispevent.objects[0].uuid = 'a'
154
+ with open('tests/mispevent_testfiles/event_obj_tag.json') as f:
155
+ ref_json = json.load(f)
156
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
157
+
158
+ def test_object_galaxy(self) -> None:
159
+ self.init_event()
160
+ misp_object = MISPObject('github-user')
161
+ misp_object.add_attribute('username', 'adulau')
162
+ misp_object.add_attribute('repository', 'cve-search')
163
+ self.mispevent.add_object(misp_object)
164
+ with open('tests/mispevent_testfiles/galaxy.json') as f:
165
+ galaxy = json.load(f)
166
+ misp_galaxy = MISPGalaxy()
167
+ misp_galaxy.from_dict(**galaxy)
168
+ self.mispevent.objects[0].attributes[0].add_galaxy(misp_galaxy)
169
+ self.assertEqual(
170
+ self.mispevent.objects[0].attributes[0].galaxies[0].to_json(sort_keys=True, indent=2),
171
+ json.dumps(galaxy, sort_keys=True, indent=2)
172
+ )
173
+
174
+ def test_malware(self) -> None:
175
+ with open('tests/mispevent_testfiles/simple.json', 'rb') as f:
176
+ pseudofile = BytesIO(f.read())
177
+ self.init_event()
178
+ a: MISPAttribute = self.mispevent.add_attribute('malware-sample', 'bar.exe', data=pseudofile) # type: ignore[assignment]
179
+ del a.uuid
180
+ attribute = self.mispevent.attributes[0]
181
+ self.assertEqual(attribute.malware_binary, pseudofile)
182
+ with open('tests/mispevent_testfiles/malware.json') as f:
183
+ ref_json = json.load(f)
184
+ del self.mispevent.uuid
185
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
186
+
187
+ def test_existing_malware(self) -> None:
188
+ self.mispevent.load_file('tests/mispevent_testfiles/malware_exist.json')
189
+ with open('tests/mispevent_testfiles/simple.json', 'rb') as f:
190
+ pseudofile = BytesIO(f.read())
191
+ self.assertTrue(self.mispevent.objects[0].get_attributes_by_relation('malware-sample')[0].malware_binary)
192
+ if _mb := self.mispevent.objects[0].get_attributes_by_relation('malware-sample')[0].malware_binary:
193
+ self.assertEqual(_mb.read(), pseudofile.read())
194
+
195
+ def test_sighting(self) -> None:
196
+ sighting = MISPSighting()
197
+ sighting.from_dict(value='1', type='bar', timestamp=11111111)
198
+ with open('tests/mispevent_testfiles/sighting.json') as f:
199
+ ref_json = json.load(f)
200
+ self.assertEqual(sighting.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
201
+
202
+ def test_existing_event(self) -> None:
203
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
204
+ with open('tests/mispevent_testfiles/existing_event.json') as f:
205
+ ref_json = json.load(f)
206
+
207
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
208
+
209
+ def test_shadow_attributes_existing(self) -> None:
210
+ self.mispevent.load_file('tests/mispevent_testfiles/shadow.json')
211
+ with open('tests/mispevent_testfiles/shadow.json') as f:
212
+ ref_json = json.load(f)
213
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
214
+
215
+ @unittest.skip("Not supported on MISP.")
216
+ def test_shadow_attributes(self) -> None:
217
+ self.init_event()
218
+ p = self.mispevent.add_proposal(type='filename', value='baz.jpg')
219
+ del p.uuid
220
+ a: MISPAttribute = self.mispevent.add_attribute('filename', 'bar.exe') # type: ignore[assignment]
221
+ del a.uuid
222
+ p = self.mispevent.attributes[0].add_proposal(type='filename', value='bar.pdf')
223
+ del p.uuid
224
+ with open('tests/mispevent_testfiles/proposals.json') as f:
225
+ ref_json = json.load(f)
226
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
227
+
228
+ def test_default_attributes(self) -> None:
229
+ self.mispevent.add_object(name='file', strict=True)
230
+ a: MISPAttribute = self.mispevent.objects[0].add_attribute('filename', value='bar', Tag=[{'name': 'blah'}]) # type: ignore[assignment]
231
+ del a.uuid
232
+ a = self.mispevent.objects[0].add_attribute('pattern-in-file', value='baz') # type: ignore[assignment]
233
+ self.assertEqual(a.category, 'Artifacts dropped')
234
+ del a.uuid
235
+ self.mispevent.add_object(name='file', strict=False, default_attributes_parameters=self.mispevent.objects[0].attributes[0])
236
+ a = self.mispevent.objects[1].add_attribute('filename', value='baz') # type: ignore[assignment]
237
+ del a.uuid
238
+ self.mispevent.objects[0].uuid = 'a'
239
+ self.mispevent.objects[1].uuid = 'b'
240
+ with open('tests/mispevent_testfiles/event_obj_def_param.json') as f:
241
+ ref_json = json.load(f)
242
+ del self.mispevent.uuid
243
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
244
+
245
+ def test_obj_default_values(self) -> None:
246
+ self.init_event()
247
+ self.mispevent.add_object(name='whois', strict=True)
248
+ a: MISPAttribute = self.mispevent.objects[0].add_attribute('registrar', value='registar.example.com') # type: ignore[assignment]
249
+ del a.uuid
250
+ a = self.mispevent.objects[0].add_attribute('domain', value='domain.example.com') # type: ignore[assignment]
251
+ del a.uuid
252
+ a = self.mispevent.objects[0].add_attribute('nameserver', value='ns1.example.com') # type: ignore[assignment]
253
+ del a.uuid
254
+ a = self.mispevent.objects[0].add_attribute('nameserver', value='ns2.example.com', disable_correlation=False, to_ids=True, category='External analysis') # type: ignore[assignment]
255
+ del a.uuid
256
+ self.mispevent.objects[0].uuid = 'a'
257
+ with open('tests/mispevent_testfiles/def_param.json') as f:
258
+ ref_json = json.load(f)
259
+ del self.mispevent.uuid
260
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
261
+
262
+ def test_obj_references_export(self) -> None:
263
+ self.init_event()
264
+ obj1 = MISPObject(name="file")
265
+ obj2 = MISPObject(name="url", standalone=False)
266
+ obj1.add_reference(obj2, "downloads")
267
+ obj2.add_reference(obj1, "downloaded-by")
268
+ self.assertFalse("ObjectReference" in obj1.jsonable())
269
+ self.assertTrue("ObjectReference" in obj2.jsonable())
270
+ self.mispevent.add_object(obj1)
271
+ obj2.standalone = True
272
+ self.assertTrue("ObjectReference" in obj1.jsonable())
273
+ self.assertFalse("ObjectReference" in obj2.jsonable())
274
+
275
+ def test_event_not_edited(self) -> None:
276
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
277
+ self.assertFalse(self.mispevent.edited)
278
+
279
+ def test_event_edited(self) -> None:
280
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
281
+ self.mispevent.info = 'blah'
282
+ self.assertTrue(self.mispevent.edited)
283
+
284
+ def test_event_tag_edited(self) -> None:
285
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
286
+ self.assertFalse(self.mispevent.edited)
287
+ self.mispevent.add_tag('foo')
288
+ self.assertTrue(self.mispevent.edited)
289
+
290
+ def test_event_attribute_edited(self) -> None:
291
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
292
+ self.mispevent.attributes[0].value = 'blah'
293
+ self.assertTrue(self.mispevent.attributes[0].edited)
294
+ self.assertFalse(self.mispevent.attributes[1].edited)
295
+ self.assertTrue(self.mispevent.edited)
296
+
297
+ def test_event_attribute_tag_edited(self) -> None:
298
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
299
+ self.assertFalse(self.mispevent.edited)
300
+ self.mispevent.attributes[0].tags[0].name = 'blah'
301
+ self.assertTrue(self.mispevent.attributes[0].tags[0].edited)
302
+ self.assertFalse(self.mispevent.attributes[0].tags[1].edited)
303
+ self.assertTrue(self.mispevent.attributes[0].edited)
304
+ self.assertTrue(self.mispevent.edited)
305
+
306
+ def test_event_attribute_tag_edited_second(self) -> None:
307
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
308
+ self.assertFalse(self.mispevent.edited)
309
+ self.mispevent.attributes[0].add_tag(name='blah')
310
+ self.assertTrue(self.mispevent.attributes[0].edited)
311
+ self.assertTrue(self.mispevent.edited)
312
+
313
+ def test_event_object_edited(self) -> None:
314
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
315
+ self.assertFalse(self.mispevent.edited)
316
+ self.mispevent.objects[0].comment = 'blah'
317
+ self.assertTrue(self.mispevent.objects[0].edited)
318
+ self.assertFalse(self.mispevent.objects[1].edited)
319
+ self.assertTrue(self.mispevent.edited)
320
+
321
+ def test_event_object_attribute_edited(self) -> None:
322
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
323
+ self.assertFalse(self.mispevent.edited)
324
+ self.mispevent.objects[0].attributes[0].comment = 'blah'
325
+ self.assertTrue(self.mispevent.objects[0].attributes[0].edited)
326
+ self.assertTrue(self.mispevent.objects[0].edited)
327
+ self.assertTrue(self.mispevent.edited)
328
+
329
+ def test_event_object_attribute_edited_tag(self) -> None:
330
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
331
+ self.assertFalse(self.mispevent.edited)
332
+ self.mispevent.objects[0].attributes[0].add_tag('blah')
333
+ self.assertTrue(self.mispevent.objects[0].attributes[0].edited)
334
+ self.assertTrue(self.mispevent.objects[0].edited)
335
+ self.assertTrue(self.mispevent.edited)
336
+ with open('tests/mispevent_testfiles/existing_event_edited.json') as f:
337
+ ref_json = json.load(f)
338
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
339
+
340
+ def test_obj_by_id(self) -> None:
341
+ self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
342
+ misp_obj = self.mispevent.get_object_by_id(1556)
343
+ self.assertEqual(misp_obj.uuid, '5a3cd604-e11c-4de5-bbbf-c170950d210f')
344
+
345
+ def test_userdefined_object_custom_template(self) -> None:
346
+ self.init_event()
347
+ with open('tests/mispevent_testfiles/test_object_template/definition.json') as f:
348
+ template = json.load(f)
349
+ self.mispevent.add_object(name='test_object_template', strict=True,
350
+ misp_objects_template_custom=template)
351
+ with self.assertRaises(InvalidMISPObject) as e:
352
+ # Fail on required
353
+ self.mispevent.to_json(sort_keys=True, indent=2)
354
+ self.assertEqual(e.exception.message, '{\'member3\'} are required.')
355
+
356
+ a: MISPAttribute = self.mispevent.objects[0].add_attribute('member3', value='foo') # type: ignore[assignment]
357
+ del a.uuid
358
+ with self.assertRaises(InvalidMISPObject) as e:
359
+ # Fail on requiredOneOf
360
+ self.mispevent.to_json(sort_keys=True, indent=2)
361
+ self.assertEqual(e.exception.message, 'At least one of the following attributes is required: member1, member2')
362
+
363
+ a = self.mispevent.objects[0].add_attribute('member1', value='bar') # type: ignore[assignment]
364
+ del a.uuid
365
+ a = self.mispevent.objects[0].add_attribute('member1', value='baz') # type: ignore[assignment]
366
+ del a.uuid
367
+ with self.assertRaises(InvalidMISPObject) as e:
368
+ # member1 is not a multiple
369
+ self.mispevent.to_json(sort_keys=True, indent=2)
370
+ self.assertEqual(e.exception.message, 'Multiple occurrences of member1 is not allowed')
371
+
372
+ self.mispevent.objects[0].attributes = self.mispevent.objects[0].attributes[:2]
373
+ self.mispevent.objects[0].uuid = 'a'
374
+ with open('tests/mispevent_testfiles/misp_custom_obj.json') as f:
375
+ ref_json = json.load(f)
376
+ del self.mispevent.uuid
377
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
378
+
379
+ def test_userdefined_object_custom_dir(self) -> None:
380
+ self.init_event()
381
+ self.mispevent.add_object(name='test_object_template', strict=True, misp_objects_path_custom='tests/mispevent_testfiles')
382
+ with self.assertRaises(InvalidMISPObject) as e:
383
+ # Fail on required
384
+ self.mispevent.to_json(sort_keys=True, indent=2)
385
+ self.assertEqual(e.exception.message, '{\'member3\'} are required.')
386
+
387
+ a: MISPAttribute = self.mispevent.objects[0].add_attribute('member3', value='foo') # type: ignore[assignment]
388
+ del a.uuid
389
+ with self.assertRaises(InvalidMISPObject) as e:
390
+ # Fail on requiredOneOf
391
+ self.mispevent.to_json(sort_keys=True, indent=2)
392
+ self.assertEqual(e.exception.message, 'At least one of the following attributes is required: member1, member2')
393
+
394
+ a = self.mispevent.objects[0].add_attribute('member1', value='bar') # type: ignore[assignment]
395
+ del a.uuid
396
+ a = self.mispevent.objects[0].add_attribute('member1', value='baz') # type: ignore[assignment]
397
+ del a.uuid
398
+ with self.assertRaises(InvalidMISPObject) as e:
399
+ # member1 is not a multiple
400
+ self.mispevent.to_json(sort_keys=True, indent=2)
401
+ self.assertEqual(e.exception.message, 'Multiple occurrences of member1 is not allowed')
402
+
403
+ self.mispevent.objects[0].attributes = self.mispevent.objects[0].attributes[:2]
404
+ self.mispevent.objects[0].uuid = 'a'
405
+ with open('tests/mispevent_testfiles/misp_custom_obj.json') as f:
406
+ ref_json = json.load(f)
407
+ del self.mispevent.uuid
408
+ self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
409
+
410
+ def test_first_last_seen(self) -> None:
411
+ me = MISPEvent()
412
+ me.info = 'Test First and Last Seen'
413
+ me.date = '2020.01.12' # type: ignore[assignment]
414
+ self.assertEqual(me.date.day, 12)
415
+ me.add_attribute('ip-dst', '8.8.8.8', first_seen='06-21-1998', last_seen=1580213607.469571)
416
+ self.assertEqual(me.attributes[0].first_seen.year, 1998)
417
+ self.assertEqual(me.attributes[0].last_seen.year, 2020)
418
+ now = datetime.now().astimezone()
419
+ me.attributes[0].last_seen = now
420
+ today = date.today()
421
+ me.attributes[0].first_seen = today # type: ignore[assignment]
422
+ self.assertEqual(me.attributes[0].first_seen.year, today.year)
423
+ self.assertEqual(me.attributes[0].last_seen, now)
424
+
425
+ def test_feed(self) -> None:
426
+ me = MISPEvent()
427
+ me.info = 'Test feed'
428
+ org = MISPOrganisation()
429
+ org.name = 'TestOrg'
430
+ org.uuid = '123478'
431
+ me.Orgc = org
432
+ me.add_attribute('ip-dst', '8.8.8.8')
433
+ obj = me.add_object(name='file')
434
+ obj.add_attributes('filename', *['foo.exe', 'bar.exe'])
435
+ h = hashlib.new('md5')
436
+ h.update(b'8.8.8.8')
437
+ hash_attr_val = h.hexdigest()
438
+ feed = me.to_feed(with_meta=True)
439
+ self.assertEqual(feed['Event']['_hashes'][0], hash_attr_val)
440
+ self.assertEqual(feed['Event']['_manifest'][me.uuid]['info'], 'Test feed')
441
+ self.assertEqual(len(feed['Event']['Object'][0]['Attribute']), 2)
442
+
443
+ def test_object_templates(self) -> None:
444
+ me = MISPEvent()
445
+ for template in glob.glob(str(me.misp_objects_path / '*' / 'definition.json')):
446
+ with open(template) as f:
447
+ t_json = json.load(f)
448
+ if 'requiredOneOf' in t_json:
449
+ obj_relations = set(t_json['attributes'].keys())
450
+ subset = set(t_json['requiredOneOf']).issubset(obj_relations)
451
+ self.assertTrue(subset, f'{t_json["name"]}')
452
+ if 'required' in t_json:
453
+ obj_relations = set(t_json['attributes'].keys())
454
+ subset = set(t_json['required']).issubset(obj_relations)
455
+ self.assertTrue(subset, f'{t_json["name"]}')
456
+ for obj_relation, entry in t_json['attributes'].items():
457
+ self.assertTrue(entry['misp-attribute'] in me.describe_types['types'], f'Missing type: {entry["misp-attribute"]}')
458
+ if 'categories' in entry:
459
+ subset = set(entry['categories']).issubset(me.describe_types['categories'])
460
+ self.assertTrue(subset, f'{t_json["name"]} - {obj_relation}')
461
+
462
+ def test_git_vuln_finder(self) -> None:
463
+ with open('tests/git-vuln-finder-quagga.json') as f:
464
+ dump = json.load(f)
465
+
466
+ for vuln in dump.values():
467
+ author = vuln['author']
468
+ vuln_finder = GitVulnFinderObject(vuln)
469
+ self.assertEqual(vuln_finder.get_attributes_by_relation('author')[0].value, author)
470
+
471
+
472
+ if __name__ == '__main__':
473
+ unittest.main()