Merge pull request #450 from CIRCL/tags_v2

Tags v2
This commit is contained in:
Thirion Aurélien 2020-01-14 16:16:34 +01:00 committed by GitHub
commit 83ae6a0a6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 174 additions and 23 deletions

View file

@ -55,7 +55,7 @@ def exist_object(object_type, correlation_id, type_id=None):
return Pgp.pgp._exist_corelation_field(type_id, correlation_id) return Pgp.pgp._exist_corelation_field(type_id, correlation_id)
elif object_type == 'cryptocurrency': elif object_type == 'cryptocurrency':
return Cryptocurrency.cryptocurrency._exist_corelation_field(type_id, correlation_id) return Cryptocurrency.cryptocurrency._exist_corelation_field(type_id, correlation_id)
elif object_type == 'screenshot': elif object_type == 'screenshot' or object_type == 'image':
return Screenshot.exist_screenshot(correlation_id) return Screenshot.exist_screenshot(correlation_id)
else: else:
return False return False
@ -63,7 +63,7 @@ def exist_object(object_type, correlation_id, type_id=None):
def get_object_metadata(object_type, correlation_id, type_id=None): def get_object_metadata(object_type, correlation_id, type_id=None):
if object_type == 'domain': if object_type == 'domain':
return Domain.Domain(correlation_id).get_domain_metadata(tags=True) return Domain.Domain(correlation_id).get_domain_metadata(tags=True)
elif object_type == 'paste': elif object_type == 'paste' or object_type == 'item':
return Item.get_item({"id": correlation_id, "date": True, "date_separator": True, "tags": True})[0] return Item.get_item({"id": correlation_id, "date": True, "date_separator": True, "tags": True})[0]
elif object_type == 'decoded': elif object_type == 'decoded':
return Decoded.get_decoded_metadata(correlation_id, nb_seen=True, size=True, file_type=True) return Decoded.get_decoded_metadata(correlation_id, nb_seen=True, size=True, file_type=True)
@ -71,7 +71,7 @@ def get_object_metadata(object_type, correlation_id, type_id=None):
return Pgp.pgp.get_metadata(type_id, correlation_id) return Pgp.pgp.get_metadata(type_id, correlation_id)
elif object_type == 'cryptocurrency': elif object_type == 'cryptocurrency':
return Cryptocurrency.cryptocurrency.get_metadata(type_id, correlation_id) return Cryptocurrency.cryptocurrency.get_metadata(type_id, correlation_id)
elif object_type == 'screenshot': elif object_type == 'screenshot' or object_type == 'image':
return Screenshot.get_metadata(correlation_id) return Screenshot.get_metadata(correlation_id)
def get_object_correlation(object_type, value, correlation_names, correlation_objects, requested_correl_type=None): def get_object_correlation(object_type, value, correlation_names, correlation_objects, requested_correl_type=None):
@ -85,7 +85,7 @@ def get_object_correlation(object_type, value, correlation_names, correlation_ob
return Pgp.pgp.get_correlation_all_object(requested_correl_type, value, correlation_objects=correlation_objects) return Pgp.pgp.get_correlation_all_object(requested_correl_type, value, correlation_objects=correlation_objects)
elif object_type == 'cryptocurrency': elif object_type == 'cryptocurrency':
return Cryptocurrency.cryptocurrency.get_correlation_all_object(requested_correl_type, value, correlation_objects=correlation_objects) return Cryptocurrency.cryptocurrency.get_correlation_all_object(requested_correl_type, value, correlation_objects=correlation_objects)
elif object_type == 'screenshot': elif object_type == 'screenshot' or object_type == 'image':
return Screenshot.get_screenshot_correlated_object(value, correlation_objects) return Screenshot.get_screenshot_correlated_object(value, correlation_objects)
return {} return {}
@ -145,7 +145,7 @@ def get_correlation_node_icon(correlation_name, correlation_type=None, value=Non
else: else:
icon_text = '\uf249' icon_text = '\uf249'
elif correlation_name == 'screenshot': elif correlation_name == 'screenshot' or correlation_name == 'image':
node_color = '#E1F5DF' node_color = '#E1F5DF'
icon_text = '\uf03e' icon_text = '\uf03e'
@ -181,7 +181,9 @@ def get_item_url(correlation_name, value, correlation_type=None):
elif correlation_name == 'decoded': elif correlation_name == 'decoded':
endpoint = 'correlation.show_correlation' endpoint = 'correlation.show_correlation'
url = url_for(endpoint, object_type="decoded", correlation_id=value) url = url_for(endpoint, object_type="decoded", correlation_id=value)
elif correlation_name == 'screenshot': elif correlation_name == 'screenshot': ### # TODO: remove me
endpoint = 'correlation.show_correlation'
elif correlation_name == 'image':
endpoint = 'correlation.show_correlation' endpoint = 'correlation.show_correlation'
url = url_for(endpoint, object_type="screenshot", correlation_id=value) url = url_for(endpoint, object_type="screenshot", correlation_id=value)
elif correlation_name == 'domain': elif correlation_name == 'domain':

View file

@ -9,6 +9,7 @@ import redis
sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages')) sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages'))
import Item import Item
import Date import Date
import Tag
import ConfigLoader import ConfigLoader
@ -33,8 +34,13 @@ def exist_screenshot(sha256_string):
def get_metadata(sha256_string): def get_metadata(sha256_string):
metadata_dict = {} metadata_dict = {}
metadata_dict['img'] = get_screenshot_rel_path(sha256_string) metadata_dict['img'] = get_screenshot_rel_path(sha256_string)
metadata_dict['tags'] = get_screenshot_tags(sha256_string)
metadata_dict['is_tags_safe'] = Tag.is_tags_safe(metadata_dict['tags'])
return metadata_dict return metadata_dict
def get_screenshot_tags(sha256_string):
return Tag.get_obj_tag(sha256_string)
def get_screenshot_items_list(sha256_string): def get_screenshot_items_list(sha256_string):
res = r_serv_onion.smembers('screenshot:{}'.format(sha256_string)) res = r_serv_onion.smembers('screenshot:{}'.format(sha256_string))

