MozDef/mq/plugins/suricataFixup.py

185 строки
10 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Copyright (c) 2018 Mozilla Corporation
import json
from datetime import datetime
from platform import node
from mozdef_util.utilities.toUTC import toUTC
class message(object):
def __init__(self):
'''
takes an incoming suricata event
and parses the message to extract
data points, and sets the type
field
'''
self.registration = ['suricata']
self.priority = 5
try:
self.mozdefhostname = '{0}'.format(node())
except:
self.mozdefhostname = 'failed to fetch mozdefhostname'
pass
def onMessage(self, message, metadata):
# make sure I really wanted to see this message
# bail out early if not
if 'customendpoint' not in message:
return message, metadata
if 'category' not in message:
return message, metadata
if message['category'] != 'suricata':
return message, metadata
# move Suricata specific fields under 'details' while preserving metadata
newmessage = dict()
# Set NSM as type for categorical filtering of events.
newmessage["type"] = "nsm"
try:
newmessage['details'] = json.loads(message['message'])
except:
newmessage['details'] = {}
newmessage['rawdetails'] = message
# move some fields that are expected at the event 'root' where they belong
if 'host_from' in message:
newmessage['hostname'] = message['host_from']
if 'tags' in message:
newmessage['tags'] = message['tags']
if 'category' in message:
newmessage['category'] = message['category']
newmessage['source'] = 'unknown'
if 'source' in message:
newmessage['source'] = message['source']
logtype = newmessage['source']
newmessage['event_type'] = 'unknown'
if 'event_type' in message:
newmessage['event_type'] = message['event_type']
eventtype = newmessage['event_type']
# add mandatory fields
if 'flow' in newmessage['details']:
if 'start' in newmessage['details']['flow']:
newmessage['utctimestamp'] = toUTC(newmessage['details']['flow']['start']).isoformat()
newmessage['timestamp'] = toUTC(newmessage['details']['flow']['start']).isoformat()
else:
# a malformed message somehow managed to crawl to us, let's put it somewhat together
newmessage['utctimestamp'] = toUTC(datetime.now()).isoformat()
newmessage['timestamp'] = toUTC(datetime.now()).isoformat()
newmessage['receivedtimestamp'] = toUTC(datetime.now()).isoformat()
newmessage['eventsource'] = 'nsm'
newmessage['severity'] = 'INFO'
newmessage['mozdefhostname'] = self.mozdefhostname
if 'details' in newmessage:
newmessage['details']['sourceipaddress'] = "0.0.0.0"
newmessage['details']['destinationipaddress'] = "0.0.0.0"
newmessage['details']['sourceport'] = 0
newmessage['details']['destinationport'] = 0
if 'alert' in newmessage['details']:
newmessage['details']['suricata_alert'] = newmessage['details']['alert']
del(newmessage['details']['alert'])
if 'src_ip' in newmessage['details']:
newmessage['details']['sourceipaddress'] = newmessage['details']['src_ip']
del(newmessage['details']['src_ip'])
if 'src_port' in newmessage['details']:
newmessage['details']['sourceport'] = newmessage['details']['src_port']
del(newmessage['details']['src_port'])
if 'dest_ip' in newmessage['details']:
newmessage['details']['destinationipaddress'] = newmessage['details']['dest_ip']
del(newmessage['details']['dest_ip'])
if 'dest_port' in newmessage['details']:
newmessage['details']['destinationport'] = newmessage['details']['dest_port']
del(newmessage['details']['dest_port'])
if 'file_name' in newmessage['details']:
del(newmessage['details']['file_name'])
if 'message' in newmessage['details']:
del(newmessage['details']['message'])
if 'source' in newmessage['details']:
del(newmessage['details']['source'])
if logtype == 'eve-log':
if eventtype == 'alert':
# Truncate packet, payload and payload_printable to reasonable sizes
if 'packet' in newmessage['details']:
newmessage['details']['packet'] = newmessage['details']['packet'][0:4095]
if 'payload' in newmessage['details']:
newmessage['details']['payload'] = newmessage['details']['payload'][0:4095]
if 'payload_printable' in newmessage['details']:
newmessage['details']['payload_printable'] = newmessage['details']['payload_printable'][0:4095]
# Match names to Bro
newmessage['details']['originipbytes'] = 0
newmessage['details']['responseipbytes'] = 0
newmessage['details']['orig_pkts'] = 0
newmessage['details']['resp_pkts'] = 0
if 'flow' in newmessage['details']:
if 'bytes_toserver' in newmessage['details']['flow']:
newmessage['details']['originipbytes'] = newmessage['details']['flow']['bytes_toserver']
del(newmessage['details']['flow']['bytes_toserver'])
if 'bytes_toclient' in newmessage['details']['flow']:
newmessage['details']['responseipbytes'] = newmessage['details']['flow']['bytes_toclient']
del(newmessage['details']['flow']['bytes_toclient'])
if 'pkts_toserver' in newmessage['details']['flow']:
newmessage['details']['orig_pkts'] = newmessage['details']['flow']['pkts_toserver']
del(newmessage['details']['flow']['pkts_toserver'])
if 'pkts_toclient' in newmessage['details']['flow']:
newmessage['details']['resp_pkts'] = newmessage['details']['flow']['pkts_toclient']
del(newmessage['details']['flow']['pkts_toclient'])
if 'http' in newmessage['details']:
if 'hostname' in newmessage['details']['http']:
newmessage['details']['host'] = newmessage['details']['http']['hostname']
del(newmessage['details']['http']['hostname'])
if 'http_method' in newmessage['details']['http']:
newmessage['details']['method'] = newmessage['details']['http']['http_method']
del(newmessage['details']['http']['http_method'])
if 'http_user_agent' in newmessage['details']['http']:
newmessage['details']['user_agent'] = newmessage['details']['http']['http_user_agent']
del(newmessage['details']['http']['http_user_agent'])
if 'status' in newmessage['details']['http']:
newmessage['details']['status_code'] = newmessage['details']['http']['status']
del(newmessage['details']['http']['status'])
if 'url' in newmessage['details']['http']:
newmessage['details']['uri'] = newmessage['details']['http']['url']
del(newmessage['details']['http']['url'])
if 'redirect' in newmessage['details']['http']:
newmessage['details']['redirect_dst'] = newmessage['details']['http']['redirect']
del(newmessage['details']['http']['redirect'])
if 'length' in newmessage['details']['http']:
newmessage['details']['request_body_len'] = newmessage['details']['http']['length']
del(newmessage['details']['http']['length'])
if 'http_response_body' in newmessage['details']['http']:
newmessage['details']['http_response_body'] = newmessage['details']['http']['http_response_body'][0:4095]
del(newmessage['details']['http']['http_response_body'])
if 'http_response_body_printable' in newmessage['details']['http']:
newmessage['details']['http_response_body_printable'] = newmessage['details']['http']['http_response_body_printable'][0:4095]
del(newmessage['details']['http']['http_response_body_printable'])
if 'app_proto' in newmessage['details']:
newmessage['details']['service'] = newmessage['details']['app_proto']
del(newmessage['details']['app_proto'])
# Make sure details.vars.flowbits exceptions are handled
if 'vars' in newmessage['details']:
if 'flowbits' in newmessage['details']['vars']:
if 'ET.http.javaclient' in newmessage['details']['vars']['flowbits']:
if 'ET.http.javaclient.vulnerable':
del(newmessage['details']['vars']['flowbits']['ET.http.javaclient'])
newmessage['details']['vars']['flowbits']['ET.http.javaclient.vulnerable'] = "True"
newmessage['summary'] = (
'{sourceipaddress}:'+
'{sourceport} -> '+
'{destinationipaddress}:'
'{destinationport}'
).format(**newmessage['details'])
return (newmessage, metadata)
return (newmessage, metadata)