misp-modules 2.4.196__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.
Files changed (194) hide show
  1. misp_modules/__init__.py +379 -0
  2. misp_modules/helpers/__init__.py +1 -0
  3. misp_modules/helpers/cache.py +84 -0
  4. misp_modules/lib/__init__.py +4 -0
  5. misp_modules/lib/_vmray/__init__.py +0 -0
  6. misp_modules/lib/_vmray/parser.py +1417 -0
  7. misp_modules/lib/_vmray/rest_api.py +148 -0
  8. misp_modules/lib/cof2misp/LICENSE-2.0.txt +202 -0
  9. misp_modules/lib/cof2misp/__init__.py +0 -0
  10. misp_modules/lib/cof2misp/cof.py +165 -0
  11. misp_modules/lib/joe_mapping.py +114 -0
  12. misp_modules/lib/joe_parser.py +573 -0
  13. misp_modules/lib/lastline_api.py +841 -0
  14. misp_modules/lib/qintel_helper.py +263 -0
  15. misp_modules/lib/stix2misp.py +2080 -0
  16. misp_modules/lib/stix2misp_mapping.py +460 -0
  17. misp_modules/lib/synonymsToTagNames.json +1 -0
  18. misp_modules/lib/vt_graph_parser/__init__.py +8 -0
  19. misp_modules/lib/vt_graph_parser/errors.py +20 -0
  20. misp_modules/lib/vt_graph_parser/helpers/__init__.py +7 -0
  21. misp_modules/lib/vt_graph_parser/helpers/parsers.py +88 -0
  22. misp_modules/lib/vt_graph_parser/helpers/rules.py +304 -0
  23. misp_modules/lib/vt_graph_parser/helpers/wrappers.py +58 -0
  24. misp_modules/lib/vt_graph_parser/importers/__init__.py +7 -0
  25. misp_modules/lib/vt_graph_parser/importers/base.py +98 -0
  26. misp_modules/lib/vt_graph_parser/importers/pymisp_response.py +73 -0
  27. misp_modules/modules/__init__.py +4 -0
  28. misp_modules/modules/action_mod/__init__.py +1 -0
  29. misp_modules/modules/action_mod/_utils/__init__.py +1 -0
  30. misp_modules/modules/action_mod/_utils/utils.py +70 -0
  31. misp_modules/modules/action_mod/mattermost.py +113 -0
  32. misp_modules/modules/action_mod/slack.py +96 -0
  33. misp_modules/modules/action_mod/testaction.py +68 -0
  34. misp_modules/modules/expansion/__init__.py +36 -0
  35. misp_modules/modules/expansion/_dnsdb_query/COPYRIGHT +27 -0
  36. misp_modules/modules/expansion/_dnsdb_query/LICENSE +202 -0
  37. misp_modules/modules/expansion/_dnsdb_query/README.md +162 -0
  38. misp_modules/modules/expansion/_dnsdb_query/__init__.py +0 -0
  39. misp_modules/modules/expansion/_dnsdb_query/dnsdb_query.py +327 -0
  40. misp_modules/modules/expansion/_ransomcoindb/__init__.py +0 -0
  41. misp_modules/modules/expansion/_ransomcoindb/ransomcoindb.py +96 -0
  42. misp_modules/modules/expansion/_vulnerability_parser/__init__.py +0 -0
  43. misp_modules/modules/expansion/_vulnerability_parser/vulnerability_parser.py +118 -0
  44. misp_modules/modules/expansion/abuseipdb.py +146 -0
  45. misp_modules/modules/expansion/apiosintds.py +365 -0
  46. misp_modules/modules/expansion/apivoid.py +133 -0
  47. misp_modules/modules/expansion/assemblyline_query.py +179 -0
  48. misp_modules/modules/expansion/assemblyline_submit.py +100 -0
  49. misp_modules/modules/expansion/backscatter_io.py +84 -0
  50. misp_modules/modules/expansion/btc_scam_check.py +54 -0
  51. misp_modules/modules/expansion/btc_steroids.py +238 -0
  52. misp_modules/modules/expansion/censys_enrich.py +287 -0
  53. misp_modules/modules/expansion/circl_passivedns.py +85 -0
  54. misp_modules/modules/expansion/circl_passivessl.py +113 -0
  55. misp_modules/modules/expansion/clamav.py +129 -0
  56. misp_modules/modules/expansion/cluster25_expand.py +239 -0
  57. misp_modules/modules/expansion/countrycode.py +69 -0
  58. misp_modules/modules/expansion/cpe.py +140 -0
  59. misp_modules/modules/expansion/crowdsec.py +235 -0
  60. misp_modules/modules/expansion/crowdstrike_falcon.py +148 -0
  61. misp_modules/modules/expansion/cuckoo_submit.py +161 -0
  62. misp_modules/modules/expansion/cve.py +57 -0
  63. misp_modules/modules/expansion/cve_advanced.py +185 -0
  64. misp_modules/modules/expansion/cytomic_orion.py +196 -0
  65. misp_modules/modules/expansion/dbl_spamhaus.py +78 -0
  66. misp_modules/modules/expansion/dns.py +71 -0
  67. misp_modules/modules/expansion/docx_enrich.py +71 -0
  68. misp_modules/modules/expansion/domaintools.py +290 -0
  69. misp_modules/modules/expansion/eql.py +91 -0
  70. misp_modules/modules/expansion/eupi.py +86 -0
  71. misp_modules/modules/expansion/extract_url_components.py +83 -0
  72. misp_modules/modules/expansion/farsight_passivedns.py +243 -0
  73. misp_modules/modules/expansion/geoip_asn.py +75 -0
  74. misp_modules/modules/expansion/geoip_city.py +75 -0
  75. misp_modules/modules/expansion/geoip_country.py +73 -0
  76. misp_modules/modules/expansion/google_safe_browsing.py +86 -0
  77. misp_modules/modules/expansion/google_search.py +57 -0
  78. misp_modules/modules/expansion/google_threat_intelligence.py +453 -0
  79. misp_modules/modules/expansion/greynoise.py +346 -0
  80. misp_modules/modules/expansion/hashdd.py +53 -0
  81. misp_modules/modules/expansion/hashlookup.py +118 -0
  82. misp_modules/modules/expansion/hibp.py +62 -0
  83. misp_modules/modules/expansion/html_to_markdown.py +63 -0
  84. misp_modules/modules/expansion/hyasinsight.py +881 -0
  85. misp_modules/modules/expansion/intel471.py +73 -0
  86. misp_modules/modules/expansion/intelmq_eventdb.py.experimental +67 -0
  87. misp_modules/modules/expansion/ip2locationio.py +90 -0
  88. misp_modules/modules/expansion/ipasn.py +70 -0
  89. misp_modules/modules/expansion/ipinfo.py +112 -0
  90. misp_modules/modules/expansion/ipqs_fraud_and_risk_scoring.py +633 -0
  91. misp_modules/modules/expansion/iprep.py +98 -0
  92. misp_modules/modules/expansion/jinja_template_rendering.py +54 -0
  93. misp_modules/modules/expansion/joesandbox_query.py +91 -0
  94. misp_modules/modules/expansion/joesandbox_submit.py +147 -0
  95. misp_modules/modules/expansion/lastline_query.py +148 -0
  96. misp_modules/modules/expansion/lastline_submit.py +180 -0
  97. misp_modules/modules/expansion/macaddress_io.py +130 -0
  98. misp_modules/modules/expansion/macvendors.py +55 -0
  99. misp_modules/modules/expansion/malshare_upload.py +107 -0
  100. misp_modules/modules/expansion/malwarebazaar.py +67 -0
  101. misp_modules/modules/expansion/mcafee_insights_enrich.py +249 -0
  102. misp_modules/modules/expansion/mmdb_lookup.py +138 -0
  103. misp_modules/modules/expansion/module.py.skeleton +44 -0
  104. misp_modules/modules/expansion/mwdb.py +152 -0
  105. misp_modules/modules/expansion/ocr_enrich.py +74 -0
  106. misp_modules/modules/expansion/ods_enrich.py +71 -0
  107. misp_modules/modules/expansion/odt_enrich.py +61 -0
  108. misp_modules/modules/expansion/onyphe.py +243 -0
  109. misp_modules/modules/expansion/onyphe_full.py +387 -0
  110. misp_modules/modules/expansion/otx.py +167 -0
  111. misp_modules/modules/expansion/passive_ssh.py +150 -0
  112. misp_modules/modules/expansion/passivetotal.py +358 -0
  113. misp_modules/modules/expansion/pdf_enrich.py +58 -0
  114. misp_modules/modules/expansion/pptx_enrich.py +65 -0
  115. misp_modules/modules/expansion/qintel_qsentry.py +229 -0
  116. misp_modules/modules/expansion/qrcode.py +99 -0
  117. misp_modules/modules/expansion/ransomcoindb.py +82 -0
  118. misp_modules/modules/expansion/rbl.py +126 -0
  119. misp_modules/modules/expansion/recordedfuture.py +544 -0
  120. misp_modules/modules/expansion/reversedns.py +77 -0
  121. misp_modules/modules/expansion/securitytrails.py +571 -0
  122. misp_modules/modules/expansion/shodan.py +244 -0
  123. misp_modules/modules/expansion/sigma_queries.py +61 -0
  124. misp_modules/modules/expansion/sigma_syntax_validator.py +49 -0
  125. misp_modules/modules/expansion/sigmf_expand.py +303 -0
  126. misp_modules/modules/expansion/socialscan.py +108 -0
  127. misp_modules/modules/expansion/sophoslabs_intelix.py +146 -0
  128. misp_modules/modules/expansion/sourcecache.py +57 -0
  129. misp_modules/modules/expansion/stairwell.py +156 -0
  130. misp_modules/modules/expansion/stix2_pattern_syntax_validator.py +56 -0
  131. misp_modules/modules/expansion/threatcrowd.py +170 -0
  132. misp_modules/modules/expansion/threatfox.py +75 -0
  133. misp_modules/modules/expansion/threatminer.py +152 -0
  134. misp_modules/modules/expansion/triage_submit.py +119 -0
  135. misp_modules/modules/expansion/trustar_enrich.py +235 -0
  136. misp_modules/modules/expansion/urlhaus.py +164 -0
  137. misp_modules/modules/expansion/urlscan.py +269 -0
  138. misp_modules/modules/expansion/variotdbs.py +133 -0
  139. misp_modules/modules/expansion/virustotal.py +311 -0
  140. misp_modules/modules/expansion/virustotal_public.py +272 -0
  141. misp_modules/modules/expansion/virustotal_upload.py +91 -0
  142. misp_modules/modules/expansion/vmray_submit.py +161 -0
  143. misp_modules/modules/expansion/vmware_nsx.py +628 -0
  144. misp_modules/modules/expansion/vulndb.py +292 -0
  145. misp_modules/modules/expansion/vulnerability_lookup.py +324 -0
  146. misp_modules/modules/expansion/vulners.py +81 -0
  147. misp_modules/modules/expansion/vysion.py +221 -0
  148. misp_modules/modules/expansion/whois.py +72 -0
  149. misp_modules/modules/expansion/whoisfreaks.py +232 -0
  150. misp_modules/modules/expansion/wiki.py +58 -0
  151. misp_modules/modules/expansion/xforceexchange.py +189 -0
  152. misp_modules/modules/expansion/xlsx_enrich.py +63 -0
  153. misp_modules/modules/expansion/yara_query.py +70 -0
  154. misp_modules/modules/expansion/yara_syntax_validator.py +49 -0
  155. misp_modules/modules/expansion/yeti.py +196 -0
  156. misp_modules/modules/export_mod/__init__.py +3 -0
  157. misp_modules/modules/export_mod/cef_export.py +93 -0
  158. misp_modules/modules/export_mod/cisco_firesight_manager_ACL_rule_export.py +150 -0
  159. misp_modules/modules/export_mod/defender_endpoint_export.py +141 -0
  160. misp_modules/modules/export_mod/goamlexport.py +255 -0
  161. misp_modules/modules/export_mod/liteexport.py +97 -0
  162. misp_modules/modules/export_mod/mass_eql_export.py +106 -0
  163. misp_modules/modules/export_mod/nexthinkexport.py +131 -0
  164. misp_modules/modules/export_mod/osqueryexport.py +125 -0
  165. misp_modules/modules/export_mod/pdfexport.py +107 -0
  166. misp_modules/modules/export_mod/testexport.py +73 -0
  167. misp_modules/modules/export_mod/threatStream_misp_export.py +114 -0
  168. misp_modules/modules/export_mod/threat_connect_export.py +125 -0
  169. misp_modules/modules/export_mod/virustotal_collections.py +141 -0
  170. misp_modules/modules/export_mod/vt_graph.py +120 -0
  171. misp_modules/modules/export_mod/yara_export.py +290 -0
  172. misp_modules/modules/import_mod/__init__.py +22 -0
  173. misp_modules/modules/import_mod/cof2misp.py +264 -0
  174. misp_modules/modules/import_mod/csvimport.py +319 -0
  175. misp_modules/modules/import_mod/cuckooimport.py +749 -0
  176. misp_modules/modules/import_mod/email_import.py +294 -0
  177. misp_modules/modules/import_mod/goamlimport.py +188 -0
  178. misp_modules/modules/import_mod/import_blueprint.py +93 -0
  179. misp_modules/modules/import_mod/joe_import.py +74 -0
  180. misp_modules/modules/import_mod/lastline_import.py +160 -0
  181. misp_modules/modules/import_mod/mispjson.py +73 -0
  182. misp_modules/modules/import_mod/ocr.py +122 -0
  183. misp_modules/modules/import_mod/openiocimport.py +99 -0
  184. misp_modules/modules/import_mod/taxii21.py +383 -0
  185. misp_modules/modules/import_mod/testimport.py +73 -0
  186. misp_modules/modules/import_mod/threatanalyzer_import.py +552 -0
  187. misp_modules/modules/import_mod/url_import.py +97 -0
  188. misp_modules/modules/import_mod/vmray_import.py +96 -0
  189. misp_modules/modules/import_mod/vmray_summary_json_import.py +87 -0
  190. misp_modules-2.4.196.dist-info/LICENSE +661 -0
  191. misp_modules-2.4.196.dist-info/METADATA +281 -0
  192. misp_modules-2.4.196.dist-info/RECORD +194 -0
  193. misp_modules-2.4.196.dist-info/WHEEL +4 -0
  194. misp_modules-2.4.196.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,573 @@
