From 46f6f648a0f177499177826c4f2663e28e6477df Mon Sep 17 00:00:00 2001 From: Terrtia Date: Fri, 22 Nov 2019 15:30:11 +0100 Subject: [PATCH] chg: [Correlation UI] btc address: get related transaction input/output --- bin/lib/btc_ail.py | 53 ++++++ var/www/blueprints/correlation.py | 15 +- .../metadata_card_cryptocurrency.html | 178 ++++++++++++++++++ .../correlation/show_correlation.html | 4 +- 4 files changed, 244 insertions(+), 6 deletions(-) create mode 100755 bin/lib/btc_ail.py create mode 100644 var/www/templates/correlation/metadata_card_cryptocurrency.html diff --git a/bin/lib/btc_ail.py b/bin/lib/btc_ail.py new file mode 100755 index 00000000..c9f264bb --- /dev/null +++ b/bin/lib/btc_ail.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys +import json +import requests + +sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages/')) +import Cryptocurrency + +blockchain_all='https://blockchain.info/rawaddr' + +# pre-alpha script + +# default nb_transactions = 50 +def get_bitcoin_info(bitcoin_address, nb_transaction=50): + dict_btc = {} + set_btc_in = set() + set_btc_out = set() + req = None + try: + req = requests.get('{}/{}?limit={}'.format(blockchain_all, bitcoin_address, nb_transaction)) + jreq = req.json() + except Exception as e: + print(e) + return dict_btc + + #print(json.dumps(jreq)) + dict_btc['n_tx'] = jreq['n_tx'] + dict_btc['total_received'] = float(jreq['total_received'] / 100000000) + dict_btc['total_sent'] = float(jreq['total_sent'] / 100000000) + dict_btc['final_balance'] = float(jreq['final_balance'] / 100000000) + + for transaction in jreq['txs']: + for input in transaction['inputs']: + if input['prev_out']['addr'] != bitcoin_address: + set_btc_in.add(input['prev_out']['addr']) + for output in transaction['out']: + if output['addr'] != bitcoin_address: + set_btc_out.add(output['addr']) + + dict_btc['btc_in'] = filter_btc_seen(set_btc_in) + dict_btc['btc_out'] = filter_btc_seen(set_btc_out) + return dict_btc + +# filter btc seen in ail +def filter_btc_seen(btc_addr_set): + list_seen_btc = [] + for btc_addr in btc_addr_set: + if Cryptocurrency.cryptocurrency._exist_corelation_field('bitcoin', btc_addr): + list_seen_btc.append(btc_addr) + return list_seen_btc diff --git a/var/www/blueprints/correlation.py b/var/www/blueprints/correlation.py index f17f3637..0adcebba 100644 --- a/var/www/blueprints/correlation.py +++ b/var/www/blueprints/correlation.py @@ -18,11 +18,12 @@ import Flask_config # Import Role_Manager from Role_Manager import create_user_db, check_password_strength, check_user_role_integrity -from Role_Manager import login_admin, login_analyst +from Role_Manager import login_admin, login_analyst, login_read_only sys.path.append(os.path.join(os.environ['AIL_BIN'], 'lib')) import Correlate_object import Domain +import btc_ail sys.path.append(os.path.join(os.environ['AIL_BIN'], 'packages')) import Cryptocurrency @@ -95,11 +96,13 @@ def sanitise_correlation_objects(correlation_objects): else: return all_correlation_objects -def get_card_metadata(object_type, correlation_id, type_id=None): +def get_card_metadata(object_type, correlation_id, type_id=None, expand_card=False): card_dict = {} if object_type == 'cryptocurrency': card_dict["sparkline"] = Cryptocurrency.cryptocurrency.get_list_nb_previous_correlation_object(type_id, correlation_id, 6) card_dict["icon"] = Correlate_object.get_correlation_node_icon(object_type, type_id) + if type_id == 'bitcoin' and expand_card: + card_dict["related_btc"] = btc_ail.get_bitcoin_info(correlation_id) elif object_type == 'pgp': card_dict["sparkline"] = Pgp.pgp.get_list_nb_previous_correlation_object(type_id, correlation_id, 6) card_dict["icon"] = Correlate_object.get_correlation_node_icon(object_type, type_id) @@ -118,7 +121,7 @@ def get_card_metadata(object_type, correlation_id, type_id=None): # ============= ROUTES ============== @correlation.route('/correlation/show_correlation', methods=['GET', 'POST']) # GET + POST @login_required -@login_analyst +@login_read_only def show_correlation(): if request.method == 'POST': object_type = request.form.get('object_type') @@ -168,6 +171,8 @@ def show_correlation(): max_nodes = sanitise_nb_max_nodes(request.args.get('max_nodes')) mode = sanitise_graph_mode(request.args.get('mode')) + expand_card = request.args.get('expand_card') + correlation_names = sanitise_correlation_names(request.args.get('correlation_names')) correlation_objects = sanitise_correlation_objects(request.args.get('correlation_objects')) @@ -186,13 +191,13 @@ def show_correlation(): dict_object["metadata"] = Correlate_object.get_object_metadata(object_type, correlation_id, type_id=type_id) if type_id: dict_object["metadata"]['type_id'] = type_id - dict_object["metadata_card"] = get_card_metadata(object_type, correlation_id, type_id=type_id) + dict_object["metadata_card"] = get_card_metadata(object_type, correlation_id, type_id=type_id, expand_card=expand_card) return render_template("show_correlation.html", dict_object=dict_object, bootstrap_label=bootstrap_label) @correlation.route('/correlation/graph_node_json') @login_required -@login_analyst +@login_read_only def graph_node_json(): # # TODO: use post correlation_id = request.args.get('correlation_id') type_id = request.args.get('type_id') diff --git a/var/www/templates/correlation/metadata_card_cryptocurrency.html b/var/www/templates/correlation/metadata_card_cryptocurrency.html new file mode 100644 index 00000000..6818a55e --- /dev/null +++ b/var/www/templates/correlation/metadata_card_cryptocurrency.html @@ -0,0 +1,178 @@ +
+
+