View file

@ -355,7 +355,7 @@ def api_add_obj_tags(tags=[], galaxy_tags=[], object_id=None, object_type="item"
return ({'status': 'error', 'reason': 'object_id id not found'}, 404) return ({'status': 'error', 'reason': 'object_id id not found'}, 404)
if not tags and not galaxy_tags: if not tags and not galaxy_tags:
return ({'status': 'error', 'reason': 'Tags or Galaxy not specified'}, 400) return ({'status': 'error', 'reason': 'Tags or Galaxy not specified'}, 400)
if object_type not in ('item', 'domain'): # # TODO: put me in another file if object_type not in ('item', 'domain', 'image'): # # TODO: put me in another file
return ({'status': 'error', 'reason': 'Incorrect object_type'}, 400) return ({'status': 'error', 'reason': 'Incorrect object_type'}, 400)
# remove empty tags # remove empty tags

View file

@ -23,12 +23,14 @@ from Role_Manager import login_admin, login_analyst, login_read_only
sys.path.append(os.path.join(os.environ['AIL_BIN'], 'lib')) sys.path.append(os.path.join(os.environ['AIL_BIN'], 'lib'))
import Correlate_object import Correlate_object
import Domain import Domain
import Screenshot
import btc_ail import btc_ail
sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages')) sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages'))
import Cryptocurrency import Cryptocurrency
import Pgp import Pgp
import Decoded import Decoded
import Tag
bootstrap_label = Flask_config.bootstrap_label bootstrap_label = Flask_config.bootstrap_label
vt_enabled = Flask_config.vt_enabled vt_enabled = Flask_config.vt_enabled
@ -114,6 +116,8 @@ def get_card_metadata(object_type, correlation_id, type_id=None, expand_card=Fal
elif object_type == 'domain': elif object_type == 'domain':
card_dict["icon"] = Correlate_object.get_correlation_node_icon(object_type, value=correlation_id) card_dict["icon"] = Correlate_object.get_correlation_node_icon(object_type, value=correlation_id)
card_dict["tags"] = Domain.get_domain_tags(correlation_id) card_dict["tags"] = Domain.get_domain_tags(correlation_id)
elif object_type == 'screenshot':
card_dict["add_tags_modal"] = Tag.get_modal_add_tags(correlation_id, object_type='image')
elif object_type == 'paste': elif object_type == 'paste':
card_dict["icon"] = Correlate_object.get_correlation_node_icon(object_type, value=correlation_id) card_dict["icon"] = Correlate_object.get_correlation_node_icon(object_type, value=correlation_id)
return card_dict return card_dict
@ -179,6 +183,10 @@ def show_correlation():
correlation_names = sanitise_correlation_names(request.args.get('correlation_names')) correlation_names = sanitise_correlation_names(request.args.get('correlation_names'))
correlation_objects = sanitise_correlation_objects(request.args.get('correlation_objects')) correlation_objects = sanitise_correlation_objects(request.args.get('correlation_objects'))
# # TODO: remove me, rename screenshot to image
if object_type == 'image':
object_type == 'screenshot'
# check if correlation_id exist # check if correlation_id exist
if not Correlate_object.exist_object(object_type, correlation_id, type_id=type_id): if not Correlate_object.exist_object(object_type, correlation_id, type_id=type_id):
abort(404) # return 404 abort(404) # return 404

View file

@ -0,0 +1,127 @@
<link href="{{ url_for('static', filename='css/tags.css') }}" rel="stylesheet" type="text/css" />
<script src="{{ url_for('static', filename='js/tags.js') }}"></script>
{% with modal_add_tags=dict_object['metadata_card']['add_tags_modal']%}
{% include 'modals/add_tags.html' %}
{% endwith %}
{% include 'modals/edit_tag.html' %}
<div class="card my-3">
<div class="card-header">
<h4 class="text-secondary">{{ dict_object["correlation_id"] }} :</h4>
<ul class="list-group mb-2">
<li class="list-group-item py-0">
<div id="accordionscreenshot" class="my-3">
<div class="card">
<div class="card-header py-1" id="headingScreenshot">
<div class="row">
<div class="col-11">
<div class="mt-2">
<i class="far fa-image"></i> Show Screenshot&nbsp;&nbsp;
</div>
</div>
<div class="col-1">
<button class="btn btn-link collapsed rotate" data-toggle="collapse" data-target="#collapseScreenshot" aria-expanded="false" aria-controls="collapseScreenshot">
<i class="fas fa-chevron-circle-down"></i>
</button>
</div>
</div>
</div>
<div id="collapseScreenshot" class="collapse" aria-labelledby="headingScreenshot" data-parent="#accordionscreenshot">
<div class="card-body">
<div class="card my-2" style="background-color:#ecf0f1;">
<div class="card-body py-2">
<div class="row">
<div class="col-md-3 text-center">
<button class="btn {%if dict_object['metadata']['is_tags_safe']%}btn-primary{%else%}btn-danger{%endif%}" onclick="blocks.value=0;pixelate();">
<i class="fas fa-eye-slash"></i>
<span class="label-icon">Hide</span>
</button>
</div>
<div class="col-md-6">
<input class="custom-range mt-2" id="blocks" type="range" min="1" max="50" value="{%if dict_object['metadata']['is_tags_safe']%}13{%else%}0{%endif%}">
</div>
<div class="col-md-3 text-center">
<button class="btn {%if dict_object['metadata']['is_tags_safe']%}btn-primary{%else%}btn-danger{%endif%}" onclick="blocks.value=50;pixelate();">
{%if dict_object['metadata']['is_tags_safe']%}
<i class="fas fa-plus-square"></i>
{%else%}
<i class="fas fa-exclamation-triangle"></i>
{%endif%}
<span class="label-icon">Full resolution</span>
</button>
</div>
</div>
</div>
</div>
<canvas id="canvas" style="width:100%;"></canvas>
</div>
</div>
</div>
</div>
</li>
<li class="list-group-item py-0">
<br>
<div class="mb-3">
Tags:
{% for tag in dict_object["metadata"]['tags'] %}
<button class="btn btn-{{ bootstrap_label[loop.index0 % 5] }}" data-toggle="modal" data-target="#edit_tags_modal"
data-tagid="{{ tag }}" data-objtype="image" data-objid="{{ dict_object["correlation_id"] }}">
{{ tag }}
</button>
{% endfor %}
<button type="button" class="btn btn-light" data-toggle="modal" data-target="#add_tags_modal">
<i class="far fa-plus-square"></i>
</button>
</div>
</li>
</ul>
</div>
</div>
<script>
var ctx = canvas.getContext('2d'), img = new Image();
/// turn off image smoothing
ctx.webkitImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
img.onload = pixelate;
img.addEventListener("error", img_error);
var draw_img = false;
img.src = "{{ url_for('showsavedpastes.screenshot', filename=dict_object['metadata']['img']) }}";
function pixelate() {
/// use slider value
if( blocks.value == 50 ){
size = 1;
} else {
var size = (blocks.value) * 0.01;
}
canvas.width = img.width;
canvas.height = img.height;
/// cache scaled width and height
w = canvas.width * size;
h = canvas.height * size;
/// draw original image to the scaled size
ctx.drawImage(img, 0, 0, w, h);
/// pixelated
ctx.drawImage(canvas, 0, 0, w, h, 0, 0, canvas.width, canvas.height);
}
blocks.addEventListener('change', pixelate, false);
function img_error() {
img.onerror=null;
img.src="{{ url_for('static', filename='image/AIL.png') }}";
blocks.value = 50;
pixelate;
}
</script>

View file

@ -53,7 +53,7 @@
pointer-events: auto; pointer-events: auto;
} }
div.tooltip { div.tooltip_graph {
position: absolute; position: absolute;
text-align: center; text-align: center;
padding: 2px; padding: 2px;
@ -99,6 +99,8 @@
{% include 'correlation/metadata_card_decoded.html' %} {% include 'correlation/metadata_card_decoded.html' %}
{% elif dict_object["object_type"] == "domain" %} {% elif dict_object["object_type"] == "domain" %}
{% include 'correlation/metadata_card_domain.html' %} {% include 'correlation/metadata_card_domain.html' %}
{% elif dict_object["object_type"] == "screenshot" %}
{% include 'correlation/metadata_card_screenshot.html' %}
{% elif dict_object["object_type"] == "paste" %} {% elif dict_object["object_type"] == "paste" %}
{% include 'correlation/metadata_card_paste.html' %} {% include 'correlation/metadata_card_paste.html' %}
{% endif %} {% endif %}
@ -127,18 +129,6 @@
</div> </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">&times;</span>
</button>
</div>
<div class="toast-body">
Hello, world! This is a toast message.
</div>
</div>
</div> </div>
<div class="col-xl-2"> <div class="col-xl-2">
@ -310,7 +300,7 @@ var zoom = d3.zoom()
var color = d3.scaleOrdinal(d3.schemeCategory10); var color = d3.scaleOrdinal(d3.schemeCategory10);
var div = d3.select("body").append("div") var div = d3.select("body").append("div")
.attr("class", "tooltip") .attr("class", "tooltip_graph")
.style("opacity", 0); .style("opacity", 0);
var simulation = d3.forceSimulation() var simulation = d3.forceSimulation()

View file

@ -46,6 +46,8 @@
<th>last check</th> <th>last check</th>
<th style="max-width: 800px;">Domain</th> <th style="max-width: 800px;">Domain</th>
<th>status</th> <th>status</th>
{%elif dict_tagged["object_type"]=="image"%}
<th style="max-width: 800px;">Image</th>
{%endif%} {%endif%}
</tr> </tr>
</thead> </thead>
@ -63,7 +65,7 @@
</a> </a>
<div class="mb-2"> <div class="mb-2">
{% for tag in dict_obj['tags'] %} {% for tag in dict_obj['tags'] %}
<a href="{{ url_for('Tags.Tags_page') }}?ltags={{ tag }}"> <a href="{{ url_for('tags_ui.get_obj_by_tags') }}?object_type={{dict_tagged['object_type']}}&ltags={{ tag }}">
<span class="badge badge-{{ bootstrap_label[loop.index0 % 5] }}">{{ tag }}</span> <span class="badge badge-{{ bootstrap_label[loop.index0 % 5] }}">{{ tag }}</span>
</a> </a>
{% endfor %} {% endfor %}
@ -85,8 +87,24 @@
</tr> </tr>
{% endfor %} {% endfor %}
{%elif dict_tagged["object_type"]=="image"%}
{% for dict_obj in dict_tagged["tagged_obj"] %}
<tr>
<td class="pb-0">
<a target="_blank" href="{{ url_for('correlation.show_correlation') }}?object_type=screenshot&correlation_id={{dict_obj['id']}}" class="text-secondary">
<div style="line-height:0.9;">{{ dict_obj['id'] }}</div>
</a>
<div class="mb-2">
{% for tag in dict_obj['tags'] %}
<a href="{{ url_for('tags_ui.get_obj_by_tags') }}?object_type={{dict_tagged['object_type']}}&ltags={{ tag }}">
<span class="badge badge-{{ bootstrap_label[loop.index0 % 5] }}">{{ tag }}</span>
</a>
{% endfor %}
</div>
</td>
</tr>
{% endfor %}
{% endif %} {% endif %}
</tbody> </tbody>
</table> </table>