2016-03-21 21:24:15 +01:00
|
|
|
#!/usr/bin/env python
|
2014-11-16 17:02:23 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
"""
|
|
|
|
Python script to extract network activity from MISP database
|
|
|
|
|
|
|
|
Koen Van Impe 20141116
|
2015-08-04 23:25:15 +02:00
|
|
|
netflow 20150804
|
2014-11-16 17:02:23 +01:00
|
|
|
Feed it a list of event_id's (1 id per line) with the option "-f".
|
|
|
|
Use --no-comment to get a flat list of entries without event id and title information
|
|
|
|
|
2015-08-04 23:25:15 +02:00
|
|
|
Usage
|
|
|
|
./get_network_activity.py --netflow --event 8
|
|
|
|
get netflow filter for event 8
|
|
|
|
|
2015-11-06 10:17:20 +01:00
|
|
|
./get_network_activity.py -f get_network_activity.event_id --netflow
|
2015-08-04 23:25:15 +02:00
|
|
|
get netflow filter for events in id file
|
|
|
|
|
|
|
|
./get_network_activity.py -f get_network_activity.event_id
|
2015-11-06 10:17:20 +01:00
|
|
|
get output with comments
|
2015-02-24 14:31:01 +01:00
|
|
|
"""
|
|
|
|
|
2014-11-16 17:02:23 +01:00
|
|
|
from pymisp import PyMISP
|
|
|
|
|
2015-11-06 10:17:20 +01:00
|
|
|
from keys import misp_key
|
|
|
|
from keys import misp_url
|
|
|
|
from keys import misp_verifycert
|
2014-11-16 17:02:23 +01:00
|
|
|
|
2015-02-24 14:31:01 +01:00
|
|
|
source = None
|
2014-11-16 17:02:23 +01:00
|
|
|
|
|
|
|
|
|
|
|
def init():
|
2015-02-24 14:31:01 +01:00
|
|
|
"""
|
|
|
|
Initialize PyMISP
|
|
|
|
Get configuration settings from config file
|
|
|
|
"""
|
|
|
|
global source
|
2014-11-16 17:02:23 +01:00
|
|
|
source = PyMISP(misp_url, misp_key, misp_verifycert, 'json')
|
|
|
|
|
|
|
|
|
|
|
|
def get_event(event_id):
|
2015-02-24 14:31:01 +01:00
|
|
|
"""
|
|
|
|
Get details of an event and add it to the result arrays
|
|
|
|
:event_id the id of the event
|
|
|
|
"""
|
2014-11-16 17:02:23 +01:00
|
|
|
global network_ip_src, network_ip_dst, network_hostname, network_domain
|
2015-08-04 23:25:15 +02:00
|
|
|
global app_hostname, app_domain, app_ip_src, app_ip_dst, app_ids_only, app_printcomment, app_netflow
|
2014-11-16 17:02:23 +01:00
|
|
|
|
|
|
|
event_id = int(event_id)
|
|
|
|
if event_id > 0:
|
|
|
|
event = source.get_event(event_id)
|
|
|
|
if event.status_code == 200:
|
|
|
|
|
|
|
|
try:
|
|
|
|
event_json = event.json()
|
|
|
|
except:
|
|
|
|
return False
|
|
|
|
|
|
|
|
event_core = event_json["Event"]
|
2015-02-24 14:31:01 +01:00
|
|
|
# event_threatlevel_id = event_core["threat_level_id"]
|
2014-11-16 17:02:23 +01:00
|
|
|
|
2015-02-24 14:31:01 +01:00
|
|
|
# attribute_count = event_core["attribute_count"]
|
2014-11-16 17:02:23 +01:00
|
|
|
attribute = event_core["Attribute"]
|
|
|
|
|
|
|
|
for attribute in event_core["Attribute"]:
|
2015-02-24 14:31:01 +01:00
|
|
|
if app_ids_only and not attribute["to_ids"]:
|
2014-11-16 17:02:23 +01:00
|
|
|
continue
|
2015-02-24 14:31:01 +01:00
|
|
|
|
2014-11-16 17:02:23 +01:00
|
|
|
value = attribute["value"]
|
|
|
|
title = event_core["info"]
|
2015-08-04 23:25:15 +02:00
|
|
|
if app_netflow:
|
|
|
|
app_printcomment = False
|
|
|
|
if attribute["type"] == "ip-dst" and app_ip_dst:
|
2015-11-06 10:17:20 +01:00
|
|
|
network_ip_dst.append([build_entry(value, event_id, title, "ip-dst")])
|
2014-11-16 17:02:23 +01:00
|
|
|
else:
|
2015-08-04 23:25:15 +02:00
|
|
|
if attribute["type"] == "ip-src" and app_ip_src:
|
|
|
|
network_ip_src.append([build_entry(value, event_id, title, "ip-src")])
|
|
|
|
elif attribute["type"] == "ip-dst" and app_ip_dst:
|
|
|
|
network_ip_dst.append([build_entry(value, event_id, title, "ip-dst")])
|
|
|
|
elif attribute["type"] == "domain" and app_domain:
|
|
|
|
network_domain.append([build_entry(value, event_id, title, "domain")])
|
|
|
|
elif attribute["type"] == "hostname" and app_hostname:
|
|
|
|
network_hostname.append([build_entry(value, event_id, title, "hostname")])
|
|
|
|
else:
|
|
|
|
continue
|
2014-11-16 17:02:23 +01:00
|
|
|
else:
|
2015-05-03 02:47:47 +02:00
|
|
|
print("Not a valid ID")
|
2015-02-24 14:31:01 +01:00
|
|
|
return
|
2014-11-16 17:02:23 +01:00
|
|
|
|
|
|
|
|
2015-02-24 14:31:01 +01:00
|
|
|
def build_entry(value, event_id, title, source):
|
|
|
|
"""
|
2014-11-16 17:02:23 +01:00
|
|
|
Build the line containing the entry
|
|
|
|
|
|
|
|
:value the datavalue of the entry
|
2015-02-24 14:31:01 +01:00
|
|
|
:event_id id of the event
|
|
|
|
:title name of the event
|
2014-11-16 17:02:23 +01:00
|
|
|
:source from which set was the entry retrieved
|
2015-02-24 14:31:01 +01:00
|
|
|
"""
|
2014-11-16 17:02:23 +01:00
|
|
|
global app_printcomment
|
|
|
|
|
2015-02-24 14:31:01 +01:00
|
|
|
if app_printcomment:
|
|
|
|
if app_printtitle:
|
|
|
|
return "%s # Event: %s / %s (from %s) " % (value, event_id, title, source)
|
2014-11-16 17:02:23 +01:00
|
|
|
else:
|
2015-02-24 14:31:01 +01:00
|
|
|
return "%s # Event: %s (from %s) " % (value, event_id, source)
|
2014-11-16 17:02:23 +01:00
|
|
|
else:
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
|
def print_events():
|
2015-02-24 14:31:01 +01:00
|
|
|
"""
|
|
|
|
Print the events from the result arrays
|
|
|
|
"""
|
2014-11-16 17:02:23 +01:00
|
|
|
global network_ip_src, network_ip_dst, network_domain, network_hostname
|
2015-08-04 23:25:15 +02:00
|
|
|
global app_hostname, app_domain, app_ip_src, app_ip_dst, app_ids_only, app_printcomment, app_printtitle, app_netflow
|
2014-11-16 17:02:23 +01:00
|
|
|
|
2015-08-04 23:25:15 +02:00
|
|
|
if app_netflow:
|
|
|
|
firsthost = True
|
2014-11-16 17:02:23 +01:00
|
|
|
for ip in network_ip_dst:
|
2015-08-04 23:25:15 +02:00
|
|
|
if firsthost:
|
|
|
|
firsthost = False
|
|
|
|
else:
|
2015-11-06 10:17:20 +01:00
|
|
|
print " or "
|
2015-08-04 23:25:15 +02:00
|
|
|
print "host %s" % ip[0]
|
|
|
|
else:
|
|
|
|
if app_ip_src:
|
|
|
|
for ip in network_ip_src:
|
|
|
|
print(ip[0])
|
|
|
|
if app_ip_dst:
|
|
|
|
for ip in network_ip_dst:
|
|
|
|
print(ip[0])
|
|
|
|
if app_domain:
|
|
|
|
for ip in network_domain:
|
|
|
|
print(ip[0])
|
|
|
|
if app_hostname:
|
|
|
|
for ip in network_hostname:
|
|
|
|
print(ip[0])
|
2014-11-16 17:02:23 +01:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
import argparse
|
|
|
|
|
|
|
|
network_ip_src = []
|
|
|
|
network_ip_dst = []
|
|
|
|
network_domain = []
|
|
|
|
network_hostname = []
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(
|
2015-02-24 14:31:01 +01:00
|
|
|
description='Download network activity information from MISP.')
|
2014-11-16 17:02:23 +01:00
|
|
|
parser.add_argument('-f', '--filename', type=str,
|
|
|
|
help='File containing a list of event id.')
|
|
|
|
parser.add_argument('--hostname', action='store_true', default=False,
|
|
|
|
help='Include hostnames.')
|
|
|
|
parser.add_argument('--no-ip-src', action='store_true', default=False,
|
|
|
|
help='Do not include ip-src.')
|
|
|
|
parser.add_argument('--no-ip-dst', action='store_true', default=False,
|
|
|
|
help='Do not include ip-dst.')
|
|
|
|
parser.add_argument('--domain', action='store_true', default=False,
|
|
|
|
help='Include domains.')
|
|
|
|
parser.add_argument('--no-comment', action='store_false', default=True,
|
|
|
|
help='Do not include comment in the output.')
|
|
|
|
parser.add_argument('--no-ids-only', action='store_true', default=False,
|
|
|
|
help='Include IDS and non-IDS attribures.')
|
|
|
|
parser.add_argument('--no-titles', action='store_true', default=False,
|
2015-02-24 14:31:01 +01:00
|
|
|
help='Do not include titles')
|
2015-08-04 23:25:15 +02:00
|
|
|
parser.add_argument('--netflow', action='store_true', default=False,
|
|
|
|
help='Netflow (nfdump) output')
|
|
|
|
parser.add_argument('--event', type=int, default=0,
|
|
|
|
help='EventID to parse (not using filename)')
|
2014-11-16 17:02:23 +01:00
|
|
|
args = parser.parse_args()
|
2015-02-24 14:31:01 +01:00
|
|
|
|
2015-08-04 23:25:15 +02:00
|
|
|
init()
|
|
|
|
app_printcomment = args.no_comment
|
|
|
|
app_hostname = args.hostname
|
|
|
|
app_domain = args.domain
|
|
|
|
app_ip_src = not(args.no_ip_src)
|
|
|
|
app_ip_dst = not(args.no_ip_dst)
|
|
|
|
app_ids_only = args.no_ids_only
|
|
|
|
app_printtitle = not(args.no_titles)
|
|
|
|
app_netflow = args.netflow
|
|
|
|
app_event = args.event
|
|
|
|
|
|
|
|
if app_event > 0:
|
2015-11-06 10:17:20 +01:00
|
|
|
get_event(app_event)
|
2015-08-04 23:25:15 +02:00
|
|
|
print_events()
|
|
|
|
elif args.filename is not None:
|
2014-11-16 17:02:23 +01:00
|
|
|
# print "app_printcomment %s app_hostname %s app_domain %s app_ip_src %s app_ip_dst %s app_ids_only %s app_printtitle %s" % (app_printcomment,app_hostname, app_domain, app_ip_src, app_ip_dst, app_ids_only, app_printtitle)
|
|
|
|
with open(args.filename, 'r') as line:
|
|
|
|
for event_id in line:
|
2015-02-24 14:31:01 +01:00
|
|
|
get_event(event_id.strip())
|
2014-11-16 17:02:23 +01:00
|
|
|
print_events()
|
|
|
|
else:
|
2015-05-03 02:47:47 +02:00
|
|
|
print("No filename given, stopping.")
|