{{ dict_object["correlation_id"] }} :

+
    +
  • +
    +
    + + + + + + + + + + + + + + + + + + + +
    Object typetypeFirst seenLast seenNb seen
    {{ dict_object["object_type"] }} + + + + {{ dict_object["metadata_card"]["icon"]["icon_text"] }} + + + {{ dict_object["metadata"]["type_id"] }} + {{ dict_object["metadata"]['first_seen'] }}{{ dict_object["metadata"]['last_seen'] }}{{ dict_object["metadata"]['nb_seen'] }}
    +
    +
    +
    +
    +
    +
  • +
+ {% if dict_object["metadata"]["type_id"] == "bitcoin" %} + {% if "related_btc" in dict_object["metadata_card"] %} +
+ + + + + + + + + + + + + + + + + + + + + +
Numbers of transactionsTotal receivedTotal sentBalanceInputs address seen in AILOuputs address seen in AIL
{{ dict_object["metadata_card"]["related_btc"]["n_tx"] }}{{ dict_object["metadata_card"]["related_btc"]["total_received"] }}{{ dict_object["metadata_card"]["related_btc"]["total_sent"] }}{{ dict_object["metadata_card"]["related_btc"]["final_balance"] }} + {% for btc_addr in dict_object["metadata_card"]["related_btc"]["btc_in"] %} + {{ btc_addr }} + {% endfor %} + + {% for btc_addr in dict_object["metadata_card"]["related_btc"]["btc_out"] %} + {{ btc_addr }} + {% endfor %} +
+
+ {% else %} + Expand Bitcoin address + {% endif %} + {% endif %} +
+
+ + + + + diff --git a/var/www/templates/correlation/show_correlation.html b/var/www/templates/correlation/show_correlation.html index bcf4d19a..de74f1d3 100644 --- a/var/www/templates/correlation/show_correlation.html +++ b/var/www/templates/correlation/show_correlation.html @@ -90,8 +90,10 @@
- {% if dict_object["object_type"] in ["pgp", "cryptocurrency"] %} + {% 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" %}