mirror of https://github.com/CIRCL/AIL-framework
chg: [UI MISP export] add MISP export
parent
ee15a9b5c6
commit
4d0e9a94d0
|
@ -2,6 +2,7 @@
|
||||||
# -*-coding:UTF-8 -*
|
# -*-coding:UTF-8 -*
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import io
|
||||||
import sys
|
import sys
|
||||||
import uuid
|
import uuid
|
||||||
import redis
|
import redis
|
||||||
|
@ -20,6 +21,28 @@ import Correlate_object
|
||||||
# MISP
|
# MISP
|
||||||
from pymisp import MISPEvent, MISPObject, PyMISP
|
from pymisp import MISPEvent, MISPObject, PyMISP
|
||||||
|
|
||||||
|
def is_valid_obj_to_export(obj_type, obj_subtype, obj_id):
|
||||||
|
if not Correlate_object.is_valid_object_type(obj_type):
|
||||||
|
return False
|
||||||
|
if not Correlate_object.is_valid_object_subtype(obj_type, obj_subtype):
|
||||||
|
return False
|
||||||
|
if not Correlate_object.exist_object(obj_type, obj_id, type_id=obj_subtype):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def sanitize_obj_export_lvl(lvl):
|
||||||
|
try:
|
||||||
|
lvl = int(lvl)
|
||||||
|
except:
|
||||||
|
lvl = 0
|
||||||
|
return lvl
|
||||||
|
|
||||||
|
def get_export_filename(json_content):
|
||||||
|
print(json_content)
|
||||||
|
return 'ail_export.json'
|
||||||
|
|
||||||
|
def create_in_memory_file(json_content):
|
||||||
|
return io.BytesIO(json_content.encode())
|
||||||
|
|
||||||
def tag_misp_object_attributes(l_ref_obj_attr, tags):
|
def tag_misp_object_attributes(l_ref_obj_attr, tags):
|
||||||
for obj_attr in l_ref_obj_attr:
|
for obj_attr in l_ref_obj_attr:
|
||||||
|
@ -144,12 +167,6 @@ def filter_obj_linked(l_obj):
|
||||||
res = Correlate_object.get_object_correlation(obj['type'], obj['id'], obj.get('subtype', None))
|
res = Correlate_object.get_object_correlation(obj['type'], obj['id'], obj.get('subtype', None))
|
||||||
print(res)
|
print(res)
|
||||||
|
|
||||||
|
|
||||||
def export_object_list(l_obj, mode='union'):
|
|
||||||
# filter elements to export
|
|
||||||
if mode=='linked':
|
|
||||||
filter_obj_linked(l_obj)
|
|
||||||
|
|
||||||
def add_relation_ship_to_create(set_relationship, dict_obj, dict_new_obj):
|
def add_relation_ship_to_create(set_relationship, dict_obj, dict_new_obj):
|
||||||
global_id = Correlate_object.get_obj_global_id(dict_obj['type'], dict_obj['id'], dict_obj.get('subtype', None))
|
global_id = Correlate_object.get_obj_global_id(dict_obj['type'], dict_obj['id'], dict_obj.get('subtype', None))
|
||||||
global_id_new = Correlate_object.get_obj_global_id(dict_new_obj['type'], dict_new_obj['id'], dict_new_obj.get('subtype', None))
|
global_id_new = Correlate_object.get_obj_global_id(dict_new_obj['type'], dict_new_obj['id'], dict_new_obj.get('subtype', None))
|
||||||
|
@ -194,7 +211,7 @@ def add_obj_to_create_by_lvl(all_obj_to_export, set_relationship, dict_obj, lvl)
|
||||||
add_obj_to_create_by_lvl(all_obj_to_export, set_relationship, dict_obj, lvl)
|
add_obj_to_create_by_lvl(all_obj_to_export, set_relationship, dict_obj, lvl)
|
||||||
|
|
||||||
|
|
||||||
def create_list_of_objs_to_export(l_obj, mode='union'):
|
def create_list_of_objs_to_export(l_obj):
|
||||||
all_obj_to_export = set()
|
all_obj_to_export = set()
|
||||||
set_relationship = set()
|
set_relationship = set()
|
||||||
for obj in l_obj:
|
for obj in l_obj:
|
||||||
|
@ -219,10 +236,9 @@ def create_list_of_objs_to_export(l_obj, mode='union'):
|
||||||
# add object to event
|
# add object to event
|
||||||
event.add_object(dict_misp_obj[obj_global_id])
|
event.add_object(dict_misp_obj[obj_global_id])
|
||||||
|
|
||||||
print(event.to_json())
|
#misp = PyMISP('https://127.0.0.1:8443/', 'uXgcN42b7xuL88XqK5hubwD8Q8596VrrBvkHQzB0', False)
|
||||||
|
#misp.add_event(event, pythonify=True)
|
||||||
misp = PyMISP('https://127.0.0.1:8443/', 'uXgcN42b7xuL88XqK5hubwD8Q8596VrrBvkHQzB0', False)
|
return event.to_json()
|
||||||
misp.add_event(event, pythonify=True)
|
|
||||||
|
|
||||||
|
|
||||||
def create_all_misp_obj(all_obj_to_export, set_relationship):
|
def create_all_misp_obj(all_obj_to_export, set_relationship):
|
||||||
|
|
|
@ -24,7 +24,22 @@ r_serv_metadata = config_loader.get_redis_conn("ARDB_Metadata")
|
||||||
config_loader = None
|
config_loader = None
|
||||||
|
|
||||||
def is_valid_object_type(object_type):
|
def is_valid_object_type(object_type):
|
||||||
if object_type in ['domain', 'item', 'image', 'decoded']:
|
if object_type in ['domain', 'item', 'image', 'decoded', 'pgp', 'cryptocurrency']:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_valid_object_subtype(object_type, object_subtype):
|
||||||
|
if object_type == 'pgp':
|
||||||
|
return Pgp.pgp.is_valid_obj_subtype(object_subtype)
|
||||||
|
elif object_type == 'cryptocurrency':
|
||||||
|
return Pgp.pgp.is_valid_obj_subtype(object_subtype)
|
||||||
|
elif object_subtype == None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if object_type in ['domain', 'item', 'image', 'decoded', 'pgp', 'cryptocurrency']:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -133,6 +133,12 @@ class Correlation(object):
|
||||||
'''
|
'''
|
||||||
return self.all_correlation_types
|
return self.all_correlation_types
|
||||||
|
|
||||||
|
def is_valid_obj_subtype(self, subtype):
|
||||||
|
if subtype in self.all_correlation_types:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def get_correlation_obj_type(self):
|
def get_correlation_obj_type(self):
|
||||||
if self.correlation_name=='pgpdump':
|
if self.correlation_name=='pgpdump':
|
||||||
return 'pgp'
|
return 'pgp'
|
||||||
|
|
|
@ -10,7 +10,7 @@ import sys
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for, Response
|
from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for, Response, send_file
|
||||||
from flask_login import login_required, current_user, login_user, logout_user
|
from flask_login import login_required, current_user, login_user, logout_user
|
||||||
|
|
||||||
sys.path.append('modules')
|
sys.path.append('modules')
|
||||||
|
@ -73,3 +73,45 @@ def import_object_file():
|
||||||
def export_object():
|
def export_object():
|
||||||
object_type = request.args.get('object_type')
|
object_type = request.args.get('object_type')
|
||||||
return render_template("export_object.html", bootstrap_label=bootstrap_label)
|
return render_template("export_object.html", bootstrap_label=bootstrap_label)
|
||||||
|
|
||||||
|
@import_export.route("/import_export/export_file", methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
@login_analyst
|
||||||
|
def export_object_file():
|
||||||
|
l_obj_to_export = []
|
||||||
|
l_obj_invalid = []
|
||||||
|
for obj_tuple in list(request.form):
|
||||||
|
l_input = request.form.getlist(obj_tuple)
|
||||||
|
if len(l_input) == 3:
|
||||||
|
obj_type = l_input[0]
|
||||||
|
obj_id = l_input[1]
|
||||||
|
lvl = l_input[2]
|
||||||
|
lvl = MispExport.sanitize_obj_export_lvl(lvl)
|
||||||
|
|
||||||
|
obj_subtype = obj_type.split(';')
|
||||||
|
if len(obj_subtype) == 2:
|
||||||
|
obj_type = obj_subtype[0]
|
||||||
|
obj_subtype = obj_subtype[1]
|
||||||
|
else:
|
||||||
|
obj_subtype = None
|
||||||
|
|
||||||
|
obj_dict = {'id': obj_id, 'type': obj_type, 'lvl': lvl}
|
||||||
|
if obj_subtype:
|
||||||
|
obj_dict['subtype'] = obj_subtype
|
||||||
|
|
||||||
|
if MispExport.is_valid_obj_to_export(obj_type, obj_subtype, obj_id):
|
||||||
|
l_obj_to_export.append(obj_dict)
|
||||||
|
else:
|
||||||
|
l_obj_invalid.append(obj_dict)
|
||||||
|
print(l_obj_to_export)
|
||||||
|
print(l_obj_invalid)
|
||||||
|
|
||||||
|
if l_obj_to_export:
|
||||||
|
|
||||||
|
json_export = MispExport.create_list_of_objs_to_export(l_obj_to_export)
|
||||||
|
export_filename = MispExport.get_export_filename(json_export)
|
||||||
|
json_export = MispExport.create_in_memory_file(json_export)
|
||||||
|
return send_file(json_export, as_attachment=True, attachment_filename=export_filename)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return render_template("export_object.html", bootstrap_label=bootstrap_label)
|
||||||
|
|
|
@ -40,12 +40,12 @@
|
||||||
</h5>
|
</h5>
|
||||||
<ul class="nav flex-md-column flex-row navbar-nav justify-content-between w-100">
|
<ul class="nav flex-md-column flex-row navbar-nav justify-content-between w-100">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{url_for('import_export.import_object')}}" id="nav_show_item_by_id">
|
<a class="nav-link" href="{{url_for('import_export.import_object')}}" id="nav_misp_import">
|
||||||
<b>Import</b>
|
<b>Import</b>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{url_for('import_export.export_object')}}" id="nav_show_item_by_id">
|
<a class="nav-link" href="{{url_for('import_export.export_object')}}" id="nav_misp_export">
|
||||||
<b>Export</b>
|
<b>Export</b>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -30,15 +30,66 @@
|
||||||
|
|
||||||
<div class="col-12 col-lg-10" id="core_content">
|
<div class="col-12 col-lg-10" id="core_content">
|
||||||
|
|
||||||
MISP exporter
|
<h3>MISP exporter</h3>
|
||||||
|
|
||||||
|
<form action="{{ url_for('import_export.export_object_file') }}" method="post" enctype=multipart/form-data onsubmit="submitPaste()">
|
||||||
|
|
||||||
|
<div id="container-id-to-import">
|
||||||
|
|
||||||
|
<p>Select a list of objects to export</p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-2" for="obj_input_type"><b>Object Type</b></div>
|
||||||
|
<div class="col-8" for="obj_input_id"><b>Object ID</b></div>
|
||||||
|
<div class="col-1" for="obj_input_lvl"><b>Lvl</b></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="form-body">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="fields">
|
||||||
|
<div class="input-group mb-1">
|
||||||
|
<select class="custom-select col-2" name="first_obj_to_export" id="obj_input_type">
|
||||||
|
<option selected>Object type...</option>
|
||||||
|
<option value="item">Item</option>
|
||||||
|
<option value="domain">Domain</option>
|
||||||
|
<option value="image">Image</option>
|
||||||
|
<option value="decoded">Decoded</option>
|
||||||
|
<option value="pgp;key">PGP - Key</option>
|
||||||
|
<option value="pgp;name">PGP - Name</option>
|
||||||
|
<option value="pgp;mail">PGP - Mail</option>
|
||||||
|
<option value="cryptocurrency;bitcoin">Cryptocurrency - Bitcoin</option>
|
||||||
|
<option value="cryptocurrency;bitcoin-cash">Cryptocurrency - Bitcoin Cash</option>
|
||||||
|
<option value="cryptocurrency;dash">Cryptocurrency - Dash</option>
|
||||||
|
<option value="cryptocurrency;etherum">Cryptocurrency - Etherum</option>
|
||||||
|
<option value="cryptocurrency;litecoin">Cryptocurrency - Litecoin</option>
|
||||||
|
<option value="cryptocurrency;monero">Cryptocurrency - Monero</option>
|
||||||
|
<option value="cryptocurrency;zcash">Cryptocurrency - Zcash</option>
|
||||||
|
</select>
|
||||||
|
<input type="text" class="form-control col-8" name="first_obj_to_export" id="obj_input_id">
|
||||||
|
<input class="form-control col-1" type="number" min="0" value="0" name="first_obj_to_export" id="obj_input_lvl">
|
||||||
|
<span class="btn btn-info input-group-addon add-field col-1"><i class="fas fa-plus"></i></span>
|
||||||
|
</div>
|
||||||
|
<span class="help-block" hidden>Export Objects</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-info" name="submit" type="submit">Export Objects</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$("#page-Decoded").addClass("active");
|
$("#page-Decoded").addClass("active");
|
||||||
|
$("#nav_misp_export").addClass("active");
|
||||||
});
|
});
|
||||||
|
|
||||||
function toggle_sidebar(){
|
function toggle_sidebar(){
|
||||||
|
@ -54,6 +105,31 @@ function toggle_sidebar(){
|
||||||
$('#core_content').addClass('col-lg-10')
|
$('#core_content').addClass('col-lg-10')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var input_1 = '<div class="input-group mb-1"><select class="custom-select col-2" name="'
|
||||||
|
var input_2 = '"><option selected>Object type...</option><option value="item">Item</option><option value="domain">Domain</option><option value="image">Image</option><option value="decoded">Decoded</option><option value="pgp;key">PGP - Key</option><option value="pgp;name">PGP - Name</option><option value="pgp;mail">PGP - Mail</option><option value="cryptocurrency;bitcoin">Cryptocurrency - Bitcoin</option><option value="cryptocurrency;bitcoin-cash">Cryptocurrency - Bitcoin Cash</option><option value="cryptocurrency;dash">Cryptocurrency - Dash</option><option value="cryptocurrency;etherum">Cryptocurrency - Etherum</option><option value="cryptocurrency;litecoin">Cryptocurrency - Litecoin</option><option value="cryptocurrency;monero">Cryptocurrency - Monero</option><option value="cryptocurrency;zcash">Cryptocurrency - Zcash</option></select><input type="text" class="form-control col-8" name="'
|
||||||
|
var input_3 = '"><input class="form-control col-1" type="number" min="0" value="0" name="'
|
||||||
|
var input_4 = '"></div>';
|
||||||
|
var minusButton = '<span class="btn btn-danger input-group-addon delete-field col-1"><i class="fas fa-trash-alt"></i></span>';
|
||||||
|
|
||||||
|
$('.add-field').click(function() {
|
||||||
|
var new_uuid = uuidv4();
|
||||||
|
var template = input_1 + new_uuid + input_2 + new_uuid + input_3+ new_uuid + input_4;
|
||||||
|
var temp = $(template).insertBefore('.help-block');
|
||||||
|
temp.append(minusButton);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.fields').on('click', '.delete-field', function(){
|
||||||
|
$(this).parent().remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function uuidv4() {
|
||||||
|
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||||
|
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
<form action="{{ url_for('import_export.import_object_file') }}" method="post" enctype=multipart/form-data onsubmit="submitPaste()">
|
<form action="{{ url_for('import_export.import_object_file') }}" method="post" enctype=multipart/form-data>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="file">Select a <b>JSON File</b> to import:</label>
|
<label for="file">Select a <b>JSON File</b> to import:</label>
|
||||||
|
@ -58,6 +58,7 @@
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$("#page-Decoded").addClass("active");
|
$("#page-Decoded").addClass("active");
|
||||||
|
$("#nav_misp_import").addClass("active");
|
||||||
});
|
});
|
||||||
|
|
||||||
function toggle_sidebar(){
|
function toggle_sidebar(){
|
||||||
|
|
Loading…
Reference in New Issue