mirror of https://github.com/CIRCL/AIL-framework
chg: [mail exporter] add obj content extract for each yara rule match
parent
4e3784922c
commit
c01b806ae3
|
@ -124,16 +124,26 @@ class MailExporterTracker(MailExporter):
|
||||||
def __init__(self, host=None, port=None, password=None, user='', sender=''):
|
def __init__(self, host=None, port=None, password=None, user='', sender=''):
|
||||||
super().__init__(host=host, port=port, password=password, user=user, sender=sender)
|
super().__init__(host=host, port=port, password=password, user=user, sender=sender)
|
||||||
|
|
||||||
def export(self, tracker, obj): # TODO match
|
def export(self, tracker, obj, matches=[]):
|
||||||
tracker_type = tracker.get_type()
|
tracker_type = tracker.get_type()
|
||||||
tracker_name = tracker.get_tracked()
|
tracker_name = tracker.get_tracked()
|
||||||
subject = f'AIL Framework Tracker: {tracker_name}' # TODO custom subject
|
description = tracker.get_description()
|
||||||
|
if not description:
|
||||||
|
description = tracker_name
|
||||||
|
|
||||||
|
subject = f'AIL Framework Tracker: {description}'
|
||||||
body = f"AIL Framework, New occurrence for {tracker_type} tracker: {tracker_name}\n"
|
body = f"AIL Framework, New occurrence for {tracker_type} tracker: {tracker_name}\n"
|
||||||
body += f'Item: {obj.id}\nurl:{obj.get_link()}'
|
body += f'Item: {obj.id}\nurl:{obj.get_link()}'
|
||||||
|
|
||||||
# TODO match option
|
if matches:
|
||||||
# if match:
|
body += '\n'
|
||||||
# body += f'Tracker Match:\n\n{escape(match)}'
|
nb = 1
|
||||||
|
for match in matches:
|
||||||
|
body += f'\nMatch {nb}: {match[0]}\nExtract:\n{match[1]}\n\n'
|
||||||
|
nb += 1
|
||||||
|
else:
|
||||||
|
body = f"AIL Framework, New occurrence for {tracker_type} tracker: {tracker_name}\n"
|
||||||
|
body += f'Item: {obj.id}\nurl:{obj.get_link()}'
|
||||||
|
|
||||||
for mail in tracker.get_mails():
|
for mail in tracker.get_mails():
|
||||||
self._export(mail, subject, body)
|
self._export(mail, subject, body)
|
||||||
|
|
|
@ -248,7 +248,8 @@ class Tracker:
|
||||||
return self._get_field('user_id')
|
return self._get_field('user_id')
|
||||||
|
|
||||||
def webhook_export(self):
|
def webhook_export(self):
|
||||||
return r_tracker.hexists(f'tracker:{self.uuid}', 'webhook')
|
webhook = self.get_webhook()
|
||||||
|
return webhook is not None and webhook
|
||||||
|
|
||||||
def get_webhook(self):
|
def get_webhook(self):
|
||||||
return r_tracker.hget(f'tracker:{self.uuid}', 'webhook')
|
return r_tracker.hget(f'tracker:{self.uuid}', 'webhook')
|
||||||
|
|
|
@ -73,8 +73,56 @@ class Tracker_Yara(AbstractModule):
|
||||||
print(f'{self.obj.get_id()}: yara scanning timed out')
|
print(f'{self.obj.get_id()}: yara scanning timed out')
|
||||||
self.redis_logger.info(f'{self.obj.get_id()}: yara scanning timed out')
|
self.redis_logger.info(f'{self.obj.get_id()}: yara scanning timed out')
|
||||||
|
|
||||||
|
def convert_byte_offset_to_string(self, b_content, offset):
|
||||||
|
byte_chunk = b_content[:offset + 1]
|
||||||
|
try:
|
||||||
|
string_chunk = byte_chunk.decode()
|
||||||
|
offset = len(string_chunk) - 1
|
||||||
|
return offset
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return self.convert_byte_offset_to_string(b_content, offset - 1)
|
||||||
|
|
||||||
|
def extract_matches(self, data, limit=500, lines=5):
|
||||||
|
matches = []
|
||||||
|
content = self.obj.get_content()
|
||||||
|
l_content = len(content)
|
||||||
|
b_content = content.encode()
|
||||||
|
for string_match in data.get('strings'):
|
||||||
|
for string_match_instance in string_match.instances:
|
||||||
|
start = string_match_instance.offset
|
||||||
|
value = string_match_instance.matched_data.decode()
|
||||||
|
end = start + string_match_instance.matched_length
|
||||||
|
# str
|
||||||
|
start = self.convert_byte_offset_to_string(b_content, start)
|
||||||
|
end = self.convert_byte_offset_to_string(b_content, end)
|
||||||
|
|
||||||
|
# Start
|
||||||
|
if start > limit:
|
||||||
|
i_start = start - limit
|
||||||
|
else:
|
||||||
|
i_start = 0
|
||||||
|
str_start = content[i_start:start].splitlines()
|
||||||
|
if len(str_start) > lines:
|
||||||
|
str_start = '\n'.join(str_start[-lines + 1:])
|
||||||
|
else:
|
||||||
|
str_start = content[i_start:start]
|
||||||
|
|
||||||
|
# End
|
||||||
|
if end + limit > l_content:
|
||||||
|
i_end = l_content
|
||||||
|
else:
|
||||||
|
i_end = end + limit
|
||||||
|
str_end = content[end:i_end].splitlines()
|
||||||
|
if len(str_end) > lines:
|
||||||
|
str_end = '\n'.join(str_end[:lines + 1])
|
||||||
|
else:
|
||||||
|
str_end = content[end:i_end]
|
||||||
|
matches.append((value, f'{str_start}{value}{str_end}'))
|
||||||
|
return matches
|
||||||
|
|
||||||
def yara_rules_match(self, data):
|
def yara_rules_match(self, data):
|
||||||
tracker_name = data['namespace']
|
tracker_name = data['namespace']
|
||||||
|
matches = None
|
||||||
obj_id = self.obj.get_id()
|
obj_id = self.obj.get_id()
|
||||||
for tracker_uuid in Tracker.get_trackers_by_tracked_obj_type('yara', self.obj.get_type(), tracker_name):
|
for tracker_uuid in Tracker.get_trackers_by_tracked_obj_type('yara', self.obj.get_type(), tracker_name):
|
||||||
tracker = Tracker.Tracker(tracker_uuid)
|
tracker = Tracker.Tracker(tracker_uuid)
|
||||||
|
@ -96,8 +144,9 @@ class Tracker_Yara(AbstractModule):
|
||||||
|
|
||||||
# Mails
|
# Mails
|
||||||
if tracker.mail_export():
|
if tracker.mail_export():
|
||||||
# TODO add matches + custom subjects
|
if not matches:
|
||||||
self.exporters['mail'].export(tracker, self.obj)
|
matches = self.extract_matches(data)
|
||||||
|
self.exporters['mail'].export(tracker, self.obj, matches)
|
||||||
|
|
||||||
# Webhook
|
# Webhook
|
||||||
if tracker.webhook_export():
|
if tracker.webhook_export():
|
||||||
|
|
Loading…
Reference in New Issue