BigSnarf blog

Infosec FTW

Monthly Archives: March 2016

Real Time Analytics with PostgreSQL

Screen Shot 2016-04-02 at 10.38.53 PMScreen Shot 2016-03-29 at 8.18.46 AM

Screen Shot 2016-04-02 at 8.48.39 AM

 

RF, SVM, KNN ensembles training

Screen Shot 2016-03-26 at 12.24.10 AM

Spark OLAP

STL for anomaly detection

Monitor Cloudtrail logs with this Python Slackbot – Who is using AWS Console?

Screen Shot 2016-07-05 at 11.44.32 PM


#! /usr/local/env python
# coding: utf-8
import gzip
import json
from pprint import pprint
import pandas as pd
from pandas.io.json import json_normalize
import sys
import socket
import boto
import os
import ipaddress
import asyncio
import glob
from urllib.parse import urljoin
from urllib.parse import urlencode
import urllib.request as urlrequest
class Slack():
def __init__(self, url=""):
self.url = url
self.opener = urlrequest.build_opener(urlrequest.HTTPHandler())
def notify(self, **kwargs):
"""
Send message to slack API
"""
return self.send(kwargs)
def send(self, payload):
"""
Send payload to slack API
"""
payload_json = json.dumps(payload)
data = urlencode({"payload": payload_json})
req = urlrequest.Request(self.url)
response = self.opener.open(req, data.encode('utf-8')).read()
return response.decode('utf-8')
class CloudtrailAnalysis():
@staticmethod
def check_value(file_name, df_data, value):
if df_data[df_data['eventName'] == value].empty:
pass
else:
frame = df_data[df_data['eventName'] == value]
#print(df_data[df_data['eventName'] == value])
try:
normalized_name = frame['userIdentity.userName'].values[0]
except:
normalized_name = "noNameFound"
result = value, frame['eventTime'].values[0], frame['sourceIPAddress'].values[0], normalized_name
#print(file_name)
return result
async def get_file_analyse_local_events(zipped, event, outgoing_message):
#print("+++ Found new log: ", f)
with gzip.open(zipped, "rb") as f:
d = json.loads(f.read().decode("ascii"))
records = d["Records"]
df_data = json_normalize(records)
if CloudtrailAnalysis.check_value(zipped, df_data, event) == None:
pass
else:
outgoing_message.append(CloudtrailAnalysis.check_value(zipped, df_data, event))
return CloudtrailAnalysis.check_value(zipped, df_data, event)
async def main(unzipped, event, outgoing_message):
await get_file_analyse_local_events(unzipped, event, outgoing_message)
"""
($.eventName=CreateTrail)
($.eventName=UpdateTrail)
($.eventName=DeleteTrail)
($.eventName=DeleteGroupPolicy)
($.eventName=DeleteRolePolicy)
($.eventName=DeleteUserPolicy)
($.eventName=PutGroupPolicy)
($.eventName=PutRolePolicy)
($.eventName=PutUserPolicy)
($.eventName=CreatePolicy)
($.eventName=DeletePolicy)
($.eventName=CreatePolicyVersion)
($.eventName=DeletePolicyVersion)
($.eventName=AttachRolePolicy)
($.eventName=DetachRolePolicy)
($.eventName=AttachUserPolicy)
($.eventName=DetachUserPolicy)
($.eventName=AttachGroupPolicy)
($.eventName=DetachGroupPolicy)
"""
#security_events = ['ConsoleLogin','CreateKeyPair', 'CheckMfa','PutUserPolicy','DeleteTrail']
# list group of Cloudtrail logs you want processed
hdd_files = glob.glob("/Users/bigsnarfdude/cloudtrail_logs/*.json.gz")
security_events = ['ConsoleLogin']
outgoing_message = []
loop = asyncio.get_event_loop()
for zipped in hdd_files:
for event in security_events:
loop.run_until_complete(main(zipped, event, outgoing_message))
loop.close()
deduped = [ str(x) for x in list(set(outgoing_message))]
sort_deduped = deduped.sort()
post = "\n".join(deduped)
# put in the details of your slack webhook
slack = Slack(url="https://hooks.slack.com/services/asdfasdf/qwerqwer/asdfqwerasdfqwer")
slack.notify(text=post, channel="#testing", username="security-bot", icon_emoji=":robot_face:")

view raw

gistfile1.txt

hosted with ❤ by GitHub

Cloudtrail Log Analyzer Python3 Aysnc Await


#! /usr/local/env python
# coding: utf-8
import gzip
import json
from pprint import pprint
import pandas as pd
from pandas.io.json import json_normalize
import sys
import socket
import boto
import os
import ipaddress
import asyncio
import glob
hdd_files = glob.glob("/Users/bigsnarfdude/cloudtrail_logs/*.json.gz")
security_events = ['CreateKeyPair', 'CheckMfa']
class CloudtrailAnalysis():
@staticmethod
def check_value(df_data, value):
if df_data[df_data['eventName'] == value].empty:
pass
else:
frame = df_data[df_data['eventName'] == value]
return value, frame['eventTime'].values[0], frame['userIdentity.userName'].values[0], frame['awsRegion'].values[0]
async def get_file_analyse_local_events(f, event):
#print("+++ Found new log: ", f)
with gzip.open(f, "rb") as f:
d = json.loads(f.read().decode("ascii"))
records = d["Records"]
df_data = json_normalize(records)
if CloudtrailAnalysis.check_value(df_data, event) == None:
pass
else:
print(CloudtrailAnalysis.check_value(df_data, event))
async def main(f, event):
await get_file_analyse_local_events(f, event)
# process async
loop = asyncio.get_event_loop()
for f in hdd_files:
for event in security_events:
loop.run_until_complete(main(f, event))
loop.close()

view raw

gistfile1.txt

hosted with ❤ by GitHub