51
51
52
52
53
53
class JoeParser ():
54
- def __init__ (self ):
54
+ def __init__ (self , config ):
55
55
self .misp_event = MISPEvent ()
56
56
self .references = defaultdict (list )
57
57
self .attributes = defaultdict (lambda : defaultdict (set ))
58
58
self .process_references = {}
59
59
60
+ self .import_pe = config ["import_pe" ]
61
+ self .create_mitre_attack = config ["mitre_attack" ]
62
+
60
63
def parse_data (self , data ):
61
64
self .data = data
62
65
if self .analysis_type () == "file" :
@@ -72,7 +75,9 @@ def parse_data(self, data):
72
75
73
76
if self .attributes :
74
77
self .handle_attributes ()
75
- self .parse_mitre_attack ()
78
+
79
+ if self .create_mitre_attack :
80
+ self .parse_mitre_attack ()
76
81
77
82
def build_references (self ):
78
83
for misp_object in self .misp_event .objects :
@@ -97,12 +102,12 @@ def parse_dropped_files(self):
97
102
file_object = MISPObject ('file' )
98
103
for key , mapping in dropped_file_mapping .items ():
99
104
attribute_type , object_relation = mapping
100
- file_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : droppedfile [key ]})
105
+ file_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : droppedfile [key ], 'to_ids' : False })
101
106
if droppedfile ['@malicious' ] == 'true' :
102
- file_object .add_attribute ('state' , ** {'type' : 'text' , 'value' : 'Malicious' })
107
+ file_object .add_attribute ('state' , ** {'type' : 'text' , 'value' : 'Malicious' , 'to_ids' : False })
103
108
for h in droppedfile ['value' ]:
104
109
hash_type = dropped_hash_mapping [h ['@algo' ]]
105
- file_object .add_attribute (hash_type , ** {'type' : hash_type , 'value' : h ['$' ]})
110
+ file_object .add_attribute (hash_type , ** {'type' : hash_type , 'value' : h ['$' ], 'to_ids' : False })
106
111
self .misp_event .add_object (** file_object )
107
112
self .references [self .process_references [(int (droppedfile ['@targetid' ]), droppedfile ['@process' ])]].append ({
108
113
'referenced_uuid' : file_object .uuid ,
@@ -132,9 +137,12 @@ def parse_network_behavior(self):
132
137
for object_relation , attribute in attributes .items ():
133
138
network_connection_object .add_attribute (object_relation , ** attribute )
134
139
network_connection_object .add_attribute ('first-packet-seen' ,
135
- ** {'type' : 'datetime' , 'value' : min (tuple (min (timestamp ) for timestamp in data .values ()))})
140
+ ** {'type' : 'datetime' ,
141
+ 'value' : min (tuple (min (timestamp ) for timestamp in data .values ())),
142
+ 'to_ids' : False })
136
143
for protocol in data .keys ():
137
- network_connection_object .add_attribute ('layer{}-protocol' .format (protocols [protocol ]), ** {'type' : 'text' , 'value' : protocol })
144
+ network_connection_object .add_attribute ('layer{}-protocol' .format (protocols [protocol ]),
145
+ ** {'type' : 'text' , 'value' : protocol , 'to_ids' : False })
138
146
self .misp_event .add_object (** network_connection_object )
139
147
self .references [self .analysisinfo_uuid ].append (dict (referenced_uuid = network_connection_object .uuid ,
140
148
relationship_type = 'initiates' ))
@@ -143,8 +151,8 @@ def parse_network_behavior(self):
143
151
network_connection_object = MISPObject ('network-connection' )
144
152
for object_relation , attribute in attributes .items ():
145
153
network_connection_object .add_attribute (object_relation , ** attribute )
146
- network_connection_object .add_attribute ('first-packet-seen' , ** {'type' : 'datetime' , 'value' : min (timestamps )})
147
- network_connection_object .add_attribute ('layer{}-protocol' .format (protocols [protocol ]), ** {'type' : 'text' , 'value' : protocol })
154
+ network_connection_object .add_attribute ('first-packet-seen' , ** {'type' : 'datetime' , 'value' : min (timestamps ), 'to_ids' : False })
155
+ network_connection_object .add_attribute ('layer{}-protocol' .format (protocols [protocol ]), ** {'type' : 'text' , 'value' : protocol , 'to_ids' : False })
148
156
self .misp_event .add_object (** network_connection_object )
149
157
self .references [self .analysisinfo_uuid ].append (dict (referenced_uuid = network_connection_object .uuid ,
150
158
relationship_type = 'initiates' ))
@@ -154,7 +162,8 @@ def parse_screenshot(self):
154
162
if screenshotdata :
155
163
screenshotdata = screenshotdata ['interesting' ]['$' ]
156
164
attribute = {'type' : 'attachment' , 'value' : 'screenshot.jpg' ,
157
- 'data' : screenshotdata , 'disable_correlation' : True }
165
+ 'data' : screenshotdata , 'disable_correlation' : True ,
166
+ 'to_ids' : False }
158
167
self .misp_event .add_attribute (** attribute )
159
168
160
169
def parse_system_behavior (self ):
@@ -166,9 +175,9 @@ def parse_system_behavior(self):
166
175
general = process ['general' ]
167
176
process_object = MISPObject ('process' )
168
177
for feature , relation in process_object_fields .items ():
169
- process_object .add_attribute (relation , ** {'type' : 'text' , 'value' : general [feature ]})
178
+ process_object .add_attribute (relation , ** {'type' : 'text' , 'value' : general [feature ], 'to_ids' : False })
170
179
start_time = datetime .strptime ('{} {}' .format (general ['date' ], general ['time' ]), '%d/%m/%Y %H:%M:%S' )
171
- process_object .add_attribute ('start-time' , ** {'type' : 'datetime' , 'value' : start_time })
180
+ process_object .add_attribute ('start-time' , ** {'type' : 'datetime' , 'value' : start_time , 'to_ids' : False })
172
181
self .misp_event .add_object (** process_object )
173
182
for field , to_call in process_activities .items ():
174
183
if process .get (field ):
@@ -203,7 +212,7 @@ def parse_url_analysis(self):
203
212
url_object = MISPObject ("url" )
204
213
self .analysisinfo_uuid = url_object .uuid
205
214
206
- url_object .add_attribute ("url" , generalinfo ["target" ]["url" ])
215
+ url_object .add_attribute ("url" , generalinfo ["target" ]["url" ], to_ids = False )
207
216
self .misp_event .add_object (** url_object )
208
217
209
218
def parse_fileinfo (self ):
@@ -213,10 +222,10 @@ def parse_fileinfo(self):
213
222
self .analysisinfo_uuid = file_object .uuid
214
223
215
224
for field in file_object_fields :
216
- file_object .add_attribute (field , ** {'type' : field , 'value' : fileinfo [field ]})
225
+ file_object .add_attribute (field , ** {'type' : field , 'value' : fileinfo [field ], 'to_ids' : False })
217
226
for field , mapping in file_object_mapping .items ():
218
227
attribute_type , object_relation = mapping
219
- file_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : fileinfo [field ]})
228
+ file_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : fileinfo [field ], 'to_ids' : False })
220
229
arch = self .data ['generalinfo' ]['arch' ]
221
230
if arch in arch_type_mapping :
222
231
to_call = arch_type_mapping [arch ]
@@ -234,9 +243,9 @@ def parse_apk(self, fileinfo, file_object):
234
243
attribute_type = 'text'
235
244
for comment , permissions in permission_lists .items ():
236
245
permission_object = MISPObject ('android-permission' )
237
- permission_object .add_attribute ('comment' , ** dict (type = attribute_type , value = comment ))
246
+ permission_object .add_attribute ('comment' , ** dict (type = attribute_type , value = comment , to_ids = False ))
238
247
for permission in permissions :
239
- permission_object .add_attribute ('permission' , ** dict (type = attribute_type , value = permission ))
248
+ permission_object .add_attribute ('permission' , ** dict (type = attribute_type , value = permission , to_ids = False ))
240
249
self .misp_event .add_object (** permission_object )
241
250
self .references [file_object .uuid ].append (dict (referenced_uuid = permission_object .uuid ,
242
251
relationship_type = 'grants' ))
@@ -255,24 +264,24 @@ def parse_elf(self, fileinfo, file_object):
255
264
if elf .get ('type' ):
256
265
# Haven't seen anything but EXEC yet in the files I tested
257
266
attribute_value = "EXECUTABLE" if elf ['type' ] == "EXEC (Executable file)" else elf ['type' ]
258
- elf_object .add_attribute ('type' , ** dict (type = attribute_type , value = attribute_value ))
267
+ elf_object .add_attribute ('type' , ** dict (type = attribute_type , value = attribute_value , to_ids = False ))
259
268
for feature , relation in elf_object_mapping .items ():
260
269
if elf .get (feature ):
261
- elf_object .add_attribute (relation , ** dict (type = attribute_type , value = elf [feature ]))
270
+ elf_object .add_attribute (relation , ** dict (type = attribute_type , value = elf [feature ], to_ids = False ))
262
271
sections_number = len (fileinfo ['sections' ]['section' ])
263
- elf_object .add_attribute ('number-sections' , ** {'type' : 'counter' , 'value' : sections_number })
272
+ elf_object .add_attribute ('number-sections' , ** {'type' : 'counter' , 'value' : sections_number , 'to_ids' : False })
264
273
self .misp_event .add_object (** elf_object )
265
274
for section in fileinfo ['sections' ]['section' ]:
266
275
section_object = MISPObject ('elf-section' )
267
276
for feature in ('name' , 'type' ):
268
277
if section .get (feature ):
269
- section_object .add_attribute (feature , ** dict (type = attribute_type , value = section [feature ]))
278
+ section_object .add_attribute (feature , ** dict (type = attribute_type , value = section [feature ], to_ids = False ))
270
279
if section .get ('size' ):
271
- section_object .add_attribute (size , ** dict (type = size , value = int (section ['size' ], 16 )))
280
+ section_object .add_attribute (size , ** dict (type = size , value = int (section ['size' ], 16 ), to_ids = False ))
272
281
for flag in section ['flagsdesc' ]:
273
282
try :
274
283
attribute_value = elf_section_flags_mapping [flag ]
275
- section_object .add_attribute ('flag' , ** dict (type = attribute_type , value = attribute_value ))
284
+ section_object .add_attribute ('flag' , ** dict (type = attribute_type , value = attribute_value , to_ids = False ))
276
285
except KeyError :
277
286
print (f'Unknown elf section flag: { flag } ' )
278
287
continue
@@ -281,6 +290,8 @@ def parse_elf(self, fileinfo, file_object):
281
290
relationship_type = relationship ))
282
291
283
292
def parse_pe (self , fileinfo , file_object ):
293
+ if not self .import_pe :
294
+ return
284
295
try :
285
296
peinfo = fileinfo ['pe' ]
286
297
except KeyError :
@@ -292,27 +303,27 @@ def parse_pe(self, fileinfo, file_object):
292
303
self .misp_event .add_object (** file_object )
293
304
for field , mapping in pe_object_fields .items ():
294
305
attribute_type , object_relation = mapping
295
- pe_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : peinfo [field ]})
296
- pe_object .add_attribute ('compilation-timestamp' , ** {'type' : 'datetime' , 'value' : int (peinfo ['timestamp' ].split ()[0 ], 16 )})
306
+ pe_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : peinfo [field ], 'to_ids' : False })
307
+ pe_object .add_attribute ('compilation-timestamp' , ** {'type' : 'datetime' , 'value' : int (peinfo ['timestamp' ].split ()[0 ], 16 ), 'to_ids' : False })
297
308
program_name = fileinfo ['filename' ]
298
309
if peinfo ['versions' ]:
299
310
for feature in peinfo ['versions' ]['version' ]:
300
311
name = feature ['name' ]
301
312
if name == 'InternalName' :
302
313
program_name = feature ['value' ]
303
314
if name in pe_object_mapping :
304
- pe_object .add_attribute (pe_object_mapping [name ], ** {'type' : 'text' , 'value' : feature ['value' ]})
315
+ pe_object .add_attribute (pe_object_mapping [name ], ** {'type' : 'text' , 'value' : feature ['value' ], 'to_ids' : False })
305
316
sections_number = len (peinfo ['sections' ]['section' ])
306
- pe_object .add_attribute ('number-sections' , ** {'type' : 'counter' , 'value' : sections_number })
317
+ pe_object .add_attribute ('number-sections' , ** {'type' : 'counter' , 'value' : sections_number , 'to_ids' : False })
307
318
signatureinfo = peinfo ['signature' ]
308
319
if signatureinfo ['signed' ]:
309
320
signerinfo_object = MISPObject ('authenticode-signerinfo' )
310
321
pe_object .add_reference (signerinfo_object .uuid , 'signed-by' )
311
322
self .misp_event .add_object (** pe_object )
312
- signerinfo_object .add_attribute ('program-name' , ** {'type' : 'text' , 'value' : program_name })
323
+ signerinfo_object .add_attribute ('program-name' , ** {'type' : 'text' , 'value' : program_name , 'to_ids' : False })
313
324
for feature , mapping in signerinfo_object_mapping .items ():
314
325
attribute_type , object_relation = mapping
315
- signerinfo_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : signatureinfo [feature ]})
326
+ signerinfo_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : signatureinfo [feature ], 'to_ids' : False })
316
327
self .misp_event .add_object (** signerinfo_object )
317
328
else :
318
329
self .misp_event .add_object (** pe_object )
@@ -327,7 +338,7 @@ def parse_pe_section(self, section):
327
338
for feature , mapping in pe_section_object_mapping .items ():
328
339
if section .get (feature ):
329
340
attribute_type , object_relation = mapping
330
- section_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : section [feature ]})
341
+ section_object .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : section [feature ], 'to_ids' : False })
331
342
return section_object
332
343
333
344
def parse_network_interactions (self ):
@@ -339,21 +350,21 @@ def parse_network_interactions(self):
339
350
for key , mapping in domain_object_mapping .items ():
340
351
attribute_type , object_relation = mapping
341
352
domain_object .add_attribute (object_relation ,
342
- ** {'type' : attribute_type , 'value' : domain [key ]})
353
+ ** {'type' : attribute_type , 'value' : domain [key ], 'to_ids' : False })
343
354
self .misp_event .add_object (** domain_object )
344
355
reference = dict (referenced_uuid = domain_object .uuid , relationship_type = 'contacts' )
345
356
self .add_process_reference (domain ['@targetid' ], domain ['@currentpath' ], reference )
346
357
else :
347
358
attribute = MISPAttribute ()
348
- attribute .from_dict (** {'type' : 'domain' , 'value' : domain ['@name' ]})
359
+ attribute .from_dict (** {'type' : 'domain' , 'value' : domain ['@name' ], 'to_ids' : False })
349
360
self .misp_event .add_attribute (** attribute )
350
361
reference = dict (referenced_uuid = attribute .uuid , relationship_type = 'contacts' )
351
362
self .add_process_reference (domain ['@targetid' ], domain ['@currentpath' ], reference )
352
363
ipinfo = self .data ['ipinfo' ]
353
364
if ipinfo :
354
365
for ip in ipinfo ['ip' ]:
355
366
attribute = MISPAttribute ()
356
- attribute .from_dict (** {'type' : 'ip-dst' , 'value' : ip ['@ip' ]})
367
+ attribute .from_dict (** {'type' : 'ip-dst' , 'value' : ip ['@ip' ], 'to_ids' : False })
357
368
self .misp_event .add_attribute (** attribute )
358
369
reference = dict (referenced_uuid = attribute .uuid , relationship_type = 'contacts' )
359
370
self .add_process_reference (ip ['@targetid' ], ip ['@currentpath' ], reference )
@@ -363,7 +374,7 @@ def parse_network_interactions(self):
363
374
target_id = int (url ['@targetid' ])
364
375
current_path = url ['@currentpath' ]
365
376
attribute = MISPAttribute ()
366
- attribute_dict = {'type' : 'url' , 'value' : url ['@name' ]}
377
+ attribute_dict = {'type' : 'url' , 'value' : url ['@name' ], 'to_ids' : False }
367
378
if target_id != - 1 and current_path != 'unknown' :
368
379
self .references [self .process_references [(target_id , current_path )]].append ({
369
380
'referenced_uuid' : attribute .uuid ,
@@ -384,8 +395,8 @@ def parse_registryactivities(self, process_uuid, registryactivities):
384
395
registry_key = MISPObject ('registry-key' )
385
396
for field , mapping in regkey_object_mapping .items ():
386
397
attribute_type , object_relation = mapping
387
- registry_key .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : call [field ]})
388
- registry_key .add_attribute ('data-type' , ** {'type' : 'text' , 'value' : 'REG_{}' .format (call ['type' ].upper ())})
398
+ registry_key .add_attribute (object_relation , ** {'type' : attribute_type , 'value' : call [field ], 'to_ids' : False })
399
+ registry_key .add_attribute ('data-type' , ** {'type' : 'text' , 'value' : 'REG_{}' .format (call ['type' ].upper ()), 'to_ids' : False })
389
400
self .misp_event .add_object (** registry_key )
390
401
self .references [process_uuid ].append (dict (referenced_uuid = registry_key .uuid ,
391
402
relationship_type = relationship ))
@@ -398,7 +409,7 @@ def add_process_reference(self, target, currentpath, reference):
398
409
399
410
def create_attribute (self , attribute_type , attribute_value ):
400
411
attribute = MISPAttribute ()
401
- attribute .from_dict (** {'type' : attribute_type , 'value' : attribute_value })
412
+ attribute .from_dict (** {'type' : attribute_type , 'value' : attribute_value , 'to_ids' : False })
402
413
self .misp_event .add_attribute (** attribute )
403
414
return attribute .uuid
404
415
@@ -419,5 +430,5 @@ def prefetch_attributes_data(connection):
419
430
attributes = {}
420
431
for field , value in zip (network_behavior_fields , connection ):
421
432
attribute_type , object_relation = network_connection_object_mapping [field ]
422
- attributes [object_relation ] = {'type' : attribute_type , 'value' : value }
433
+ attributes [object_relation ] = {'type' : attribute_type , 'value' : value , 'to_ids' : False }
423
434
return attributes
0 commit comments