mirror of https://github.com/MISP/PyMISP
chg: Update asciidoctor generator
parent
30da658292
commit
ea327ceffb
|
@ -1,55 +1,21 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from datetime import date
|
||||||
|
import importlib
|
||||||
|
|
||||||
from pymisp import MISPEvent
|
from pymisp import MISPEvent
|
||||||
from defang import defang
|
from defang import defang
|
||||||
import argparse
|
|
||||||
from pytaxonomies import Taxonomies
|
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():
|
class ReportGenerator():
|
||||||
|
def __init__(self, profile="daily_report"):
|
||||||
def __init__(self):
|
|
||||||
self.taxonomies = Taxonomies()
|
self.taxonomies = Taxonomies()
|
||||||
self.report = ''
|
self.report = ''
|
||||||
|
profile_name = "profiles.{}".format(profile)
|
||||||
|
self.template = importlib.import_module(name=profile_name)
|
||||||
|
|
||||||
def from_remote(self, event_id):
|
def from_remote(self, event_id):
|
||||||
from pymisp import PyMISP
|
from pymisp import PyMISP
|
||||||
|
@ -66,15 +32,16 @@ class ReportGenerator():
|
||||||
def attributes(self):
|
def attributes(self):
|
||||||
if not self.misp_event.attributes:
|
if not self.misp_event.attributes:
|
||||||
return ''
|
return ''
|
||||||
list_attributes = ''
|
list_attributes = []
|
||||||
for attribute in self.misp_event.attributes:
|
for attribute in self.misp_event.attributes:
|
||||||
if attribute.type in types_to_attach:
|
if attribute.type in self.template.types_to_attach:
|
||||||
list_attributes += "\n* {}\n".format(defang(attribute.value))
|
list_attributes.append("* {}".format(defang(attribute.value)))
|
||||||
for obj in self.misp_event.Object:
|
for obj in self.misp_event.Object:
|
||||||
for attribute in obj.Attribute:
|
if obj.name in self.template.objects_to_attach:
|
||||||
if attribute.type in types_to_attach:
|
for attribute in obj.Attribute:
|
||||||
list_attributes += "\n* {}\n".format(defang(attribute.value))
|
if attribute.type in self.template.types_to_attach:
|
||||||
return attributes.format(list_attributes=list_attributes)
|
list_attributes.append("* {}".format(defang(attribute.value)))
|
||||||
|
return self.template.attributes.format(list_attributes="\n".join(list_attributes))
|
||||||
|
|
||||||
def _get_tag_info(self, machinetag):
|
def _get_tag_info(self, machinetag):
|
||||||
return self.taxonomies.revert_machinetag(machinetag)
|
return self.taxonomies.revert_machinetag(machinetag)
|
||||||
|
@ -82,7 +49,7 @@ class ReportGenerator():
|
||||||
def report_headers(self):
|
def report_headers(self):
|
||||||
content = {'org_name': 'name',
|
content = {'org_name': 'name',
|
||||||
'date': date.today().isoformat()}
|
'date': date.today().isoformat()}
|
||||||
self.report += headers.format(**content)
|
self.report += self.template.headers.format(**content)
|
||||||
|
|
||||||
def event_level_tags(self):
|
def event_level_tags(self):
|
||||||
if not self.misp_event.Tag:
|
if not self.misp_event.Tag:
|
||||||
|
@ -91,7 +58,7 @@ class ReportGenerator():
|
||||||
# Only look for TLP for now
|
# Only look for TLP for now
|
||||||
if tag['name'].startswith('tlp'):
|
if tag['name'].startswith('tlp'):
|
||||||
tax, predicate = self._get_tag_info(tag['name'])
|
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):
|
def title(self):
|
||||||
internal_id = ''
|
internal_id = ''
|
||||||
|
@ -106,34 +73,42 @@ class ReportGenerator():
|
||||||
if a.object_relation == 'summary':
|
if a.object_relation == 'summary':
|
||||||
summary = a.value
|
summary = a.value
|
||||||
|
|
||||||
return title.format(internal_id=internal_id, title=self.misp_event.info,
|
return self.template.title.format(internal_id=internal_id, title=self.misp_event.info,
|
||||||
summary=summary)
|
summary=summary)
|
||||||
|
|
||||||
|
|
||||||
def asciidoc(self, lang='en'):
|
def asciidoc(self, lang='en'):
|
||||||
self.report += self.title()
|
self.report += self.title()
|
||||||
self.report += self.event_level_tags()
|
self.report += self.event_level_tags()
|
||||||
self.report += self.attributes()
|
self.report += self.attributes()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
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')
|
args = parser.parse_args()
|
||||||
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()
|
report = ReportGenerator(args.profile)
|
||||||
|
report.report_headers()
|
||||||
|
|
||||||
report = ReportGenerator()
|
if args.event:
|
||||||
report.report_headers()
|
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:
|
if args.output:
|
||||||
for eid in args.event:
|
with open(args.output, "w") as ofile:
|
||||||
report.from_remote(eid)
|
ofile.write(report.report)
|
||||||
report.asciidoc()
|
else:
|
||||||
else:
|
print(report.report)
|
||||||
for f in args.path:
|
except ModuleNotFoundError as err:
|
||||||
report.from_file(f)
|
print(err)
|
||||||
report.asciidoc()
|
|
||||||
|
|
||||||
print(report.report)
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
"""
|
|
@ -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}
|
||||||
|
|
||||||
|
"""
|
Loading…
Reference in New Issue