diff --git a/examples/asciidoc_generator.py b/examples/asciidoc_generator.py index 156a7ff..f1a09a5 100755 --- a/examples/asciidoc_generator.py +++ b/examples/asciidoc_generator.py @@ -1,55 +1,21 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +import argparse +from datetime import date +import importlib + from pymisp import MISPEvent from defang import defang -import argparse from pytaxonomies import Taxonomies -from datetime import date -headers = """ -:toc: right -:toclevels: 1 -:toc-title: Daily Report -:icons: font -:sectanchors: -:sectlinks: -= Daily report by {org_name} -{date} - -:icons: font - -""" - -event_level_tags = """ -IMPORTANT: This event is classified TLP:{value}. - -{expanded} - -""" - -attributes = """ -=== Indicator(s) of compromise - -{list_attributes} - -""" - -title = """ -== ({internal_id}) {title} - -{summary} - -""" - -types_to_attach = ['ip-dst', 'url', 'domain'] -objects_to_attach = ['domain-ip'] class ReportGenerator(): - - def __init__(self): + def __init__(self, profile="daily_report"): self.taxonomies = Taxonomies() self.report = '' + profile_name = "profiles.{}".format(profile) + self.template = importlib.import_module(name=profile_name) def from_remote(self, event_id): from pymisp import PyMISP @@ -66,15 +32,16 @@ class ReportGenerator(): def attributes(self): if not self.misp_event.attributes: return '' - list_attributes = '' + list_attributes = [] for attribute in self.misp_event.attributes: - if attribute.type in types_to_attach: - list_attributes += "\n* {}\n".format(defang(attribute.value)) + if attribute.type in self.template.types_to_attach: + list_attributes.append("* {}".format(defang(attribute.value))) for obj in self.misp_event.Object: - for attribute in obj.Attribute: - if attribute.type in types_to_attach: - list_attributes += "\n* {}\n".format(defang(attribute.value)) - return attributes.format(list_attributes=list_attributes) + if obj.name in self.template.objects_to_attach: + for attribute in obj.Attribute: + if attribute.type in self.template.types_to_attach: + list_attributes.append("* {}".format(defang(attribute.value))) + return self.template.attributes.format(list_attributes="\n".join(list_attributes)) def _get_tag_info(self, machinetag): return self.taxonomies.revert_machinetag(machinetag) @@ -82,7 +49,7 @@ class ReportGenerator(): def report_headers(self): content = {'org_name': 'name', 'date': date.today().isoformat()} - self.report += headers.format(**content) + self.report += self.template.headers.format(**content) def event_level_tags(self): if not self.misp_event.Tag: @@ -91,7 +58,7 @@ class ReportGenerator(): # Only look for TLP for now if tag['name'].startswith('tlp'): tax, predicate = self._get_tag_info(tag['name']) - return event_level_tags.format(value=predicate.predicate.upper(), expanded=predicate.expanded) + return self.template.event_level_tags.format(value=predicate.predicate.upper(), expanded=predicate.expanded) def title(self): internal_id = '' @@ -106,34 +73,42 @@ class ReportGenerator(): if a.object_relation == 'summary': summary = a.value - return title.format(internal_id=internal_id, title=self.misp_event.info, - summary=summary) - + return self.template.title.format(internal_id=internal_id, title=self.misp_event.info, + summary=summary) def asciidoc(self, lang='en'): self.report += self.title() self.report += self.event_level_tags() self.report += self.attributes() + if __name__ == '__main__': + try: + parser = argparse.ArgumentParser(description='Create a human-readable report out of a MISP event') + parser.add_argument("--profile", default="daily_report", help="Profile template to use") + parser.add_argument("-o", "--output", help="Output file to write to (generally ends in .adoc)") + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("-e", "--event", default=[], nargs='+', help="Event ID to get.") + group.add_argument("-p", "--path", default=[], nargs='+', help="Path to the JSON dump.") - parser = argparse.ArgumentParser(description='Create a human-readable report out of a MISP event') - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument("-e", "--event", default=[], nargs='+', help="Event ID to get.") - group.add_argument("-p", "--path", default=[], nargs='+', help="Path to the JSON dump.") + args = parser.parse_args() - args = parser.parse_args() + report = ReportGenerator(args.profile) + report.report_headers() - report = ReportGenerator() - report.report_headers() + if args.event: + for eid in args.event: + report.from_remote(eid) + report.asciidoc() + else: + for f in args.path: + report.from_file(f) + report.asciidoc() - if args.event: - for eid in args.event: - report.from_remote(eid) - report.asciidoc() - else: - for f in args.path: - report.from_file(f) - report.asciidoc() - - print(report.report) + if args.output: + with open(args.output, "w") as ofile: + ofile.write(report.report) + else: + print(report.report) + except ModuleNotFoundError as err: + print(err) diff --git a/examples/profiles/__init__.py b/examples/profiles/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/profiles/daily_report.py b/examples/profiles/daily_report.py new file mode 100644 index 0000000..2799333 --- /dev/null +++ b/examples/profiles/daily_report.py @@ -0,0 +1,37 @@ +types_to_attach = ['ip-dst', 'url', 'domain'] +objects_to_attach = ['domain-ip'] + +headers = """ +:toc: right +:toclevels: 1 +:toc-title: Daily Report +:icons: font +:sectanchors: +:sectlinks: += Daily report by {org_name} +{date} + +:icons: font + +""" + +event_level_tags = """ +IMPORTANT: This event is classified TLP:{value}. + +{expanded} + +""" + +attributes = """ +=== Indicator(s) of compromise + +{list_attributes} + +""" + +title = """ +== ({internal_id}) {title} + +{summary} + +""" diff --git a/examples/profiles/weekly_report.py b/examples/profiles/weekly_report.py new file mode 100644 index 0000000..1005fd9 --- /dev/null +++ b/examples/profiles/weekly_report.py @@ -0,0 +1,33 @@ +types_to_attach = ['ip-dst', 'url', 'domain', 'md5'] +objects_to_attach = ['domain-ip', 'file'] + +headers = """ +:toc: right +:toclevels: 1 +:toc-title: Weekly Report +:icons: font +:sectanchors: +:sectlinks: += Weekly report by {org_name} +{date} + +:icons: font + +""" + +event_level_tags = """ +""" + +attributes = """ +=== Indicator(s) of compromise + +{list_attributes} + +""" + +title = """ +== ({internal_id}) {title} + +{summary} + +"""