1
+ # -*- coding: utf-8 -*-
2
+ import json
3
+ from collections import defaultdict
4
+ from datetime import datetime
5
+ from pymisp import MISPAttribute, MISPEvent, MISPObject
6
+ from joe_mapping import (arch_type_mapping, domain_object_mapping,
7
+ dropped_file_mapping, dropped_hash_mapping, elf_object_mapping,
8
+ elf_section_flags_mapping, file_object_fields, file_object_mapping,
9
+ file_references_mapping, network_behavior_fields,
10
+ network_connection_object_mapping, pe_object_fields, pe_object_mapping,
11
+ pe_section_object_mapping, process_object_fields, protocols,
12
+ registry_references_mapping, regkey_object_mapping, signerinfo_object_mapping)
13
+
14
+
15
+ class JoeParser():
16
+ def __init__(self, config):
17
+ self.misp_event = MISPEvent()
18
+ self.references = defaultdict(list)
19
+ self.attributes = defaultdict(lambda: defaultdict(set))
20
+ self.process_references = {}
21
+
22
+ self.import_executable = config["import_executable"]
23
+ self.create_mitre_attack = config["mitre_attack"]
24
+
25
+ def parse_data(self, data):
26
+ self.data = data
27
+ if self.analysis_type() == "file":
28
+ self.parse_fileinfo()
29
+ else:
30
+ self.parse_url_analysis()
31
+
32
+ self.parse_system_behavior()
33
+ self.parse_network_behavior()
34
+ self.parse_screenshot()
35
+ self.parse_network_interactions()
36
+ self.parse_dropped_files()
37
+
38
+ if self.attributes:
39
+ self.handle_attributes()
40
+
41
+ if self.create_mitre_attack:
42
+ self.parse_mitre_attack()
43
+
44
+ def build_references(self):
45
+ for misp_object in self.misp_event.objects:
46
+ object_uuid = misp_object.uuid
47
+ if object_uuid in self.references:
48
+ for reference in self.references[object_uuid]:
49
+ misp_object.add_reference(**reference)
50
+
51
+ def handle_attributes(self):
52
+ for attribute_type, attribute in self.attributes.items():
53
+ for attribute_value, references in attribute.items():
54
+ attribute_uuid = self.create_attribute(attribute_type, attribute_value)
55
+ for reference in references:
56
+ source_uuid, relationship = reference
57
+ self.references[source_uuid].append(dict(referenced_uuid=attribute_uuid,
58
+ relationship_type=relationship))
59
+
60
+ def parse_dropped_files(self):
61
+ droppedinfo = self.data['droppedinfo']
62
+ if droppedinfo:
63
+ for droppedfile in droppedinfo['hash']:
64
+ file_object = MISPObject('file')
65
+ for key, mapping in dropped_file_mapping.items():
66
+ if droppedfile.get(key) is not None:
67
+ attribute = {'value': droppedfile[key], 'to_ids': False}
68
+ attribute.update(mapping)
69
+ file_object.add_attribute(**attribute)
70
+ if droppedfile['@malicious'] == 'true':
71
+ file_object.add_attribute(
72
+ **{
73
+ 'type': 'text',
74
+ 'object_relation': 'state',
75
+ 'value': 'Malicious',
76
+ 'to_ids': False
77
+ }
78
+ )
79
+ for h in droppedfile['value']:
80
+ hash_type = dropped_hash_mapping[h['@algo']]
81
+ file_object.add_attribute(
82
+ **{
83
+ 'type': hash_type,
84
+ 'object_relation': hash_type,
85
+ 'value': h['$'],
86
+ 'to_ids': False
87
+ }
88
+ )
89
+ self.misp_event.add_object(file_object)
90
+ reference_key = (int(droppedfile['@targetid']), droppedfile['@process'])
91
+ if reference_key in self.process_references:
92
+ self.references[self.process_references[reference_key]].append(
93
+ {
94
+ 'referenced_uuid': file_object.uuid,
95
+ 'relationship_type': 'drops'
96
+ }
97
+ )
98
+
99
+ def parse_mitre_attack(self):
100
+ mitreattack = self.data.get('mitreattack', {})
101
+ if mitreattack:
102
+ for tactic in mitreattack['tactic']:
103
+ if tactic.get('technique'):
104
+ for technique in tactic['technique']:
105
+ self.misp_event.add_tag(f'misp-galaxy:mitre-attack-pattern="{technique["name"]} - {technique["id"]}"')
106
+
107
+ def parse_network_behavior(self):
108
+ network = self.data['behavior']['network']
109
+ connections = defaultdict(lambda: defaultdict(set))
110
+ for protocol, layer in protocols.items():
111
+ if network.get(protocol):
112
+ for packet in network[protocol]['packet']:
113
+ timestamp = datetime.strptime(self.parse_timestamp(packet['timestamp']), '%b %d, %Y %H:%M:%S.%f')
114
+ connections[tuple(packet.get(field) for field in network_behavior_fields)][protocol].add(timestamp)
115
+ for connection, data in connections.items():
116
+ attributes = self.prefetch_attributes_data(connection)
117
+ if len(data.keys()) == len(set(protocols[protocol] for protocol in data.keys())):
118
+ network_connection_object = MISPObject('network-connection')
119
+ for attribute in attributes:
120
+ network_connection_object.add_attribute(**attribute)
121
+ network_connection_object.add_attribute(
122
+ **{
123
+ 'type': 'datetime',
124
+ 'object_relation': 'first-packet-seen',
125
+ 'value': min(tuple(min(timestamp) for timestamp in data.values())),
126
+ 'to_ids': False
127
+ }
128
+ )
129
+ for protocol in data.keys():
130
+ network_connection_object.add_attribute(
131
+ **{
132
+ 'type': 'text',
133
+ 'object_relation': f'layer{protocols[protocol]}-protocol',
134
+ 'value': protocol,
135
+ 'to_ids': False
136
+ }
137
+ )
138
+ self.misp_event.add_object(network_connection_object)
139
+ self.references[self.analysisinfo_uuid].append(dict(referenced_uuid=network_connection_object.uuid,
140
+ relationship_type='initiates'))
141
+ else:
142
+ for protocol, timestamps in data.items():
143
+ network_connection_object = MISPObject('network-connection')
144
+ for attribute in attributes:
145
+ network_connection_object.add_attribute(**attribute)
146
+ network_connection_object.add_attribute(
147
+ **{
148
+ 'type': 'datetime',
149
+ 'object_relation': 'first-packet-seen',
150
+ 'value': min(timestamps),
151
+ 'to_ids': False
152
+ }
153
+ )
154
+ network_connection_object.add_attribute(
155
+ **{
156
+ 'type': 'text',
157
+ 'object_relation': f'layer{protocols[protocol]}-protocol',
158
+ 'value': protocol,
159
+ 'to_ids': False
160
+ }
161
+ )
162
+ self.misp_event.add_object(network_connection_object)
163
+ self.references[self.analysisinfo_uuid].append(dict(referenced_uuid=network_connection_object.uuid,
164
+ relationship_type='initiates'))
165
+
166
+ def parse_screenshot(self):
167
+ if self.data['behavior'].get('screenshotdata', {}).get('interesting') is not None:
168
+ screenshotdata = self.data['behavior']['screenshotdata']['interesting']['$']
169
+ self.misp_event.add_attribute(
170
+ **{
171
+ 'type': 'attachment',
172
+ 'value': 'screenshot.jpg',
173
+ 'data': screenshotdata,
174
+ 'disable_correlation': True,
175
+ 'to_ids': False
176
+ }
177
+ )
178
+
179
+ def parse_system_behavior(self):
180
+ if not 'system' in self.data['behavior']:
181
+ return
182
+ system = self.data['behavior']['system']
183
+ if system.get('processes'):
184
+ process_activities = {'fileactivities': self.parse_fileactivities,
185
+ 'registryactivities': self.parse_registryactivities}
186
+ for process in system['processes']['process']:
187
+ general = process['general']
188
+ process_object = MISPObject('process')
189
+ for feature, relation in process_object_fields.items():
190
+ process_object.add_attribute(
191
+ **{
192
+ 'type': 'text',
193
+ 'object_relation': relation,
194
+ 'value': general[feature],
195
+ 'to_ids': False
196
+ }
197
+ )
198
+ start_time = datetime.strptime(f"{general['date']} {general['time']}", '%d/%m/%Y %H:%M:%S')
199
+ process_object.add_attribute(
200
+ **{
201
+ 'type': 'datetime',
202
+ 'object_relation': 'start-time',
203
+ 'value': start_time,
204
+ 'to_ids': False
205
+ }
206
+ )
207
+ self.misp_event.add_object(process_object)
208
+ for field, to_call in process_activities.items():
209
+ if process.get(field):
210
+ to_call(process_object.uuid, process[field])
211
+ self.references[self.analysisinfo_uuid].append(dict(referenced_uuid=process_object.uuid,
212
+ relationship_type='calls'))
213
+ self.process_references[(general['targetid'], general['path'])] = process_object.uuid
214
+
215
+ def parse_fileactivities(self, process_uuid, fileactivities):
216
+ for feature, files in fileactivities.items():
217
+ # ignore unknown features
218
+ if feature not in file_references_mapping:
219
+ continue
220
+
221
+ if files:
222
+ for call in files['call']:
223
+ self.attributes['filename'][call['path']].add((process_uuid, file_references_mapping[feature]))
224
+
225
+ def analysis_type(self):
226
+ generalinfo = self.data['generalinfo']
227
+
228
+ if generalinfo['target']['sample']:
229
+ return "file"
230
+ elif generalinfo['target']['url']:
231
+ return "url"
232
+ else:
233
+ raise Exception("Unknown analysis type")
234
+
235
+ def parse_url_analysis(self):
236
+ generalinfo = self.data["generalinfo"]
237
+
238
+ url_object = MISPObject("url")
239
+ self.analysisinfo_uuid = url_object.uuid
240
+ url_object.add_attribute(
241
+ **{
242
+ 'type': 'url',
243
+ 'object_relation': 'url',
244
+ 'value': generalinfo["target"]["url"],
245
+ 'to_ids': False
246
+ }
247
+ )
248
+ self.misp_event.add_object(url_object)
249
+
250
+ def parse_fileinfo(self):
251
+ fileinfo = self.data['fileinfo']
252
+
253
+ file_object = MISPObject('file')
254
+ self.analysisinfo_uuid = file_object.uuid
255
+
256
+ for field in file_object_fields:
257
+ file_object.add_attribute(
258
+ **{
259
+ 'type': field,
260
+ 'object_relation': field,
261
+ 'value': fileinfo[field],
262
+ 'to_ids': False
263
+ }
264
+ )
265
+ for field, mapping in file_object_mapping.items():
266
+ if fileinfo.get(field) is not None:
267
+ attribute = {'value': fileinfo[field], 'to_ids': False}
268
+ attribute.update(mapping)
269
+ file_object.add_attribute(**attribute)
270
+ arch = self.data['generalinfo']['arch']
271
+ if self.import_executable and arch in arch_type_mapping:
272
+ to_call = arch_type_mapping[arch]
273
+ getattr(self, to_call)(fileinfo, file_object)
274
+ else:
275
+ self.misp_event.add_object(file_object)
276
+
277
+ def parse_apk(self, fileinfo, file_object):
278
+ apkinfo = fileinfo['apk']
279
+ self.misp_event.add_object(file_object)
280
+ permission_lists = defaultdict(list)
281
+ for permission in apkinfo['requiredpermissions']['permission']:
282
+ permission = permission['@name'].split('.')
283
+ permission_lists[' '.join(permission[:-1])].append(permission[-1])
284
+ attribute_type = 'text'
285
+ for comment, permissions in permission_lists.items():
286
+ permission_object = MISPObject('android-permission')
287
+ permission_object.add_attribute(
288
+ **{
289
+ 'type': attribute_type,
290
+ 'object_relation': 'comment',
291
+ 'value': comment,
292
+ 'to_ids': False
293
+ }
294
+ )
295
+ for permission in permissions:
296
+ permission_object.add_attribute(
297
+ **{
298
+ 'type': attribute_type,
299
+ 'object_relation': 'permission',
300
+ 'value': permission,
301
+ 'to_ids': False
302
+ }
303
+ )
304
+ self.misp_event.add_object(permission_object)
305
+ self.references[file_object.uuid].append(dict(referenced_uuid=permission_object.uuid,
306
+ relationship_type='grants'))
307
+
308
+ def parse_elf(self, fileinfo, file_object):
309
+ elfinfo = fileinfo['elf']
310
+ self.misp_event.add_object(file_object)
311
+ attribute_type = 'text'
312
+ relationship = 'includes'
313
+ size = 'size-in-bytes'
314
+ for fileinfo in elfinfo['file']:
315
+ elf_object = MISPObject('elf')
316
+ self.references[file_object.uuid].append(dict(referenced_uuid=elf_object.uuid,
317
+ relationship_type=relationship))
318
+ elf = fileinfo['main'][0]['header'][0]
319
+ if elf.get('type'):
320
+ # Haven't seen anything but EXEC yet in the files I tested
321
+ attribute_value = "EXECUTABLE" if elf['type'] == "EXEC (Executable file)" else elf['type']
322
+ elf_object.add_attribute(
323
+ **{
324
+ 'type': attribute_type,
325
+ 'object_relation': 'type',
326
+ 'value': attribute_value,
327
+ 'to_ids': False
328
+ }
329
+ )
330
+ for feature, relation in elf_object_mapping.items():
331
+ if elf.get(feature):
332
+ elf_object.add_attribute(
333
+ **{
334
+ 'type': attribute_type,
335
+ 'object_relation': relation,
336
+ 'value': elf[feature],
337
+ 'to_ids': False
338
+ }
339
+ )
340
+ sections_number = len(fileinfo['sections']['section'])
341
+ elf_object.add_attribute(
342
+ **{
343
+ 'type': 'counter',
344
+ 'object_relation': 'number-sections',
345
+ 'value': sections_number,
346
+ 'to_ids': False
347
+ }
348
+ )
349
+ self.misp_event.add_object(elf_object)
350
+ for section in fileinfo['sections']['section']:
351
+ section_object = MISPObject('elf-section')
352
+ for feature in ('name', 'type'):
353
+ if section.get(feature):
354
+ section_object.add_attribute(
355
+ **{
356
+ 'type': attribute_type,
357
+ 'object_relation': feature,
358
+ 'value': section[feature],
359
+ 'to_ids': False
360
+ }
361
+ )
362
+ if section.get('size'):
363
+ section_object.add_attribute(
364
+ **{
365
+ 'type': size,
366
+ 'object_relation': size,
367
+ 'value': int(section['size'], 16),
368
+ 'to_ids': False
369
+ }
370
+ )
371
+ for flag in section['flagsdesc']:
372
+ try:
373
+ attribute_value = elf_section_flags_mapping[flag]
374
+ section_object.add_attribute(
375
+ **{
376
+ 'type': attribute_type,
377
+ 'object_relation': 'flag',
378
+ 'value': attribute_value,
379
+ 'to_ids': False
380
+ }
381
+ )
382
+ except KeyError:
383
+ print(f'Unknown elf section flag: {flag}')
384
+ continue
385
+ self.misp_event.add_object(section_object)
386
+ self.references[elf_object.uuid].append(dict(referenced_uuid=section_object.uuid,
387
+ relationship_type=relationship))
388
+
389
+ def parse_pe(self, fileinfo, file_object):
390
+ try:
391
+ peinfo = fileinfo['pe']
392
+ except KeyError:
393
+ self.misp_event.add_object(file_object)
394
+ return
395
+ pe_object = MISPObject('pe')
396
+ relationship = 'includes'
397
+ file_object.add_reference(pe_object.uuid, relationship)
398
+ self.misp_event.add_object(file_object)
399
+ for field, mapping in pe_object_fields.items():
400
+ if peinfo.get(field) is not None:
401
+ attribute = {'value': peinfo[field], 'to_ids': False}
402
+ attribute.update(mapping)
403
+ pe_object.add_attribute(**attribute)
404
+ pe_object.add_attribute(
405
+ **{
406
+ 'type': 'datetime',
407
+ 'object_relation': 'compilation-timestamp',
408
+ 'value': int(peinfo['timestamp'].split()[0], 16),
409
+ 'to_ids': False
410
+ }
411
+ )
412
+ program_name = fileinfo['filename']
413
+ if peinfo['versions']:
414
+ for feature in peinfo['versions']['version']:
415
+ name = feature['name']
416
+ if name == 'InternalName':
417
+ program_name = feature['value']
418
+ if name in pe_object_mapping:
419
+ pe_object.add_attribute(
420
+ **{
421
+ 'type': 'text',
422
+ 'object_relation': pe_object_mapping[name],
423
+ 'value': feature['value'],
424
+ 'to_ids': False
425
+ }
426
+ )
427
+ sections_number = len(peinfo['sections']['section'])
428
+ pe_object.add_attribute(
429
+ **{
430
+ 'type': 'counter',
431
+ 'object_relation': 'number-sections',
432
+ 'value': sections_number,
433
+ 'to_ids': False
434
+ }
435
+ )
436
+ signatureinfo = peinfo['signature']
437
+ if signatureinfo['signed']:
438
+ signerinfo_object = MISPObject('authenticode-signerinfo')
439
+ pe_object.add_reference(signerinfo_object.uuid, 'signed-by')
440
+ self.misp_event.add_object(pe_object)
441
+ signerinfo_object.add_attribute(
442
+ **{
443
+ 'type': 'text',
444
+ 'object_relation': 'program-name',
445
+ 'value': program_name,
446
+ 'to_ids': False
447
+ }
448
+ )
449
+ for feature, mapping in signerinfo_object_mapping.items():
450
+ if signatureinfo.get(feature) is not None:
451
+ attribute = {'value': signatureinfo[feature], 'to_ids': False}
452
+ attribute.update(mapping)
453
+ signerinfo_object.add_attribute(**attribute)
454
+ self.misp_event.add_object(signerinfo_object)
455
+ else:
456
+ self.misp_event.add_object(pe_object)
457
+ for section in peinfo['sections']['section']:
458
+ section_object = self.parse_pe_section(section)
459
+ self.references[pe_object.uuid].append(dict(referenced_uuid=section_object.uuid,
460
+ relationship_type=relationship))
461
+ self.misp_event.add_object(section_object)
462
+
463
+ def parse_pe_section(self, section):
464
+ section_object = MISPObject('pe-section')
465
+ for feature, mapping in pe_section_object_mapping.items():
466
+ if section.get(feature) is not None:
467
+ attribute = {'value': section[feature], 'to_ids': False}
468
+ attribute.update(mapping)
469
+ section_object.add_attribute(**attribute)
470
+ return section_object
471
+
472
+ def parse_network_interactions(self):
473
+ domaininfo = self.data['domaininfo']
474
+ if domaininfo:
475
+ for domain in domaininfo['domain']:
476
+ if domain['@ip'] != 'unknown':
477
+ domain_object = MISPObject('domain-ip')
478
+ for key, mapping in domain_object_mapping.items():
479
+ if domain.get(key) is not None:
480
+ attribute = {'value': domain[key], 'to_ids': False}
481
+ attribute.update(mapping)
482
+ domain_object.add_attribute(**attribute)
483
+ self.misp_event.add_object(domain_object)
484
+ reference = dict(referenced_uuid=domain_object.uuid, relationship_type='contacts')
485
+ self.add_process_reference(domain['@targetid'], domain['@currentpath'], reference)
486
+ else:
487
+ attribute = MISPAttribute()
488
+ attribute.from_dict(**{'type': 'domain', 'value': domain['@name'], 'to_ids': False})
489
+ self.misp_event.add_attribute(**attribute)
490
+ reference = dict(referenced_uuid=attribute.uuid, relationship_type='contacts')
491
+ self.add_process_reference(domain['@targetid'], domain['@currentpath'], reference)
492
+ ipinfo = self.data['ipinfo']
493
+ if ipinfo:
494
+ for ip in ipinfo['ip']:
495
+ attribute = MISPAttribute()
496
+ attribute.from_dict(**{'type': 'ip-dst', 'value': ip['@ip'], 'to_ids': False})
497
+ self.misp_event.add_attribute(**attribute)
498
+ reference = dict(referenced_uuid=attribute.uuid, relationship_type='contacts')
499
+ self.add_process_reference(ip['@targetid'], ip['@currentpath'], reference)
500
+ urlinfo = self.data['urlinfo']
501
+ if urlinfo:
502
+ for url in urlinfo['url']:
503
+ target_id = int(url['@targetid'])
504
+ current_path = url['@currentpath']
505
+ attribute = MISPAttribute()
506
+ attribute_dict = {'type': 'url', 'value': url['@name'], 'to_ids': False}
507
+ if target_id != -1 and current_path != 'unknown':
508
+ self.references[self.process_references[(target_id, current_path)]].append({
509
+ 'referenced_uuid': attribute.uuid,
510
+ 'relationship_type': 'contacts'
511
+ })
512
+ else:
513
+ attribute_dict['comment'] = 'From Memory - Enriched via the joe_import module'
514
+ attribute.from_dict(**attribute_dict)
515
+ self.misp_event.add_attribute(**attribute)
516
+
517
+ def parse_registryactivities(self, process_uuid, registryactivities):
518
+ if registryactivities['keyCreated']:
519
+ for call in registryactivities['keyCreated']['call']:
520
+ self.attributes['regkey'][call['path']].add((process_uuid, 'creates'))
521
+ for feature, relationship in registry_references_mapping.items():
522
+ if registryactivities[feature]:
523
+ for call in registryactivities[feature]['call']:
524
+ registry_key = MISPObject('registry-key')
525
+ for field, mapping in regkey_object_mapping.items():
526
+ if call.get(field) is not None:
527
+ attribute = {'value': call[field], 'to_ids': False}
528
+ attribute.update(mapping)
529
+ registry_key.add_attribute(**attribute)
530
+ registry_key.add_attribute(
531
+ **{
532
+ 'type': 'text',
533
+ 'object_relation': 'data-type',
534
+ 'value': f"REG_{call['type'].upper()}",
535
+ 'to_ids': False
536
+ }
537
+ )
538
+ self.misp_event.add_object(registry_key)
539
+ self.references[process_uuid].append(dict(referenced_uuid=registry_key.uuid,
540
+ relationship_type=relationship))
541
+
542
+ def add_process_reference(self, target, currentpath, reference):
543
+ try:
544
+ self.references[self.process_references[(int(target), currentpath)]].append(reference)
545
+ except KeyError:
546
+ self.references[self.analysisinfo_uuid].append(reference)
547
+
548
+ def create_attribute(self, attribute_type, attribute_value):
549
+ attribute = MISPAttribute()
550
+ attribute.from_dict(**{'type': attribute_type, 'value': attribute_value, 'to_ids': False})
551
+ self.misp_event.add_attribute(**attribute)
552
+ return attribute.uuid
553
+
554
+ def finalize_results(self):
555
+ if self.references:
556
+ self.build_references()
557
+ event = json.loads(self.misp_event.to_json())
558
+ self.results = {key: event[key] for key in ('Attribute', 'Object', 'Tag') if (key in event and event[key])}
559
+
560
+ @staticmethod
561
+ def parse_timestamp(timestamp):
562
+ timestamp = timestamp.split(':')
563
+ timestamp[-1] = str(round(float(timestamp[-1].split(' ')[0]), 6))
564
+ return ':'.join(timestamp)
565
+
566
+ @staticmethod
567
+ def prefetch_attributes_data(connection):
568
+ attributes = []
569
+ for field, value in zip(network_behavior_fields, connection):
570
+ attribute = {'value': value, 'to_ids': False}
571
+ attribute.update(network_connection_object_mapping[field])
572
+ attributes.append(attribute)
573
+ return attributes