mirror of https://github.com/MISP/misp-modules
Merge branch 'master' of github.com:MISP/misp-modules
commit
d8e6226c2b
|
@ -8,60 +8,27 @@ import subprocess
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
from pymisp import MISPEvent
|
from pymisp import MISPEvent
|
||||||
|
from pymisp.tools import reportlab_generator
|
||||||
|
|
||||||
misperrors = {'error': 'Error'}
|
misperrors = {'error': 'Error'}
|
||||||
|
|
||||||
moduleinfo = {'version': '1',
|
moduleinfo = {'version': '2',
|
||||||
'author': 'Raphaël Vinot',
|
'author': 'Vincent Falconieri (prev. Raphaël Vinot)',
|
||||||
'description': 'Simple export to PDF',
|
'description': 'Simple export to PDF',
|
||||||
'module-type': ['export'],
|
'module-type': ['export'],
|
||||||
'require_standard_format': True}
|
'require_standard_format': True}
|
||||||
|
|
||||||
moduleconfig = []
|
# config fields that your code expects from the site admin
|
||||||
|
moduleconfig = ["MISP_base_url_for_dynamic_link", "MISP_name_for_metadata"]
|
||||||
|
|
||||||
mispattributes = {}
|
mispattributes = {}
|
||||||
|
|
||||||
outputFileExtension = "pdf"
|
outputFileExtension = "pdf"
|
||||||
responseType = "application/pdf"
|
responseType = "application/pdf"
|
||||||
|
|
||||||
types_to_attach = ['ip-dst', 'url', 'domain']
|
types_to_attach = ['ip-dst', 'url', 'domain']
|
||||||
objects_to_attach = ['domain-ip']
|
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}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class ReportGenerator():
|
class ReportGenerator():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -79,61 +46,6 @@ class ReportGenerator():
|
||||||
self.misp_event = MISPEvent()
|
self.misp_event = MISPEvent()
|
||||||
self.misp_event.load(event)
|
self.misp_event.load(event)
|
||||||
|
|
||||||
def attributes(self):
|
|
||||||
if not self.misp_event.attributes:
|
|
||||||
return ''
|
|
||||||
list_attributes = []
|
|
||||||
for attribute in self.misp_event.attributes:
|
|
||||||
if attribute.type in types_to_attach:
|
|
||||||
list_attributes.append("* {}".format(attribute.value))
|
|
||||||
for obj in self.misp_event.Object:
|
|
||||||
if obj.name in objects_to_attach:
|
|
||||||
for attribute in obj.Attribute:
|
|
||||||
if attribute.type in types_to_attach:
|
|
||||||
list_attributes.append("* {}".format(attribute.value))
|
|
||||||
return attributes.format(list_attributes="\n".join(list_attributes))
|
|
||||||
|
|
||||||
def _get_tag_info(self, machinetag):
|
|
||||||
return self.taxonomies.revert_machinetag(machinetag)
|
|
||||||
|
|
||||||
def report_headers(self):
|
|
||||||
content = {'org_name': 'name',
|
|
||||||
'date': date.today().isoformat()}
|
|
||||||
self.report += headers.format(**content)
|
|
||||||
|
|
||||||
def event_level_tags(self):
|
|
||||||
if not self.misp_event.Tag:
|
|
||||||
return ''
|
|
||||||
for tag in self.misp_event.Tag:
|
|
||||||
# Only look for TLP for now
|
|
||||||
if tag['name'].startswith('tlp'):
|
|
||||||
tax, predicate = self._get_tag_info(tag['name'])
|
|
||||||
return self.event_level_tags.format(value=predicate.predicate.upper(), expanded=predicate.expanded)
|
|
||||||
|
|
||||||
def title(self):
|
|
||||||
internal_id = ''
|
|
||||||
summary = ''
|
|
||||||
# Get internal refs for report
|
|
||||||
if not hasattr(self.misp_event, 'Object'):
|
|
||||||
return ''
|
|
||||||
for obj in self.misp_event.Object:
|
|
||||||
if obj.name != 'report':
|
|
||||||
continue
|
|
||||||
for a in obj.Attribute:
|
|
||||||
if a.object_relation == 'case-number':
|
|
||||||
internal_id = a.value
|
|
||||||
if a.object_relation == 'summary':
|
|
||||||
summary = a.value
|
|
||||||
|
|
||||||
return 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()
|
|
||||||
|
|
||||||
|
|
||||||
def handler(q=False):
|
def handler(q=False):
|
||||||
if q is False:
|
if q is False:
|
||||||
return False
|
return False
|
||||||
|
@ -143,18 +55,21 @@ def handler(q=False):
|
||||||
if 'data' not in request:
|
if 'data' not in request:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for evt in request['data']:
|
config = {}
|
||||||
report = ReportGenerator()
|
|
||||||
report.report_headers()
|
|
||||||
report.from_event(evt)
|
|
||||||
report.asciidoc()
|
|
||||||
|
|
||||||
command_line = 'asciidoctor-pdf -'
|
# Construct config object for reportlab_generator
|
||||||
args = shlex.split(command_line)
|
for config_item in moduleconfig :
|
||||||
with subprocess.Popen(args, stdout=subprocess.PIPE, stdin=subprocess.PIPE) as process:
|
if (request.get('config')) and (request['config'].get(config_item) is not None):
|
||||||
cmd_out, cmd_err = process.communicate(
|
config[config_item] = request['config'].get(config_item)
|
||||||
input=report.report.encode('utf-8'))
|
|
||||||
return {'response': [], 'data': str(base64.b64encode(cmd_out), 'utf-8')}
|
for evt in request['data']:
|
||||||
|
|
||||||
|
misp_event = MISPEvent()
|
||||||
|
misp_event.load(evt)
|
||||||
|
|
||||||
|
pdf = reportlab_generator.get_base64_from_value(reportlab_generator.convert_event_in_pdf_buffer(misp_event, config))
|
||||||
|
|
||||||
|
return {'response': [], 'data': str(pdf, 'utf-8')}
|
||||||
|
|
||||||
|
|
||||||
def introspection():
|
def introspection():
|
||||||
|
|
Loading…
Reference in New Issue