mirror of https://github.com/CIRCL/AIL-framework
chg: [MISP] refactor MISP thehive auto push
parent
5d84b347bc
commit
5ef29d8abb
|
@ -292,14 +292,17 @@ def trackers_migration():
|
|||
print('RETRO HUNT MIGRATION...')
|
||||
|
||||
for task_uuid in old_Tracker.get_all_retro_hunt_tasks():
|
||||
meta = old_Tracker.get_retro_hunt_task_metadata(task_uuid, date=True, progress=True, creator=True, sources=True, tags=True, description=True, nb_match=True)
|
||||
retro_hunt = Tracker.RetroHunt(retro_hunt)
|
||||
# TODO Create filters
|
||||
# TODO GET OLD META
|
||||
meta = retro_hunt.get_meta(options={'creator', 'date', 'description', 'filter', 'progress', 'tags'})
|
||||
last_id = old_Tracker.get_retro_hunt_last_analyzed(task_uuid)
|
||||
timeout = old_Tracker.get_retro_hunt_task_timeout(task_uuid)
|
||||
Tracker._re_create_retro_hunt_task(meta['name'], meta['rule'], meta['date'], meta['date_from'], meta['date_to'], meta['creator'], meta['sources'], meta['tags'], [], timeout, meta['description'], task_uuid, state=meta['state'], nb_match=meta['nb_match'], last_id=last_id)
|
||||
|
||||
# # TODO: IN background ?
|
||||
for id in old_Tracker.get_retro_hunt_items_by_daterange(task_uuid, meta['date_from'], meta['date_to']):
|
||||
Tracker.save_retro_hunt_match(task_uuid, id)
|
||||
for obj_id in old_Tracker.get_retro_hunt_items_by_daterange(task_uuid, meta['date_from'], meta['date_to']):
|
||||
retro_hunt.add('item', '', obj_id)
|
||||
|
||||
Tracker._fix_db_custom_tags()
|
||||
|
||||
|
|
|
@ -268,6 +268,9 @@ function launching_scripts {
|
|||
screen -S "Script_AIL" -X screen -t "Zerobins" bash -c "cd ${AIL_BIN}/modules; ${ENV_PY} ./Zerobins.py; read x"
|
||||
sleep 0.1
|
||||
|
||||
screen -S "Script_AIL" -X screen -t "MISP_Thehive_Auto_Push" bash -c "cd ${AIL_BIN}/modules; ${ENV_PY} ./MISP_Thehive_Auto_Push.py; read x"
|
||||
sleep 0.1
|
||||
|
||||
##################################
|
||||
# TRACKERS MODULES #
|
||||
##################################
|
||||
|
@ -299,9 +302,7 @@ function launching_scripts {
|
|||
##################################
|
||||
# TO MIGRATE #
|
||||
##################################
|
||||
screen -S "Script_AIL" -X screen -t "ModuleInformation" bash -c "cd ${AIL_BIN}; ${ENV_PY} ./ModulesInformationV2.py -k 0 -c 1; read x"
|
||||
sleep 0.1
|
||||
# screen -S "Script_AIL" -X screen -t "MISPtheHIVEfeeder" bash -c "cd ${AIL_BIN}; ${ENV_PY} ./MISP_The_Hive_feeder.py; read x"
|
||||
# screen -S "Script_AIL" -X screen -t "ModuleInformation" bash -c "cd ${AIL_BIN}; ${ENV_PY} ./ModulesInformationV2.py -k 0 -c 1; read x"
|
||||
# sleep 0.1
|
||||
|
||||
|
||||
|
|
|
@ -1,248 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*-coding:UTF-8 -*
|
||||
|
||||
"""
|
||||
module
|
||||
====================
|
||||
|
||||
This module send tagged pastes to MISP or THE HIVE Project
|
||||
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
import redis
|
||||
import time
|
||||
import json
|
||||
import binascii
|
||||
import gzip
|
||||
|
||||
from pubsublogger import publisher
|
||||
from Helper import Process
|
||||
import ailleakObject
|
||||
|
||||
sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages'))
|
||||
import Tag
|
||||
|
||||
sys.path.append(os.path.join(os.environ['AIL_BIN'], 'lib'))
|
||||
import ConfigLoader
|
||||
import item_basic
|
||||
|
||||
from pymisp import PyMISP
|
||||
|
||||
sys.path.append('../configs/keys')
|
||||
|
||||
# import MISP KEYS
|
||||
try:
|
||||
from mispKEYS import misp_url, misp_key, misp_verifycert
|
||||
flag_misp = True
|
||||
except:
|
||||
print('Misp keys not present')
|
||||
flag_misp = False
|
||||
|
||||
# import The Hive Keys
|
||||
try:
|
||||
from theHiveKEYS import the_hive_url, the_hive_key, the_hive_verifycert
|
||||
if the_hive_url == '':
|
||||
flag_the_hive = False
|
||||
else:
|
||||
flag_the_hive = True
|
||||
except:
|
||||
print('The HIVE keys not present')
|
||||
flag_the_hive = False
|
||||
HiveApi = False
|
||||
|
||||
from thehive4py.api import TheHiveApi
|
||||
import thehive4py.exceptions
|
||||
from thehive4py.models import Alert, AlertArtifact
|
||||
from thehive4py.models import Case, CaseTask, CustomFieldHelper
|
||||
|
||||
def is_gzip_file(magic_nuber):
|
||||
return binascii.hexlify(magic_nuber) == b'1f8b'
|
||||
|
||||
def create_the_hive_alert(source, item_id, tag):
|
||||
# # TODO: check items status (processed by all modules)
|
||||
# # TODO: add item metadata: decoded content, link to auto crawled content, pgp correlation, cryptocurrency correlation...
|
||||
# # # TODO: description, add AIL link:show items ?
|
||||
tags = list( r_serv_metadata.smembers('tag:{}'.format(item_id)) )
|
||||
|
||||
path = item_basic.get_item_filepath(item_id)
|
||||
paste_handle = open(path, 'rb')
|
||||
paste_data = paste_handle.read()
|
||||
tmp_path = None
|
||||
|
||||
if is_gzip_file(paste_data[0:2]): # if gzip, create a new file to supply to TheHive
|
||||
paste_handle.close() # TheHive expects a file handle, that's why we create a new file
|
||||
tmp_data = gzip.decompress(paste_data)
|
||||
tmp_path = path + '.unzip'
|
||||
with open(tmp_path, 'wb+') as f:
|
||||
f.write(tmp_data)
|
||||
paste_handle = open(tmp_path, 'rb')
|
||||
if path.endswith(".gz"): # remove .gz from submitted path to TheHive beause we've decompressed it
|
||||
path = path[:-3]
|
||||
|
||||
path = os.path.basename(os.path.normpath(path)) + ".txt" # get last part of path, add .txt so it's easier to open when downloaded from TheHive
|
||||
|
||||
artifacts = [
|
||||
AlertArtifact( dataType='uuid-ail', data=r_serv_db.get('ail:uuid') ),
|
||||
AlertArtifact( dataType='file', data=(paste_handle, path), tags=tags )
|
||||
]
|
||||
|
||||
# Prepare the sample Alert
|
||||
sourceRef = str(uuid.uuid4())[0:6]
|
||||
alert = Alert(title='AIL Leak',
|
||||
tlp=3,
|
||||
tags=tags,
|
||||
description='AIL Leak, triggered by {}'.format(tag),
|
||||
type='ail',
|
||||
source=source,
|
||||
sourceRef=sourceRef,
|
||||
artifacts=artifacts)
|
||||
|
||||
# Create the Alert
|
||||
id = None
|
||||
try:
|
||||
response = HiveApi.create_alert(alert)
|
||||
if response.status_code == 201:
|
||||
#print(json.dumps(response.json(), indent=4, sort_keys=True))
|
||||
print('Alert Created')
|
||||
print('')
|
||||
id = response.json()['id']
|
||||
else:
|
||||
print('ko: {}/{}'.format(response.status_code, response.text))
|
||||
return 0
|
||||
except:
|
||||
print('hive connection error')
|
||||
|
||||
paste_handle.close()
|
||||
if tmp_path is not None: # this file has been send to TheHive, we won't ever need it again
|
||||
os.remove(tmp_path)
|
||||
|
||||
def feeder(message, count=0):
|
||||
|
||||
if flag_the_hive or flag_misp:
|
||||
tag, item_id = message.split(';')
|
||||
|
||||
## FIXME: remove it
|
||||
if not item_basic.exist_item(item_id):
|
||||
if count < 10:
|
||||
r_serv_db.zincrby('mess_not_saved_export', 1, message)
|
||||
return 0
|
||||
else:
|
||||
r_serv_db.zrem('mess_not_saved_export', message)
|
||||
print('Error: {} do not exist, tag= {}'.format(item_id, tag))
|
||||
return 0
|
||||
|
||||
source = item_basic.get_source(item_id)
|
||||
|
||||
if HiveApi != False:
|
||||
if int(r_serv_db.get('hive:auto-alerts')) == 1:
|
||||
if r_serv_db.sismember('whitelist_hive', tag):
|
||||
create_the_hive_alert(source, item_id, tag)
|
||||
else:
|
||||
print('hive, auto alerts creation disable')
|
||||
if flag_misp:
|
||||
if int(r_serv_db.get('misp:auto-events')) == 1:
|
||||
if r_serv_db.sismember('whitelist_misp', tag):
|
||||
misp_wrapper.pushToMISP(uuid_ail, item_id, tag)
|
||||
else:
|
||||
print('misp, auto events creation disable')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
publisher.port = 6380
|
||||
publisher.channel = "Script"
|
||||
|
||||
config_section = 'MISP_The_hive_feeder'
|
||||
|
||||
config_loader = ConfigLoader.ConfigLoader()
|
||||
|
||||
r_serv_db = config_loader.get_redis_conn("ARDB_DB")
|
||||
r_serv_metadata = config_loader.get_redis_conn("ARDB_Metadata")
|
||||
|
||||
# set sensor uuid
|
||||
uuid_ail = r_serv_db.get('ail:uuid')
|
||||
if uuid_ail is None:
|
||||
uuid_ail = r_serv_db.set('ail:uuid', uuid.uuid4() )
|
||||
|
||||
# set default
|
||||
if r_serv_db.get('hive:auto-alerts') is None:
|
||||
r_serv_db.set('hive:auto-alerts', 0)
|
||||
|
||||
if r_serv_db.get('misp:auto-events') is None:
|
||||
r_serv_db.set('misp:auto-events', 0)
|
||||
|
||||
p = Process(config_section)
|
||||
# create MISP connection
|
||||
if flag_misp:
|
||||
try:
|
||||
pymisp = PyMISP(misp_url, misp_key, misp_verifycert)
|
||||
except:
|
||||
flag_misp = False
|
||||
r_serv_db.set('ail:misp', False)
|
||||
print('Not connected to MISP')
|
||||
|
||||
if flag_misp:
|
||||
#try:
|
||||
misp_wrapper = ailleakObject.ObjectWrapper(pymisp)
|
||||
r_serv_db.set('ail:misp', True)
|
||||
print('Connected to MISP:', misp_url)
|
||||
#except Exception as e:
|
||||
# flag_misp = False
|
||||
# r_serv_db.set('ail:misp', False)
|
||||
# print(e)
|
||||
# print('Not connected to MISP')
|
||||
|
||||
# create The HIVE connection
|
||||
if flag_the_hive:
|
||||
try:
|
||||
HiveApi = TheHiveApi(the_hive_url, the_hive_key, cert = the_hive_verifycert)
|
||||
except:
|
||||
HiveApi = False
|
||||
flag_the_hive = False
|
||||
r_serv_db.set('ail:thehive', False)
|
||||
print('Not connected to The HIVE')
|
||||
else:
|
||||
HiveApi = False
|
||||
|
||||
if HiveApi != False and flag_the_hive:
|
||||
try:
|
||||
HiveApi.get_alert(0)
|
||||
r_serv_db.set('ail:thehive', True)
|
||||
print('Connected to The HIVE:', the_hive_url)
|
||||
except thehive4py.exceptions.AlertException:
|
||||
HiveApi = False
|
||||
flag_the_hive = False
|
||||
r_serv_db.set('ail:thehive', False)
|
||||
print('Not connected to The HIVE')
|
||||
|
||||
refresh_time = 3
|
||||
## FIXME: remove it
|
||||
PASTES_FOLDER = os.path.join(os.environ['AIL_HOME'], config_loader.get_config_str("Directories", "pastes"))
|
||||
config_loader = None
|
||||
|
||||
time_1 = time.time()
|
||||
|
||||
while True:
|
||||
|
||||
# Get one message from the input queue
|
||||
message = p.get_from_set()
|
||||
if message is None:
|
||||
|
||||
# handle not saved pastes
|
||||
if int(time.time() - time_1) > refresh_time:
|
||||
|
||||
num_queu = r_serv_db.zcard('mess_not_saved_export')
|
||||
list_queu = r_serv_db.zrange('mess_not_saved_export', 0, -1, withscores=True)
|
||||
|
||||
if num_queu and list_queu:
|
||||
for i in range(0, num_queu):
|
||||
feeder(list_queu[i][0],list_queu[i][1])
|
||||
|
||||
time_1 = time.time()
|
||||
else:
|
||||
publisher.debug("{} queue is empty, waiting 1s".format(config_section))
|
||||
time.sleep(1)
|
||||
else:
|
||||
feeder(message)
|
|
@ -1,127 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*-coding:UTF-8 -*
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pymisp import MISPEvent, MISPObject
|
||||
from pymisp.tools.abstractgenerator import AbstractMISPObjectGenerator
|
||||
|
||||
import datetime
|
||||
|
||||
from lib.objects.Items import Item
|
||||
from lib import ConfigLoader
|
||||
|
||||
class ObjectWrapper:
|
||||
def __init__(self, pymisp):
|
||||
self.pymisp = pymisp
|
||||
self.currentID_date = None
|
||||
self.eventID_to_push = self.get_daily_event_id()
|
||||
config_loader = ConfigLoader.ConfigLoader()
|
||||
self.maxDuplicateToPushToMISP = config_loader.get_config_int("ailleakObject", "maxDuplicateToPushToMISP")
|
||||
config_loader = None
|
||||
self.attribute_to_tag = None
|
||||
|
||||
def add_new_object(self, uuid_ail, item_id):
|
||||
self.uuid_ail = uuid_ail
|
||||
|
||||
item = Item(item_id)
|
||||
return item.get_misp_object()
|
||||
|
||||
def date_to_str(self, date):
|
||||
return "{0}-{1}-{2}".format(date.year, date.month, date.day)
|
||||
|
||||
def get_all_related_events(self, to_search):
|
||||
result = self.pymisp.search(controller='events', eventinfo=to_search, metadata=False)
|
||||
events = []
|
||||
if result:
|
||||
for e in result:
|
||||
events.append({'id': e['Event']['id'], 'org_id': e['Event']['org_id'], 'info': e['Event']['info']})
|
||||
return events
|
||||
|
||||
def get_daily_event_id(self):
|
||||
to_match = "Daily AIL-leaks {}".format(datetime.date.today())
|
||||
events = self.get_all_related_events(to_match)
|
||||
for dic in events:
|
||||
info = dic['info']
|
||||
e_id = dic['id']
|
||||
if info == to_match:
|
||||
print('Found: ', info, '->', e_id)
|
||||
self.currentID_date = datetime.date.today()
|
||||
return e_id
|
||||
created_event = self.create_daily_event()
|
||||
new_id = created_event['Event']['id']
|
||||
print('New event created:', new_id)
|
||||
self.currentID_date = datetime.date.today()
|
||||
return new_id
|
||||
|
||||
|
||||
def create_daily_event(self):
|
||||
today = datetime.date.today()
|
||||
# [0-3]
|
||||
distribution = 0
|
||||
info = "Daily AIL-leaks {}".format(today)
|
||||
# [0-2]
|
||||
analysis = 0
|
||||
# [1-4]
|
||||
threat = 3
|
||||
published = False
|
||||
org_id = None
|
||||
orgc_id = None
|
||||
sharing_group_id = None
|
||||
date = None
|
||||
|
||||
event = MISPEvent()
|
||||
event.distribution = distribution
|
||||
event.info = info
|
||||
event.analysis = analysis
|
||||
event.threat = threat
|
||||
event.published = published
|
||||
|
||||
event.add_tag('infoleak:output-format="ail-daily"')
|
||||
existing_event = self.pymisp.add_event(event)
|
||||
return existing_event
|
||||
|
||||
# Publish object to MISP
|
||||
def pushToMISP(self, uuid_ail, item_id, tag):
|
||||
|
||||
if self.currentID_date != datetime.date.today(): #refresh id
|
||||
self.eventID_to_push = self.get_daily_event_id()
|
||||
|
||||
mispTYPE = 'ail-leak'
|
||||
|
||||
# paste object already exist
|
||||
if self.paste_object_exist(self.eventID_to_push, item_id):
|
||||
# add new tag
|
||||
self.tag(self.attribute_to_tag, tag)
|
||||
print(item_id + ' tagged: ' + tag)
|
||||
# create object
|
||||
else:
|
||||
misp_obj = self.add_new_object(uuid_ail, item_id)
|
||||
|
||||
# deprecated
|
||||
# try:
|
||||
# templateID = [x['ObjectTemplate']['id'] for x in self.pymisp.get_object_templates_list() if x['ObjectTemplate']['name'] == mispTYPE][0]
|
||||
# except IndexError:
|
||||
# valid_types = ", ".join([x['ObjectTemplate']['name'] for x in self.pymisp.get_object_templates_list()])
|
||||
# print ("Template for type %s not found! Valid types are: %s" % (mispTYPE, valid_types))
|
||||
|
||||
|
||||
r = self.pymisp.add_object(self.eventID_to_push, misp_obj, pythonify=True)
|
||||
if 'errors' in r:
|
||||
print(r)
|
||||
else:
|
||||
print('Pushed:', tag, '->', item_id)
|
||||
|
||||
def paste_object_exist(self, eventId, item_id):
|
||||
res = self.pymisp.search(controller='attributes', eventid=eventId, value=item_id)
|
||||
# object already exist
|
||||
if res.get('Attribute', []):
|
||||
self.attribute_to_tag = res['Attribute'][0]['uuid']
|
||||
return True
|
||||
# new object
|
||||
else:
|
||||
return False
|
||||
|
||||
def tag(self, uuid, tag):
|
||||
self.pymisp.tag(uuid, tag)
|
|
@ -8,6 +8,7 @@ Import Content
|
|||
|
||||
"""
|
||||
import os
|
||||
import datetime
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
|
@ -154,6 +155,36 @@ class MISPExporter(AbstractExporter, ABC):
|
|||
except (TypeError, ValueError):
|
||||
return 0
|
||||
|
||||
def get_event_object_id(self, event_id, obj):
|
||||
misp = self.get_misp()
|
||||
resp = misp.search(controller='attributes', eventid=event_id, value=obj.get_id())
|
||||
attribute = resp.get('Attribute', [])
|
||||
if attribute:
|
||||
return attribute[0]['object_id']
|
||||
|
||||
def add_event_object_tag(self, obj_id, tag):
|
||||
misp = self.get_misp()
|
||||
misp_obj = misp.get_object(obj_id, pythonify=True)
|
||||
for attribute in misp_obj.attributes:
|
||||
attribute.add_tag(tag)
|
||||
misp.update_attribute(attribute)
|
||||
|
||||
def add_event_object(self, event_id, obj):
|
||||
misp_object = obj.get_misp_object()
|
||||
misp = self.get_misp()
|
||||
misp.add_object(event_id, misp_object)
|
||||
|
||||
def get_daily_event_id(self):
|
||||
misp = self.get_misp()
|
||||
event_info = f'Daily AIL-leaks {datetime.date.today()}'
|
||||
resp = misp.search(controller='events', eventinfo=event_info, metadata=True)
|
||||
if resp:
|
||||
return resp[0]['Event']['id']
|
||||
else:
|
||||
misp_event = self.create_event([], info=event_info, threat_level=3, export=True)
|
||||
return misp_event['Event']['id']
|
||||
|
||||
|
||||
# TODO EVENT REPORT ???????
|
||||
def create_event(self, objs, export=False, event_uuid=None, date=None, publish=False, info=None, tags=None,
|
||||
analysis=0, distribution=0, threat_level=4):
|
||||
|
@ -277,18 +308,57 @@ class MISPExporterTrackerMatch(MISPExporter):
|
|||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exporter = MISPExporterAILObjects()
|
||||
class MISPExporterAutoDaily(MISPExporter):
|
||||
"""MISPExporter AILObjects
|
||||
|
||||
:param url: URL of the MISP instance you want to connect to :param key: API key of the user you want to use
|
||||
:param ssl: can be True or False (to check or to not check the validity of the certificate. Or a CA_BUNDLE in
|
||||
case of self signed or other certificate (the concatenation of all the crt of the chain)
|
||||
"""
|
||||
|
||||
def __init__(self, url='', key='', ssl=False):
|
||||
super().__init__(url=url, key=key, ssl=ssl)
|
||||
|
||||
# create event if don't exists
|
||||
try:
|
||||
self.event_id = self.get_daily_event_id()
|
||||
except MISPConnectionError:
|
||||
self.event_id = - 1
|
||||
self.date = datetime.date.today()
|
||||
|
||||
def export(self, obj, tag):
|
||||
"""Export a list of AILObjects as a MISP event
|
||||
|
||||
:param obj: AIL Object to export
|
||||
:type obj: AbstractObject
|
||||
"""
|
||||
try:
|
||||
if self.date != datetime.date.today() or int(self.event_id) < 0:
|
||||
self.date = datetime.date.today()
|
||||
self.event_id = self.get_daily_event_id()
|
||||
|
||||
obj_id = self.get_event_object_id(self.event_id, obj)
|
||||
# Object already in event
|
||||
if obj_id:
|
||||
self.add_event_object_tag(obj_id, tag)
|
||||
else:
|
||||
self.add_event_object(self.event_id, obj)
|
||||
|
||||
except MISPConnectionError:
|
||||
return -1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# exporter = MISPExporterAILObjects()
|
||||
# from lib.objects.Cves import Cve
|
||||
# from lib.objects.Items import Item
|
||||
from lib.objects.Items import Item
|
||||
# objs_t = [Item('crawled/2020/09/14/circl.lu0f4976a4-dda4-4189-ba11-6618c4a8c951'),
|
||||
# Cve('CVE-2020-16856'), Cve('CVE-2014-6585'), Cve('CVE-2015-0383'),
|
||||
# Cve('CVE-2015-0410')]
|
||||
# r = exporter.export(objs_t, export=False)
|
||||
# print(r)
|
||||
|
||||
r = exporter.get_misp_uuid()
|
||||
# r = exporter.get_misp_uuid()
|
||||
# r = misp.server_settings()
|
||||
# for item in r['finalSettings']:
|
||||
# print()
|
||||
|
@ -297,4 +367,8 @@ if __name__ == '__main__':
|
|||
# # print()
|
||||
# print()
|
||||
|
||||
print(r)
|
||||
obj = Item('submitted/2023/05/15/submitted_aed90c6f-c620-4437-93d7-5ff17d1a8eef.gz')
|
||||
obj = Item('submitted/2023/05/15/submitted_8a6136c2-c7f2-4c9e-8f29-e1a62315b482.gz')
|
||||
tag = 'infoleak:automatic-detection="credit-card"'
|
||||
exporter = MISPExporterAutoDaily()
|
||||
exporter.export(obj, tag)
|
||||
|
|
|
@ -143,14 +143,16 @@ class TheHiveExporter(AbstractExporter, ABC):
|
|||
if req.status_code == 201:
|
||||
# print(json.dumps(req.json(), indent=4, sort_keys=True))
|
||||
print('Alert Created')
|
||||
print(req.json())
|
||||
# print(req.json())
|
||||
alert_id = req.json()['id']
|
||||
else:
|
||||
# TODO LOGS
|
||||
print(f'ko: {req.status_code}/{req.text}')
|
||||
return 0
|
||||
except:
|
||||
return -2
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print('hive connection error')
|
||||
return -1
|
||||
return alert_id
|
||||
|
||||
def create_case(self, observables, description=None, tags=None, title=None, threat_level=2, tlp=2):
|
||||
|
@ -187,8 +189,8 @@ class TheHiveExporter(AbstractExporter, ABC):
|
|||
return f'<{self.__class__.__name__}(url={self.url})'
|
||||
|
||||
|
||||
class TheHiveExporterTagTrigger(TheHiveExporter):
|
||||
"""TheHiveExporter TagTrigger
|
||||
class TheHiveExporterAlertTag(TheHiveExporter):
|
||||
"""TheHiveExporterAlertTag TagTrigger
|
||||
|
||||
:param url: URL of the Hive instance you want to connect to
|
||||
:param key: API key of the user you want to use
|
||||
|
@ -198,9 +200,9 @@ class TheHiveExporterTagTrigger(TheHiveExporter):
|
|||
def __init__(self, url='', key='', ssl=False):
|
||||
super().__init__(url=url, key=key, ssl=ssl)
|
||||
|
||||
def export(self, item_id, tag):
|
||||
item = Item(item_id)
|
||||
tags = item.get_tags()
|
||||
def export(self, item, tag):
|
||||
item_id = item.get_id()
|
||||
tags = list(item.get_tags())
|
||||
|
||||
# remove .gz from submitted path to TheHive because content is decompressed
|
||||
if item_id.endswith(".gz"):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*-coding:UTF-8 -*
|
||||
import time
|
||||
|
||||
import redis
|
||||
import datetime
|
||||
|
@ -24,6 +25,7 @@ from pymispgalaxies import Galaxies, Clusters
|
|||
|
||||
config_loader = ConfigLoader()
|
||||
r_tags = config_loader.get_db_conn("Kvrocks_Tags")
|
||||
r_cache = config_loader.get_redis_conn("Redis_Cache")
|
||||
config_loader = None
|
||||
|
||||
#### CORE FUNCTIONS ####
|
||||
|
@ -1240,6 +1242,89 @@ class Tag:
|
|||
return meta
|
||||
|
||||
|
||||
#### TAG AUTO PUSH ####
|
||||
|
||||
def get_auto_push_status():
|
||||
meta = {}
|
||||
for name in ['misp', 'thehive']:
|
||||
meta[name] = r_cache.hget('auto:push:status', name)
|
||||
return meta
|
||||
|
||||
def set_auto_push_status(name, status):
|
||||
return r_cache.hset('auto:push:status', name, status)
|
||||
|
||||
def get_last_auto_push_refreshed():
|
||||
last = r_cache.get('auto:push:refreshed')
|
||||
if not last:
|
||||
return -1
|
||||
else:
|
||||
return int(last)
|
||||
|
||||
def _set_last_auto_push_refreshed():
|
||||
return r_cache.set('auto:push:refreshed', int(time.time()))
|
||||
|
||||
def is_auto_push_enabled(name):
|
||||
enabled = r_tags.hget('auto:push', name)
|
||||
if enabled:
|
||||
return int(enabled) == 1
|
||||
else:
|
||||
disable_auto_push(name)
|
||||
return False
|
||||
|
||||
def enable_auto_push(name):
|
||||
r_tags.hset('auto:push', name, 1)
|
||||
|
||||
def disable_auto_push(name):
|
||||
r_tags.hset('auto:push', name, 0)
|
||||
|
||||
def get_auto_push_enabled_tags(name):
|
||||
return r_tags.smembers(f'auto:push:tags:{name}')
|
||||
|
||||
def _add_auto_push_enabled_tags(name, tag):
|
||||
return r_tags.sadd(f'auto:push:tags:{name}', tag)
|
||||
|
||||
def _del_auto_push_enabled_tags(name):
|
||||
return r_tags.delete(f'auto:push:tags:{name}')
|
||||
|
||||
def api_add_auto_push_enabled_tags(data):
|
||||
misp_tags = data.get('misp_tags', [])
|
||||
thehive_tags = data.get('thehive_tags', [])
|
||||
for tag in misp_tags:
|
||||
if not is_taxonomie_tag(tag, 'infoleak') and not is_custom_tag(tag):
|
||||
return {'error': f'Invalid Tag: {tag}'}, 400
|
||||
for tag in thehive_tags:
|
||||
if not is_taxonomie_tag(tag, 'infoleak') and not is_custom_tag(tag):
|
||||
return {'error': f'Invalid Tag: {tag}'}, 400
|
||||
|
||||
_del_auto_push_enabled_tags('misp')
|
||||
for tag in misp_tags:
|
||||
_add_auto_push_enabled_tags('misp', tag)
|
||||
_del_auto_push_enabled_tags('thehive')
|
||||
for tag in thehive_tags:
|
||||
_add_auto_push_enabled_tags('thehive', tag)
|
||||
|
||||
def get_auto_push_tags():
|
||||
tags = get_taxonomie_enabled_tags('infoleak', r_list=True)
|
||||
tags[0:0] = list(get_all_custom_tags())
|
||||
return tags
|
||||
|
||||
def get_auto_push_enabled_meta():
|
||||
meta = {}
|
||||
for name in ['misp', 'thehive']:
|
||||
meta[name] = {'enabled': is_auto_push_enabled(name)}
|
||||
meta[name]['tags'] = get_auto_push_enabled_tags(name)
|
||||
return meta
|
||||
|
||||
def refresh_auto_push():
|
||||
meta = {}
|
||||
for name in ['misp', 'thehive']:
|
||||
if is_auto_push_enabled(name):
|
||||
meta[name] = get_auto_push_enabled_tags(name)
|
||||
_set_last_auto_push_refreshed()
|
||||
return meta
|
||||
|
||||
# --- TAG AUTO PUSH --- #
|
||||
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
###################################################################################
|
||||
|
|
|
@ -31,7 +31,7 @@ from lib import regex_helper
|
|||
# TODO REWRITE ME -> PERF + IPV6 + Tracker ?
|
||||
|
||||
class IPAddress(AbstractModule):
|
||||
"""Telegram module for AIL framework"""
|
||||
"""IPAddress module for AIL framework"""
|
||||
|
||||
def __init__(self):
|
||||
super(IPAddress, self).__init__()
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*-coding:UTF-8 -*
|
||||
|
||||
"""
|
||||
module
|
||||
====================
|
||||
|
||||
This module send tagged pastes to MISP or THE HIVE Project
|
||||
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.append(os.environ['AIL_BIN'])
|
||||
##################################
|
||||
# Import Project packages
|
||||
##################################
|
||||
from modules.abstract_module import AbstractModule
|
||||
from lib.exceptions import MISPConnectionError
|
||||
from lib.objects.Items import Item
|
||||
from lib import Tag
|
||||
from exporter.MISPExporter import MISPExporterAutoDaily
|
||||
from exporter.TheHiveExporter import TheHiveExporterAlertTag
|
||||
|
||||
class MISP_Thehive_Auto_Push(AbstractModule):
|
||||
"""MISP_Hive_Feeder module for AIL framework"""
|
||||
|
||||
def __init__(self):
|
||||
super(MISP_Thehive_Auto_Push, self).__init__()
|
||||
|
||||
# refresh Tracked Regex
|
||||
self.tags = Tag.refresh_auto_push()
|
||||
self.last_refresh = time.time()
|
||||
|
||||
self.misp_exporter = MISPExporterAutoDaily()
|
||||
self.the_hive_exporter = TheHiveExporterAlertTag()
|
||||
|
||||
# Send module state to logs
|
||||
self.logger.info(f"Module {self.module_name} initialized")
|
||||
|
||||
def compute(self, message):
|
||||
if self.last_refresh < Tag.get_last_auto_push_refreshed() < 0:
|
||||
self.tags = Tag.refresh_auto_push()
|
||||
self.last_refresh = time.time()
|
||||
self.redis_logger.info('Tags Auto Push refreshed')
|
||||
|
||||
item_id, tag = message.split(' ', 1)
|
||||
item = Item(item_id)
|
||||
|
||||
# enabled
|
||||
if 'misp' in self.tags:
|
||||
if tag in self.tags['misp']:
|
||||
r = self.misp_exporter.export(item, tag)
|
||||
if r == -1:
|
||||
Tag.set_auto_push_status('misp', 'ConnectionError')
|
||||
else:
|
||||
Tag.set_auto_push_status('misp', '')
|
||||
self.logger.info('MISP Pushed:', tag, '->', item_id)
|
||||
|
||||
if 'thehive' in self.tags:
|
||||
if tag in self.tags['thehive']:
|
||||
r = self.the_hive_exporter.export(item, tag)
|
||||
if r == -1:
|
||||
Tag.set_auto_push_status('thehive', 'ConnectionError')
|
||||
elif r == -2:
|
||||
Tag.set_auto_push_status('thehive', 'Request Entity Too Large')
|
||||
else:
|
||||
Tag.set_auto_push_status('thehive', '')
|
||||
self.logger.info('thehive Pushed:', tag, '->', item_id)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
module = MISP_Thehive_Auto_Push()
|
||||
module.run()
|
|
@ -111,7 +111,7 @@ publish = Tag_feed,Sync
|
|||
[Sync_module]
|
||||
subscribe = Sync
|
||||
|
||||
[MISP_The_hive_feeder]
|
||||
[MISP_Thehive_Auto_Push]
|
||||
subscribe = Tag_feed
|
||||
|
||||
#[SentimentAnalysis]
|
||||
|
|
|
@ -366,3 +366,56 @@ def get_obj_by_tags():
|
|||
dict_tagged['date'] = dict_obj['date']
|
||||
|
||||
return render_template("tags/search_obj_by_tags.html", bootstrap_label=bootstrap_label, dict_tagged=dict_tagged)
|
||||
|
||||
|
||||
@tags_ui.route("/tags/auto_push")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def auto_push():
|
||||
|
||||
# TODO CHECK if misp or the hive connected
|
||||
|
||||
meta = Tag.get_auto_push_enabled_meta()
|
||||
auto_push_tags = Tag.get_auto_push_tags()
|
||||
return render_template("tags_auto_push.html",
|
||||
auto_push_tags=auto_push_tags,
|
||||
meta=meta,
|
||||
auto_push_status=Tag.get_auto_push_status())
|
||||
|
||||
@tags_ui.route("/tags/auto_push_post", methods=['POST'])
|
||||
@login_required
|
||||
@login_analyst
|
||||
def auto_push_post():
|
||||
tag_enabled_misp = request.form.getlist('tag_enabled_misp')
|
||||
tag_enabled_hive = request.form.getlist('tag_enabled_hive')
|
||||
|
||||
Tag.api_add_auto_push_enabled_tags({'misp_tags': tag_enabled_misp, 'thehive_tags': tag_enabled_hive})
|
||||
return redirect(url_for('tags_ui.auto_push'))
|
||||
|
||||
@tags_ui.route("/tags/auto_push/misp/enable")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def enable_misp_auto_push():
|
||||
Tag.enable_auto_push('misp')
|
||||
return redirect(url_for('tags_ui.auto_push'))
|
||||
|
||||
@tags_ui.route("/tags/auto_push/misp/disable")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def disable_misp_auto_push():
|
||||
Tag.disable_auto_push('misp')
|
||||
return redirect(url_for('tags_ui.auto_push'))
|
||||
|
||||
@tags_ui.route("/tags/auto_push/thehive/enable")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def enable_hive_auto_push():
|
||||
Tag.enable_auto_push('thehive')
|
||||
return redirect(url_for('tags_ui.auto_push'))
|
||||
|
||||
@tags_ui.route("/tags/auto_push/thehive/disable")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def disable_hive_auto_push():
|
||||
Tag.disable_auto_push('thehive')
|
||||
return redirect(url_for('tags_ui.auto_push'))
|
||||
|
|
|
@ -29,8 +29,6 @@ from lib import Tag
|
|||
|
||||
from packages import Import_helper
|
||||
|
||||
from pytaxonomies import Taxonomies # TODO REMOVE ME
|
||||
|
||||
|
||||
# ============ VARIABLES ============
|
||||
import Flask_config
|
||||
|
@ -299,189 +297,5 @@ def submit_status():
|
|||
return 'INVALID UUID'
|
||||
|
||||
|
||||
######################################################################################################
|
||||
######################################################################################################
|
||||
######################################################################################################
|
||||
######################################################################################################
|
||||
|
||||
# TODO MIGRATE TAGS PUSH
|
||||
|
||||
# TEMPORARY: 2 SET OF CUSTOM + infoleak tags ?????????
|
||||
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/edit_tag_export")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def edit_tag_export():
|
||||
return abort(404)
|
||||
|
||||
misp_auto_events = r_serv_db.get('misp:auto-events')
|
||||
hive_auto_alerts = r_serv_db.get('hive:auto-alerts')
|
||||
|
||||
whitelist_misp = r_serv_db.scard('whitelist_misp')
|
||||
whitelist_hive = r_serv_db.scard('whitelist_hive')
|
||||
|
||||
list_export_tags = list(r_serv_db.smembers('list_export_tags'))
|
||||
status_misp = []
|
||||
status_hive = []
|
||||
|
||||
infoleak_tags = Taxonomies().get('infoleak').machinetags()
|
||||
is_infoleak_tag = []
|
||||
|
||||
for tag in list_export_tags:
|
||||
if r_serv_db.sismember('whitelist_misp', tag):
|
||||
status_misp.append(True)
|
||||
else:
|
||||
status_misp.append(False)
|
||||
|
||||
for tag in list_export_tags:
|
||||
if r_serv_db.sismember('whitelist_hive', tag):
|
||||
status_hive.append(True)
|
||||
else:
|
||||
status_hive.append(False)
|
||||
|
||||
if tag in infoleak_tags:
|
||||
is_infoleak_tag.append(True)
|
||||
else:
|
||||
is_infoleak_tag.append(False)
|
||||
|
||||
if misp_auto_events is not None:
|
||||
if int(misp_auto_events) == 1:
|
||||
misp_active = True
|
||||
else:
|
||||
misp_active = False
|
||||
else:
|
||||
misp_active = False
|
||||
|
||||
if hive_auto_alerts is not None:
|
||||
if int(hive_auto_alerts) == 1:
|
||||
hive_active = True
|
||||
else:
|
||||
hive_active = False
|
||||
else:
|
||||
hive_active = False
|
||||
|
||||
nb_tags = str(r_serv_db.scard('list_export_tags'))
|
||||
nb_tags_whitelist_misp = str(r_serv_db.scard('whitelist_misp')) + ' / ' + nb_tags
|
||||
nb_tags_whitelist_hive = str(r_serv_db.scard('whitelist_hive')) + ' / ' + nb_tags
|
||||
|
||||
return render_template("edit_tag_export.html",
|
||||
misp_active=misp_active,
|
||||
hive_active=hive_active,
|
||||
list_export_tags=list_export_tags,
|
||||
is_infoleak_tag=is_infoleak_tag,
|
||||
status_misp=status_misp,
|
||||
status_hive=status_hive,
|
||||
nb_tags_whitelist_misp=nb_tags_whitelist_misp,
|
||||
nb_tags_whitelist_hive=nb_tags_whitelist_hive,
|
||||
flag_misp=True,
|
||||
flag_hive=True)
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/tag_export_edited", methods=['POST'])
|
||||
@login_required
|
||||
@login_analyst
|
||||
def tag_export_edited():
|
||||
return abort(404)
|
||||
|
||||
|
||||
tag_enabled_misp = request.form.getlist('tag_enabled_misp')
|
||||
tag_enabled_hive = request.form.getlist('tag_enabled_hive')
|
||||
|
||||
list_export_tags = list(r_serv_db.smembers('list_export_tags'))
|
||||
|
||||
r_serv_db.delete('whitelist_misp')
|
||||
r_serv_db.delete('whitelist_hive')
|
||||
|
||||
for tag in tag_enabled_misp:
|
||||
if r_serv_db.sismember('list_export_tags', tag):
|
||||
r_serv_db.sadd('whitelist_misp', tag)
|
||||
else:
|
||||
return 'invalid input'
|
||||
|
||||
for tag in tag_enabled_hive:
|
||||
if r_serv_db.sismember('list_export_tags', tag):
|
||||
r_serv_db.sadd('whitelist_hive', tag)
|
||||
else:
|
||||
return 'invalid input'
|
||||
|
||||
return redirect(url_for('PasteSubmit.edit_tag_export'))
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/enable_misp_auto_event")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def enable_misp_auto_event():
|
||||
return abort(404)
|
||||
|
||||
r_serv_db.set('misp:auto-events', 1)
|
||||
return edit_tag_export()
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/disable_misp_auto_event")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def disable_misp_auto_event():
|
||||
return abort(404)
|
||||
|
||||
r_serv_db.set('misp:auto-events', 0)
|
||||
return edit_tag_export()
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/enable_hive_auto_alert")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def enable_hive_auto_alert():
|
||||
return abort(404)
|
||||
|
||||
r_serv_db.set('hive:auto-alerts', 1)
|
||||
return edit_tag_export()
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/disable_hive_auto_alert")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def disable_hive_auto_alert():
|
||||
return abort(404)
|
||||
|
||||
r_serv_db.set('hive:auto-alerts', 0)
|
||||
return edit_tag_export()
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/add_push_tag")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def add_push_tag():
|
||||
return abort(404)
|
||||
|
||||
tag = request.args.get('tag')
|
||||
if tag is not None:
|
||||
|
||||
#limit tag length
|
||||
if len(tag) > 49:
|
||||
tag = tag[0:48]
|
||||
|
||||
r_serv_db.sadd('list_export_tags', tag)
|
||||
|
||||
to_return = {}
|
||||
to_return["tag"] = tag
|
||||
return jsonify(to_return)
|
||||
else:
|
||||
return 'None args', 400
|
||||
|
||||
@PasteSubmit.route("/PasteSubmit/delete_push_tag")
|
||||
@login_required
|
||||
@login_analyst
|
||||
def delete_push_tag():
|
||||
return abort(404)
|
||||
|
||||
|
||||
tag = request.args.get('tag')
|
||||
|
||||
infoleak_tags = Taxonomies().get('infoleak').machinetags()
|
||||
if tag not in infoleak_tags and r_serv_db.sismember('list_export_tags', tag):
|
||||
r_serv_db.srem('list_export_tags', tag)
|
||||
r_serv_db.srem('whitelist_misp', tag)
|
||||
r_serv_db.srem('whitelist_hive', tag)
|
||||
to_return = {}
|
||||
to_return["tag"] = tag
|
||||
return jsonify(to_return)
|
||||
else:
|
||||
return 'this tag can\'t be removed', 400
|
||||
|
||||
# ========= REGISTRATION =========
|
||||
app.register_blueprint(PasteSubmit, url_prefix=baseUrl)
|
||||
|
|
|
@ -1,354 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Tags Export - AIL</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.css') }}" rel="stylesheet" type="text/css" />
|
||||
<!-- JS -->
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
|
||||
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.js') }}"></script>
|
||||
|
||||
<style>
|
||||
.tooltip-inner {
|
||||
text-align: left;
|
||||
height: 200%;
|
||||
width: 200%;
|
||||
max-width: 500px;
|
||||
max-height: 500px;
|
||||
font-size: 13px;
|
||||
}
|
||||
xmp {
|
||||
white-space:pre-wrap;
|
||||
word-wrap:break-word;
|
||||
}
|
||||
.test thead{
|
||||
background: #d91f2d;
|
||||
color: #fff;
|
||||
}
|
||||
.mouse_pointer{
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% include 'navbar.html' %}
|
||||
|
||||
<div id="page-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
</div>
|
||||
<!-- /.col-lg-12 -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading"> MISP Auto Event Creation
|
||||
{% if misp_active %}
|
||||
<span class="label label-success pull-right"> Enabled</span>
|
||||
{% endif %}
|
||||
{% if not misp_active %}
|
||||
<span class="label label-danger pull-right"> Disabled</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="text-center">
|
||||
<img id="misp-logo" src="{{url_for('static', filename='image/misp-logo.png') }}" class="text-center" >
|
||||
</div>
|
||||
<br>
|
||||
|
||||
{% if flag_misp %}
|
||||
{% if misp_active %}
|
||||
<a href="{{ url_for('PasteSubmit.disable_misp_auto_event') }}" class="btn btn-danger pull-right">
|
||||
<i class="fa fa-times fa"></i> Disable Event Creation
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if not misp_active %}
|
||||
<a href="{{ url_for('PasteSubmit.enable_misp_auto_event') }}" class="btn btn-success pull-right">
|
||||
<i class="fa fa-check-square-o fa"></i> Enable Event Creation
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if not flag_misp %}
|
||||
<button class="btn btn-danger pull-right disabled">
|
||||
<i class="fa fa-times fa"></i> MISP is not connected
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="panel panel-primary" style="min-width: 500px;">
|
||||
<div class="panel-heading">The hive auto export
|
||||
{% if hive_active %}
|
||||
<span class="label label-success pull-right"> Enabled</span>
|
||||
{% endif %}
|
||||
{% if not hive_active %}
|
||||
<span class="label label-danger pull-right"> Disabled</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="text-center">
|
||||
<img id="misp-logo" src="{{url_for('static', filename='image/thehive-logo.png') }}" width="500">
|
||||
</div>
|
||||
|
||||
{% if flag_hive %}
|
||||
{% if hive_active %}
|
||||
<a href="{{ url_for('PasteSubmit.disable_hive_auto_alert') }}" class="btn btn-danger pull-right">
|
||||
<i class="fa fa-times fa"></i> Disable Alert Creation
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if not hive_active %}
|
||||
<a href="{{ url_for('PasteSubmit.enable_hive_auto_alert') }}" class="btn btn-success pull-right">
|
||||
<i class="fa fa-check-square-o fa"></i> Enable Alert Creation
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if not flag_hive %}
|
||||
<button class="btn btn-danger pull-right disabled">
|
||||
<i class="fa fa-times fa"></i> The Hive is not connected
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="{{ url_for('PasteSubmit.tag_export_edited') }}" id="checkboxForm" method='post'>
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-6">
|
||||
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Metadata :
|
||||
<span class="pull-right"> </span>
|
||||
<span class="badge pull-right">{{ nb_tags_whitelist_misp }}</span>
|
||||
<ul class="list-group"><li class="list-group-item">
|
||||
<table class="test table table-striped table-bordered table-hover table-responsive " id="myTable_misp">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Whitelist</th>
|
||||
<th>Tag</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for tag in list_export_tags %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if status_misp[loop.index0] %}
|
||||
<div style="display:none;">Enabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_misp" checked>
|
||||
{% endif %}
|
||||
{% if not status_misp[loop.index0] %}
|
||||
<div style="display:none;">Disabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_misp" >
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ tag }}
|
||||
{% if not is_infoleak_tag[loop.index0] %}
|
||||
<div class="btn-link btn-interaction pull-right mouse_pointer" data-toggle="tooltip" title="Delete this tag" onclick="delete_push_tag('{{ tag }}')">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</li></ul>
|
||||
</div></div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Metadata :
|
||||
<span class="pull-right"> </span>
|
||||
<span class="badge pull-right">{{ nb_tags_whitelist_hive }}</span>
|
||||
<ul class="list-group"><li class="list-group-item">
|
||||
|
||||
<table class="test table table-striped table-bordered table-hover table-responsive " id="myTable_hive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Whitelist</th>
|
||||
<th>Tag</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for tag in list_export_tags %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if status_hive[loop.index0] %}
|
||||
<div style="display:none;">Enabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_hive" checked>
|
||||
{% endif %}
|
||||
{% if not status_hive[loop.index0] %}
|
||||
<div style="display:none;">Disabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_hive" >
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ tag }}
|
||||
{% if not is_infoleak_tag[loop.index0] %}
|
||||
<div class="btn-link btn-interaction pull-right mouse_pointer" data-toggle="tooltip" title="Delete this tag" onclick="delete_push_tag('{{ tag }}')">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</li></ul>
|
||||
</div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="input-group-btn text-center">
|
||||
<button class="btn btn-primary btn-lg" onclick="submitActiveTags()">
|
||||
<i class="fa fa-check-square-o fa"></i>
|
||||
Update Tags
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<div>
|
||||
|
||||
<div id="add_custom_tag_modal" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div id="mymodalcontent" class="modal-content">
|
||||
<div class="modal-header" style="border-bottom: 4px solid #48c9b0; background-color: #48c9b0; color: #ffffff;">
|
||||
<h2 class="text-center">Add Custom Tag</h2>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group input-group" style="margin-bottom: 0px;">
|
||||
<span class="input-group-addon"><i class="fa fa-tag fa"></i></span>
|
||||
<input id="new_custom_tag" class="form-control" placeholder="Add a new custom tag to the tag export" type="text">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary btn-tags" onclick="add_custom_tag()">
|
||||
<span class="glyphicon glyphicon-plus"></span>
|
||||
<span class="label-icon">Add Custom Tag</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal" >Close</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary pull-right" data-toggle="modal" data-target="#add_custom_tag_modal" data-url="{{ url_for('tags_ui.tags_taxonomies') }}">
|
||||
<span class="glyphicon glyphicon-plus "></span> Add Custom Tag
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /#page-wrapper -->
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
var table_misp
|
||||
var table_hive
|
||||
$(document).ready(function(){
|
||||
|
||||
table_misp = $('#myTable_misp').DataTable(
|
||||
{
|
||||
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||
"iDisplayLength": 10,
|
||||
"order": [[ 1, "asc" ]]
|
||||
}
|
||||
);
|
||||
|
||||
table_hive = $('#myTable_hive').DataTable(
|
||||
{
|
||||
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||
"iDisplayLength": 10,
|
||||
"order": [[ 1, "asc" ]]
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function submitActiveTags(){
|
||||
table_misp.destroy()
|
||||
table_misp = $('#myTable_misp').DataTable(
|
||||
{
|
||||
"iDisplayLength": -1,
|
||||
}
|
||||
);
|
||||
table_hive.destroy()
|
||||
table_hive = $('#myTable_hive').DataTable(
|
||||
{
|
||||
"iDisplayLength": -1,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function delete_push_tag(tag){
|
||||
//var row_tr = $(this).closest("tr");
|
||||
$.get("{{ url_for('PasteSubmit.delete_push_tag') }}", { tag: tag }, function(data, status){
|
||||
if(status == "success") {
|
||||
//row_tr.remove();
|
||||
window.location.reload(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add_custom_tag(){
|
||||
$.get("{{ url_for('PasteSubmit.add_push_tag') }}", { tag: document.getElementById('new_custom_tag').value }, function(data, status){
|
||||
if(status == "success") {
|
||||
//row_tr.remove();
|
||||
window.location.reload(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -57,7 +57,7 @@
|
|||
</h5>
|
||||
<ul class="nav flex-md-column flex-row navbar-nav justify-content-between w-100">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{url_for('PasteSubmit.edit_tag_export')}}" id="nav_regular_edit_tag_export">
|
||||
<a class="nav-link" href="{{url_for('tags_ui.auto_push')}}" id="nav_regular_edit_tag_export">
|
||||
<i class="fas fa-cogs"></i>
|
||||
MISP and Hive, auto push
|
||||
</a>
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Tags Export - AIL</title>
|
||||
<link rel="icon" href="{{ url_for('static', filename='image/ail-icon.png') }}">
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link href="{{ url_for('static', filename='css/bootstrap4.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.min.css') }}" rel="stylesheet">
|
||||
<!-- JS -->
|
||||
<script src="{{ url_for('static', filename='js/jquery.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/bootstrap4.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/dataTables.bootstrap.min.js') }}"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% include 'nav_bar.html' %}
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
|
||||
{% include 'hunter/menu_sidebar.html' %}
|
||||
|
||||
<div class="col-12 col-lg-10" id="core_content">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card my-2">
|
||||
<div class="card-header bg-dark text-white">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<span class="card-title">MISP Auto Event Creation</span>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{% if meta['misp']['enabled'] %}
|
||||
<span class="badge badge-success pull-right"> Enabled</span>
|
||||
{% else %}
|
||||
<span class="badge badge-danger pull-right"> Disabled</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="text-center">
|
||||
<img id="misp-logo" src="{{url_for('static', filename='image/misp-logo.png') }}" class="text-center" >
|
||||
|
||||
<br><br>
|
||||
|
||||
{% if meta['misp']['enabled'] %}
|
||||
<a href="{{ url_for('tags_ui.disable_misp_auto_push') }}" class="btn btn-danger pull-right">
|
||||
<i class="fas fa-times"></i> Disable Event Creation
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('tags_ui.enable_misp_auto_push') }}" class="btn btn-success pull-right">
|
||||
<i class="fas fa-check-square-o"></i> Enable Event Creation
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if auto_push_status['misp'] %}
|
||||
<button class="btn btn-danger pull-right disabled">
|
||||
Error: <i class="fa fa-times fa"></i> {{ auto_push_status['misp'] }}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card my-2">
|
||||
<div class="card-header bg-dark text-white">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<span class="card-title">The hive Auto Alert Creation</span>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{% if meta['thehive']['enabled'] %}
|
||||
<span class="badge badge-success pull-right"> Enabled</span>
|
||||
{% else %}
|
||||
<span class="badge badge-danger pull-right"> Disabled</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="text-center">
|
||||
<img id="misp-logo" src="{{url_for('static', filename='image/thehive-logo.png') }}" width="500">
|
||||
<br>
|
||||
|
||||
{% if meta['thehive']['enabled'] %}
|
||||
<a href="{{ url_for('tags_ui.disable_hive_auto_push') }}" class="btn btn-danger pull-right">
|
||||
<i class="fas fa-times"></i> Disable Alert Creation
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ url_for('tags_ui.enable_hive_auto_push') }}" class="btn btn-success mr-right">
|
||||
<i class="fas fa-check-square-o"></i> Enable Alert Creation
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if auto_push_status['thehive'] %}
|
||||
<button class="btn btn-danger pull-right disabled">
|
||||
Error: <i class="fa fa-times fa"></i> {{ auto_push_status['thehive'] }}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<form action="{{ url_for('tags_ui.auto_push_post') }}" id="checkboxForm" method='post'>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-light">
|
||||
<div class="card-header">
|
||||
MISP Tags To Push :
|
||||
<span class="pull-right"> </span>
|
||||
<span class="badge badge-secondary">{{ meta['misp']['tags']|length }} / {{ auto_push_tags|length }}</span>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<table class="table table-striped table-bordered table-hover" id="myTable_misp">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Enabled</th>
|
||||
<th>Tag</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for tag in auto_push_tags %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
{% if tag in meta['misp']['tags'] %}
|
||||
<div style="display:none;">Enabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_misp" checked>
|
||||
{% else %}
|
||||
<div style="display:none;">Disabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_misp" >
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ tag }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-light">
|
||||
<div class="card-header">
|
||||
The Hive Tags To Push :
|
||||
<span class="pull-right"> </span>
|
||||
<span class="badge badge-secondary">{{ meta['thehive']['tags']|length }} / {{ auto_push_tags|length }}</span>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<table class="table table-striped table-bordered table-hover" id="myTable_hive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Enabled</th>
|
||||
<th>Tag</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for tag in auto_push_tags %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
{% if tag in meta['thehive']['tags'] %}
|
||||
<div style="display:none;">Enabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_hive" checked>
|
||||
{% else %}
|
||||
<div style="display:none;">Disabled</div>
|
||||
<input type="checkbox" value="{{ tag }}" name="tag_enabled_hive" >
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ tag }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="text-center my-4">
|
||||
<button class="btn btn-primary btn-lg" onclick="submitActiveTags()">
|
||||
<i class="fas fa-check-square"></i> Update Tags
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
var table_misp
|
||||
var table_hive
|
||||
$(document).ready(function(){
|
||||
|
||||
table_misp = $('#myTable_misp').DataTable(
|
||||
{
|
||||
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||
"iDisplayLength": 10,
|
||||
"order": [[ 1, "asc" ]]
|
||||
}
|
||||
);
|
||||
|
||||
table_hive = $('#myTable_hive').DataTable(
|
||||
{
|
||||
"aLengthMenu": [[5, 10, 15, -1], [5, 10, 15, "All"]],
|
||||
"iDisplayLength": 10,
|
||||
"order": [[ 1, "asc" ]]
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
function submitActiveTags(){
|
||||
table_misp.destroy()
|
||||
table_misp = $('#myTable_misp').DataTable(
|
||||
{
|
||||
"iDisplayLength": -1,
|
||||
}
|
||||
);
|
||||
table_hive.destroy()
|
||||
table_hive = $('#myTable_hive').DataTable(
|
||||
{
|
||||
"iDisplayLength": -1,
|
||||
}
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue