mirror of https://github.com/CIRCL/AIL-framework
547 lines
17 KiB
HTML
547 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
|
|
<title>AIL - framework</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">
|
|
|
|
<!-- JS -->
|
|
<script src="{{ url_for('static', filename='js/jquery.js')}}"></script>
|
|
<script src="{{ url_for('static', filename='js/helper.js')}}"></script>
|
|
<script src="{{ url_for('static', filename='js/popper.min.js')}}"></script>
|
|
<script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script>
|
|
<script language="javascript" src="{{ url_for('static', filename='js/d3.min.js') }}"></script>
|
|
|
|
<style>
|
|
.icon_legend {
|
|
color: #0c5460;
|
|
background-color: #bee5eb;
|
|
}
|
|
|
|
line.link {
|
|
stroke: #666;
|
|
}
|
|
line.link:hover{
|
|
stroke: red;
|
|
stroke-width: 2px;
|
|
}
|
|
.node {
|
|
pointer-events: all;
|
|
}
|
|
|
|
circle {
|
|
stroke: none;
|
|
}
|
|
|
|
.graph_text_node {
|
|
font: 8px sans-serif;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.graph_node_icon {
|
|
pointer-events: none;
|
|
}
|
|
|
|
.node text {
|
|
font: 8px sans-serif;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
div.tooltip {
|
|
position: absolute;
|
|
text-align: center;
|
|
padding: 2px;
|
|
font: 12px sans-serif;
|
|
background: #ebf4fb;
|
|
border: 2px solid #b7ddf2;
|
|
border-radius: 8px;
|
|
pointer-events: none;
|
|
color: #000000;
|
|
}
|
|
|
|
.graph_panel {
|
|
padding: unset;
|
|
}
|
|
|
|
.line_graph {
|
|
fill: none;
|
|
stroke: steelblue;
|
|
stroke-width: 2px;
|
|
stroke-linejoin: round;
|
|
stroke-linecap: round;
|
|
stroke-width: 1.5;
|
|
/*attr('stroke', '#bcbd22').*/
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
{% include 'nav_bar.html' %}
|
|
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
|
|
{% include 'decoded/menu_sidebar.html' %}
|
|
|
|
<div class="col-12 col-lg-10" id="core_content">
|
|
|
|
{% if dict_object["object_type"] == "pgp" %}
|
|
{% include 'correlation/metadata_card_pgp.html' %}
|
|
{% elif dict_object["object_type"] == "cryptocurrency" %}
|
|
{% include 'correlation/metadata_card_cryptocurrency.html' %}
|
|
{% elif dict_object["object_type"] == "decoded" %}
|
|
{% include 'correlation/metadata_card_decoded.html' %}
|
|
{% elif dict_object["object_type"] == "domain" %}
|
|
{% include 'correlation/metadata_card_domain.html' %}
|
|
{% elif dict_object["object_type"] == "paste" %}
|
|
{% include 'correlation/metadata_card_paste.html' %}
|
|
{% endif %}
|
|
|
|
<div class="row">
|
|
<div class="col-xl-10">
|
|
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-project-diagram"></i> Graph
|
|
<span class="float-right">
|
|
<button class="btn btn-primary py-1" onclick="resize_graph();">
|
|
<i class="fas fa-sync"></i> Resize Graph
|
|
</button>
|
|
</span>
|
|
</div>
|
|
<div class="card-body graph_panel">
|
|
<div id="graph_loading" class="ml-3 mt-3">
|
|
<div class="spinner-border text-secondary" role="status">
|
|
<span class="sr-only">Loading...</span>
|
|
</div>
|
|
<span>Loading...</span>
|
|
</div>
|
|
<div id="graph">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div role="alert" aria-live="assertive" aria-atomic="true" class="toast" data-autohide="false">
|
|
<div class="toast-header">
|
|
<strong class="mr-auto">Bootstrap</strong>
|
|
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="toast-body">
|
|
Hello, world! This is a toast message.
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="col-xl-2">
|
|
|
|
<div class="card mb-3">
|
|
<div class="card-body text-center px-0 py-0">
|
|
|
|
<ul class="list-group">
|
|
<li class="list-group-item list-group-item-info">Select Correlation</i></li>
|
|
<li class="list-group-item text-left">
|
|
|
|
<form action="{{ url_for('correlation.show_correlation') }}" method="post">
|
|
<input type="hidden" id="object_type" name="object_type" value="{{ dict_object["object_type"] }}">
|
|
<input type="hidden" id="type_id" name="type_id" value="{{ dict_object["metadata"]["type_id"] }}">
|
|
<input type="hidden" id="correlation_id" name="correlation_id" value="{{ dict_object["correlation_id"] }}">
|
|
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" value="True" id="CryptocurrencyCheck" name="CryptocurrencyCheck" {%if "cryptocurrency" in dict_object["correlation_names"]%}checked{%endif%}>
|
|
<label class="form-check-label" for="CryptocurrencyCheck">Cryptocurrency</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" value="True" id="DecodedCheck" name="DecodedCheck" {%if "decoded" in dict_object["correlation_names"]%}checked{%endif%}>
|
|
<label class="form-check-label" for="DecodedCheck">Decoded</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" value="True" id="ScreenshotCheck" name="ScreenshotCheck" {%if "screenshot" in dict_object["correlation_names"]%}checked{%endif%}>
|
|
<label class="form-check-label" for="ScreenshotCheck">Screenshot</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" value="True" id="PgpCheck" name="PgpCheck" {%if "pgp" in dict_object["correlation_names"]%}checked{%endif%}>
|
|
<label class="form-check-label" for="PgpCheck">PGP</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" value="True" id="DomainCheck" name="DomainCheck" {%if "domain" in dict_object["correlation_objects"]%}checked{%endif%}>
|
|
<label class="form-check-label" for="DomainCheck">Domain</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" value="True" id="PasteCheck" name="PasteCheck" {%if "paste" in dict_object["correlation_objects"]%}checked{%endif%}>
|
|
<label class="form-check-label" for="PasteCheck">Paste</label>
|
|
</div>
|
|
|
|
</li>
|
|
<li class="list-group-item text-left">
|
|
<div class="d-flex mt-1">
|
|
Union
|
|
<div class="custom-control custom-switch">
|
|
<input class="custom-control-input" type="checkbox" name="mode" value="True" id="mode" {%if dict_object["mode"]=="inter"%}checked{%endif%}>
|
|
<label class="custom-control-label" for="mode">Intersection</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li class="list-group-item text-left">
|
|
|
|
<div class="form-group">
|
|
<label for="max_nb_nodes_in">Max number of nodes:</label>
|
|
<input class="form-control" type="number" value="{{dict_object["max_nodes"]}}" min="2" id="max_nb_nodes_in" name="max_nb_nodes_in">
|
|
</div>
|
|
|
|
<div class="text-center">
|
|
<input class="btn btn-primary" type="submit" value="Redraw Graph">
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="list-group">
|
|
<li class="list-group-item list-group-item-info"><i class="fas fa-info-circle fa-2x"></i></li>
|
|
<li class="list-group-item text-left">
|
|
<p>Double click on a node to open this object<br><br>
|
|
<svg height="26" width="26">
|
|
<g class="nodes">
|
|
<circle cx="13" cy="13" r="13" fill="orange"></circle>
|
|
</g>
|
|
</svg>
|
|
Current Correlation<br>
|
|
</p>
|
|
</li>
|
|
</ul>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-xl-10">
|
|
|
|
{% include 'correlation/legend_graph_correlation.html' %}
|
|
|
|
</div>
|
|
</div>
|
|
|
|
{% if dict_object["object_type"] in ["decoded", "pgp", "cryptocurrency"] %}
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<i class="fas fa-chart-bar"></i> Graph
|
|
</div>
|
|
<div class="panel-body ">
|
|
<div id="graph_line">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
var all_graph = {};
|
|
$(document).ready(function(){
|
|
$("#page-Decoded").addClass("active");
|
|
|
|
all_graph.node_graph = create_graph("{{ url_for('correlation.graph_node_json') }}?correlation_id={{ dict_object["correlation_id"] }}&object_type={{ dict_object["object_type"] }}&mode={{ dict_object["mode"] }}&correlation_names={{ dict_object["correlation_names_str"] }}&correlation_objects={{ dict_object["correlation_objects_str"] }}&max_nodes={{dict_object["max_nodes"]}}{% if 'type_id' in dict_object["metadata"] %}&type_id={{ dict_object["metadata"]["type_id"] }}{% endif %}");
|
|
{% if dict_object["object_type"] == "pgp" %}
|
|
all_graph.line_chart = create_line_chart('graph_line', "{{ url_for('hashDecoded.pgpdump_graph_line_json') }}?type_id={{dict_object["metadata"]["type_id"]}}&key_id={{dict_object["correlation_id"]}}");
|
|
{% elif dict_object["object_type"] == "cryptocurrency" %}
|
|
all_graph.line_chart = create_line_chart('graph_line', "{{ url_for('hashDecoded.cryptocurrency_graph_line_json') }}?type_id={{dict_object["metadata"]["type_id"]}}&key_id={{dict_object["correlation_id"]}}");
|
|
{% elif dict_object["object_type"] == "decoded" %}
|
|
all_graph.line_chart = create_line_chart('graph_line', "{{ url_for('hashDecoded.hash_graph_line_json') }}?hash={{dict_object["correlation_id"]}}");
|
|
{% endif %}
|
|
all_graph.onResize();
|
|
});
|
|
|
|
$(window).on("resize", function() {
|
|
all_graph.onResize();
|
|
});
|
|
|
|
function toggle_sidebar(){
|
|
if($('#nav_menu').is(':visible')){
|
|
$('#nav_menu').hide();
|
|
$('#side_menu').removeClass('border-right')
|
|
$('#side_menu').removeClass('col-lg-2')
|
|
$('#core_content').removeClass('col-lg-10')
|
|
}else{
|
|
$('#nav_menu').show();
|
|
$('#side_menu').addClass('border-right')
|
|
$('#side_menu').addClass('col-lg-2')
|
|
$('#core_content').addClass('col-lg-10')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
function resize_graph() {
|
|
zoom.translateTo(svg_node, 200, 200);
|
|
zoom.scaleTo(svg_node, 2);
|
|
}
|
|
|
|
</script>
|
|
|
|
<script>
|
|
var width = 400,
|
|
height = 400;
|
|
|
|
var link;
|
|
|
|
var zoom = d3.zoom()
|
|
.scaleExtent([.2, 10])
|
|
.on("zoom", zoomed);
|
|
|
|
// Loading:
|
|
//$("#graph_loading").show()
|
|
|
|
//var transform = d3.zoomIdentity;
|
|
|
|
var color = d3.scaleOrdinal(d3.schemeCategory10);
|
|
|
|
var div = d3.select("body").append("div")
|
|
.attr("class", "tooltip")
|
|
.style("opacity", 0);
|
|
|
|
var simulation = d3.forceSimulation()
|
|
.force("link", d3.forceLink().id(function(d) { return d.id; }))
|
|
.force("charge", d3.forceManyBody())
|
|
.force("center", d3.forceCenter(width / 2, height / 2));
|
|
//.on("tick", ticked);
|
|
|
|
var svg_node = d3.select("#graph").append("svg")
|
|
.attr("id", "graph_div")
|
|
.attr("width", width)
|
|
.attr("height", height)
|
|
.call(d3.zoom().scaleExtent([1, 8]).on("zoom", zoomed))
|
|
.on("dblclick.zoom", null)
|
|
|
|
var container_graph = svg_node.append("g");
|
|
//.attr("transform", "translate(40,0)")
|
|
//.attr("transform", "scale(2)");
|
|
|
|
|
|
function create_graph(url){
|
|
|
|
d3.json(url)
|
|
.then(function(data){
|
|
|
|
link = container_graph.append("g")
|
|
.selectAll("line")
|
|
.data(data.links)
|
|
.enter().append("line")
|
|
.attr("class", "link");
|
|
//.attr("stroke-width", function(d) { return Math.sqrt(d.value); })
|
|
|
|
var node = container_graph.selectAll(".node")
|
|
.data(data.nodes)
|
|
.enter().append("g")
|
|
.attr("class", "nodes")
|
|
.on("dblclick", doubleclick)
|
|
.on("click", click)
|
|
.on("mouseover", mouseovered)
|
|
.on("mouseout", mouseouted)
|
|
.call(d3.drag()
|
|
.on("start", drag_start)
|
|
.on("drag", dragged)
|
|
.on("end", drag_end));
|
|
|
|
|
|
node.append("circle")
|
|
.attr("r", function(d) {
|
|
return (d.style.node_radius);})
|
|
.attr("fill", function(d) {
|
|
return d.style.node_color;});
|
|
|
|
node.append('text')
|
|
.attr('text-anchor', 'middle')
|
|
.attr('dominant-baseline', 'central')
|
|
.attr("class", function(d) {
|
|
return "graph_node_icon " + d.style.icon_class
|
|
})
|
|
.attr('font-size', '8px' )
|
|
.attr('pointer-events', 'none')
|
|
.text(function(d) {
|
|
//if(d.hash){
|
|
return d.style.icon_text
|
|
//}
|
|
});
|
|
|
|
zoom.translateTo(svg_node, 200, 200);
|
|
zoom.scaleTo(svg_node, 2);
|
|
|
|
/* node.append("text")
|
|
.attr("dy", 3)
|
|
.attr("dx", 7)
|
|
.attr("class", "graph_text_node")
|
|
//.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
|
|
.text(function(d) { return d.id; });*/
|
|
|
|
simulation
|
|
.nodes(data.nodes)
|
|
.on("tick", ticked);
|
|
|
|
simulation.force("link")
|
|
.links(data.links);
|
|
|
|
function ticked() {
|
|
link
|
|
.attr("x1", function(d) { return d.source.x; })
|
|
.attr("y1", function(d) { return d.source.y; })
|
|
.attr("x2", function(d) { return d.target.x; })
|
|
.attr("y2", function(d) { return d.target.y; });
|
|
|
|
/*node
|
|
.attr("cx", function(d) { return d.x; })
|
|
.attr("cy", function(d) { return d.y; });*/
|
|
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
|
|
}
|
|
|
|
// Loading ...
|
|
$("#graph_loading").remove();
|
|
|
|
})
|
|
.catch(function(error) {
|
|
$("#graph_loading").remove()
|
|
svg_node.remove();
|
|
d3.select("#graph").append("div")
|
|
.text(error);
|
|
});
|
|
}
|
|
|
|
function zoomed() {
|
|
container_graph.attr("transform", d3.event.transform);
|
|
}
|
|
|
|
function doubleclick (d) {
|
|
window.open(d.url, '_blank');
|
|
}
|
|
|
|
function click (d) {
|
|
console.log('clicked')
|
|
}
|
|
|
|
function drag_start(d) {
|
|
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
|
|
d.fx = d.x;
|
|
d.fy = d.y;
|
|
}
|
|
|
|
function dragged(d) {
|
|
d.fx = d3.event.x;
|
|
d.fy = d3.event.y;
|
|
}
|
|
|
|
function drag_end(d) {
|
|
if (!d3.event.active) simulation.alphaTarget(0);
|
|
d.fx = d.x;
|
|
d.fy = d.y;
|
|
}
|
|
|
|
function mouseovered(d) {
|
|
|
|
var d3_pageX = d3.event.pageX;
|
|
var d3_pageY = d3.event.pageY;
|
|
|
|
if (d.popover) {
|
|
div.html(d.popover)
|
|
.style("left", (d3_pageX) + "px")
|
|
.style("top", (d3_pageY - 28) + "px");
|
|
|
|
div.transition()
|
|
.duration(200)
|
|
.style("opacity", .9);
|
|
} else {
|
|
|
|
var pop_header = "<div class=\"card text-white\" style=\"max-width: 25rem;\"><div class=\"card-header bg-dark pb-0 border-white\"><h6>"+ sanitize_text(d.text) +"</h6></div>"
|
|
var spinner = "<div class=\"card-body bg-dark pt-0\"><div class=\"spinner-border text-warning\" role=\"status\"></div> Loading...</div>"
|
|
|
|
div.html(pop_header + spinner)
|
|
.style("left", (d3_pageX) + "px")
|
|
.style("top", (d3_pageY - 28) + "px");
|
|
|
|
div.transition()
|
|
.duration(200)
|
|
.style("opacity", .9);
|
|
|
|
$.getJSON("{{ url_for('correlation.get_description') }}?object_id="+ d.id,
|
|
function(data){
|
|
var desc = pop_header + "<div class=\"card-body bg-dark pb-1 pt-2\"><dl class=\"row py-0 my-0\">"
|
|
Object.keys(data).forEach(function(key) {
|
|
if (key=="status") {
|
|
desc = desc + "<dt class=\"col-sm-3 px-0\">status</dt><dd class=\"col-sm-9 px-0\"><div class=\"badge badge-pill badge-light flex-row-reverse\" style=\"color:"
|
|
if (data["status"]) {
|
|
desc = desc + "Green"
|
|
} else {
|
|
desc = desc + "Red"
|
|
}
|
|
desc = desc + ";\"><i class=\"fas "
|
|
if (data["status"]) {
|
|
desc = desc + "fa-check-circle\"></i>UP"
|
|
} else {
|
|
desc = desc + "fa-times-circle\"></i>DOWN"
|
|
}
|
|
desc = desc + "</div></dd>"
|
|
} else if (key!="tags" && key!="id" && key!="img") {
|
|
desc = desc + "<dt class=\"col-sm-3 px-0\">" + sanitize_text(key) + "</dt><dd class=\"col-sm-9 px-0\">" + sanitize_text(data[key]) + "</dd>"
|
|
}
|
|
});
|
|
desc = desc + "</dl>"
|
|
|
|
if (data["img"]) {
|
|
desc = desc + "<img src={{ url_for('showsavedpastes.screenshot', filename="") }}" + data["img"] +" class=\"img-thumbnail\" />";
|
|
}
|
|
|
|
if (data["tags"]) {
|
|
data["tags"].forEach(function(tag) {
|
|
desc = desc + "<span class=\"badge badge-warning\">"+ sanitize_text(tag) +"</span>";
|
|
});
|
|
}
|
|
|
|
desc = desc + "</div>"
|
|
div.html(desc)
|
|
.style("left", (d3_pageX) + "px")
|
|
.style("top", (d3_pageY - 28) + "px");
|
|
d.popover = desc
|
|
})
|
|
.fail(function(error) {
|
|
desc = pop_header + "<div class=\"card-body bg-dark pt-0\"><i class=\"fas fa-3x fa-times text-danger\"></i>"+ error.statusText +"</div>"
|
|
div.html(desc)
|
|
.style("left", (d3_pageX) + "px")
|
|
.style("top", (d3_pageY - 28) + "px");
|
|
});
|
|
}
|
|
}
|
|
|
|
function mouseouted() {
|
|
div.transition()
|
|
.duration(500)
|
|
.style("opacity", 0);
|
|
|
|
link.style("stroke", "#666");
|
|
}
|
|
|
|
all_graph.onResize = function () {
|
|
var aspect = 1000 / 500, all_graph = $("#graph_div");
|
|
var targetWidth = all_graph.parent().width();
|
|
all_graph.attr("width", targetWidth);
|
|
all_graph.attr("height", targetWidth / aspect);
|
|
}
|
|
|
|
window.all_graph = all_graph;
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|