From c01b806ae30c6304bee5203b6fd46b389cbf1c2b Mon Sep 17 00:00:00 2001 From: Terrtia Date: Thu, 24 Aug 2023 11:11:57 +0200 Subject: [PATCH] chg: [mail exporter] add obj content extract for each yara rule match --- bin/exporter/MailExporter.py | 20 ++++++++++---- bin/lib/Tracker.py | 3 +- bin/trackers/Tracker_Yara.py | 53 ++++++++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/bin/exporter/MailExporter.py b/bin/exporter/MailExporter.py index c4d3f5b5..40ee1708 100755 --- a/bin/exporter/MailExporter.py +++ b/bin/exporter/MailExporter.py @@ -124,16 +124,26 @@ class MailExporterTracker(MailExporter): def __init__(self, host=None, port=None, password=None, user='', 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_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'Item: {obj.id}\nurl:{obj.get_link()}' - # TODO match option - # if match: - # body += f'Tracker Match:\n\n{escape(match)}' + if matches: + body += '\n' + 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(): self._export(mail, subject, body) diff --git a/bin/lib/Tracker.py b/bin/lib/Tracker.py index c06e303d..4baa3e5f 100755 --- a/bin/lib/Tracker.py +++ b/bin/lib/Tracker.py @@ -248,7 +248,8 @@ class Tracker: return self._get_field('user_id') 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): return r_tracker.hget(f'tracker:{self.uuid}', 'webhook') diff --git a/bin/trackers/Tracker_Yara.py b/bin/trackers/Tracker_Yara.py index fab397d1..1cebeaa6 100755 --- a/bin/trackers/Tracker_Yara.py +++ b/bin/trackers/Tracker_Yara.py @@ -73,8 +73,56 @@ class Tracker_Yara(AbstractModule): print(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): tracker_name = data['namespace'] + matches = None obj_id = self.obj.get_id() for tracker_uuid in Tracker.get_trackers_by_tracked_obj_type('yara', self.obj.get_type(), tracker_name): tracker = Tracker.Tracker(tracker_uuid) @@ -96,8 +144,9 @@ class Tracker_Yara(AbstractModule): # Mails if tracker.mail_export(): - # TODO add matches + custom subjects - self.exporters['mail'].export(tracker, self.obj) + if not matches: + matches = self.extract_matches(data) + self.exporters['mail'].export(tracker, self.obj, matches) # Webhook if tracker.webhook_export():