File size: 3,027 Bytes
7c89ed7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | # 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 https://mozilla.org/MPL/2.0/.
# Copyright (c) 2017 Mozilla Corporation
from mozdef_util.utilities.toUTC import toUTC
import os
import yaml
import jmespath
class message(object):
def __init__(self):
"""
Plugin used to fix object type discretions with cloudtrail messages
"""
self.registration = ["stackdriver"]
self.priority = 16
with open(os.path.join(os.path.dirname(__file__), "stackdriver_gceactivity.yml"), "r") as f:
mapping_map = f.read()
yap = yaml.safe_load(mapping_map)
self.eventtypes = list(yap.keys())
self.yap = yap
del mapping_map
def onMessage(self, message, metadata):
if "tags" not in message:
return (message, metadata)
if "stackdriver" not in message["tags"]:
return (message, metadata)
if "category" not in message:
return (message, metadata)
# XXX: move into a config file
cats = ["gceactivity"]
if message["category"] not in cats:
return (message, metadata)
event = message["details"]
newmessage = dict()
newmessage["receivedtimestamp"] = toUTC(message["receivedtimestamp"]).isoformat()
newmessage["timestamp"] = toUTC(event["timestamp"]).isoformat()
newmessage["utctimestamp"] = toUTC(event["timestamp"]).isoformat()
newmessage["category"] = message["category"]
newmessage["tags"] = message["tags"]
newmessage["source"] = message["source"]
newmessage["mozdefhostname"] = message["mozdefhostname"]
newmessage["customendpoint"] = ""
newmessage["details"] = {}
newmessage["details"] = message["details"]
newmessage["details"]["gceactivity"] = newmessage["details"]["jsonPayload"]
del newmessage["details"]["jsonPayload"]
# This is fake
newmessage["details"]["service"] = "compute.googleapis.com"
# Stuff fields that will be used as a summary with something, anything. The mapping function will hopefuly find something to overwrite it with.
newmessage["details"]["username"] = "UNKNOWN"
newmessage["details"]["resourcename"] = "UNKNOWN"
if message["category"] in self.eventtypes:
for key in self.yap[newmessage["category"]]:
mappedvalue = jmespath.search(self.yap[newmessage["category"]][key], newmessage)
# JMESPath likes to silently return a None object
if mappedvalue is not None:
newmessage["details"][key] = mappedvalue
# This is redundant
newmessage["summary"] = "{0} executed {1} on {2}".format(
newmessage["details"]["username"], newmessage["details"]["action"], newmessage["details"]["resourcename"],
)
return (newmessage, metadata)
|