hcornet 506716e703
Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s
first sync
2025-03-04 07:59:21 +01:00

153 lines
5.0 KiB
Python

#!/usr/bin/env python3
#
# IRIS Source Code
# Copyright (C) 2021 - Airbus CyberSecurity (SAS) - DFIR-IRIS Team
# ir@cyberactionlab.net - contact@dfir-iris.org
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import itertools
from datetime import datetime
from flask import Blueprint
from flask import redirect
from flask import render_template
from flask import url_for
from flask_login import current_user
from flask_wtf import FlaskForm
from app.datamgmt.case.case_db import get_case
from app.datamgmt.case.case_events_db import get_case_events_assets_graph
from app.datamgmt.case.case_events_db import get_case_events_ioc_graph
from app.models.authorization import CaseAccessLevel
from app.util import ac_api_case_requires
from app.util import ac_case_requires
from app.util import response_success
case_graph_blueprint = Blueprint('case_graph',
__name__,
template_folder='templates')
# CONTENT ------------------------------------------------
@case_graph_blueprint.route('/case/graph', methods=['GET'])
@ac_case_requires(CaseAccessLevel.read_only, CaseAccessLevel.full_access)
def case_graph(caseid, url_redir):
if url_redir:
return redirect(url_for('case_graph.case_graph', cid=caseid, redirect=True))
case = get_case(caseid)
form = FlaskForm()
return render_template("case_graph.html", case=case, form=form)
@case_graph_blueprint.route('/case/graph/getdata', methods=['GET'])
@ac_api_case_requires(CaseAccessLevel.read_only, CaseAccessLevel.full_access)
def case_graph_get_data(caseid):
events = get_case_events_assets_graph(caseid)
events.extend(get_case_events_ioc_graph(caseid))
nodes = []
edges = []
dates = {
"human": [],
"machine": []
}
tmp = {}
for event in events:
if hasattr(event, 'asset_compromise_status_id'):
if event.asset_compromise_status_id == 1:
img = event.asset_icon_compromised
else:
img = event.asset_icon_not_compromised
if event.asset_ip:
title = "{} -{}".format(event.asset_ip, event.asset_description)
else:
title = "{}".format(event.asset_description)
label = event.asset_name
idx = f'a{event.asset_id}'
node_type = 'asset'
else:
img = 'virus-covid-solid.png'
label = event.ioc_value
title = event.ioc_description
idx = f'b{event.ioc_id}'
node_type = 'ioc'
try:
date = "{}-{}-{}".format(event.event_date.day, event.event_date.month, event.event_date.year)
except:
date = '15-05-2021'
if date not in dates:
dates['human'].append(date)
dates['machine'].append(datetime.timestamp(event.event_date))
new_node = {
'id': idx,
'label': label,
'image': '/static/assets/img/graph/' + img,
'shape': 'image',
'title': title,
'value': 1
}
if current_user.in_dark_mode:
new_node['font'] = "12px verdana white"
if not any(node['id'] == idx for node in nodes):
nodes.append(new_node)
ak = {
'node_id': idx,
'node_title': "{} - {}".format(event.event_date, event.event_title),
'node_name': label,
'node_type': node_type
}
if tmp.get(event.event_id):
tmp[event.event_id]['list'].append(ak)
else:
tmp[event.event_id] = {
'master_node': [],
'list': [ak]
}
for event_id in tmp:
for subset in itertools.combinations(tmp[event_id]['list'], 2):
if subset[0]['node_type'] == 'ioc' and subset[1]['node_type'] == 'ioc' and len(tmp[event_id]['list']) != 2:
continue
edge = {
'from': subset[0]['node_id'],
'to': subset[1]['node_id'],
'title': subset[0]['node_title'],
'dashes': subset[0]['node_type'] == 'ioc' or subset[1]['node_type'] == 'ioc'
}
edges.append(edge)
resp = {
'nodes': nodes,
'edges': edges,
'dates': dates
}
return response_success("", data=resp)