From 5350003e3af3aa2e66afc3495b876b4a7cbefcfd Mon Sep 17 00:00:00 2001 From: aaronkaplan Date: Mon, 25 Nov 2019 18:52:39 +0100 Subject: [PATCH] initial version of the ransomcoindb expansion module --- misp_modules/modules/expansion/__init__.py | 2 +- .../expansion/_ransomcoindb/ransomcoindb.py | 92 +++++++++++++++++++ .../modules/expansion/ransomcoindb.py | 62 +++++++++++++ 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100755 misp_modules/modules/expansion/_ransomcoindb/ransomcoindb.py create mode 100644 misp_modules/modules/expansion/ransomcoindb.py diff --git a/misp_modules/modules/expansion/__init__.py b/misp_modules/modules/expansion/__init__.py index 669fb8c..892f3bf 100644 --- a/misp_modules/modules/expansion/__init__.py +++ b/misp_modules/modules/expansion/__init__.py @@ -15,4 +15,4 @@ __all__ = ['cuckoo_submit', 'vmray_submit', 'bgpranking', 'circl_passivedns', 'c 'qrcode', 'ocr_enrich', 'pdf_enrich', 'docx_enrich', 'xlsx_enrich', 'pptx_enrich', 'ods_enrich', 'odt_enrich', 'joesandbox_submit', 'joesandbox_query', 'urlhaus', 'virustotal_public', 'apiosintds', 'urlscan', 'securitytrails', - 'assemblyline_submit', 'assemblyline_query'] + 'assemblyline_submit', 'assemblyline_query', 'ransomcoindb'] diff --git a/misp_modules/modules/expansion/_ransomcoindb/ransomcoindb.py b/misp_modules/modules/expansion/_ransomcoindb/ransomcoindb.py new file mode 100755 index 0000000..7225c47 --- /dev/null +++ b/misp_modules/modules/expansion/_ransomcoindb/ransomcoindb.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python + +import requests +import logging +import os +import pprint + +copyright = """ + Copyright 2019 (C) by Aaron Kaplan , all rights reserved. + This file is part of the ransomwarecoindDB project and licensed under the AGPL 3.0 license +""" + +__version__ = 0.1 + + +baseurl = "https://ransomcoindb.concinnity-risks.com/api/v1/" +urls = {'BTC': {'btc' : baseurl + 'bin2btc/', + 'md5' : baseurl + 'bin2btc/md5/', + 'sha1' : baseurl + 'bin2btc/sha1/', + 'sha256': baseurl + 'bin2btc/sha256/', + }, + 'XMR': {'xmr' : baseurl + 'bin2crypto/XMR/', + 'md5' : baseurl + 'bin2crypto/XMR/md5/', + 'sha1' : baseurl + 'bin2crypto/XMR/sha1/', + 'sha256': baseurl + 'bin2crypto/XMR/sha256/', + } + } + + +def get_data_by(coin: str, key: str, value: str, api_key: str): + """ + Abstract function to fetch data from the bin2btc/{key} endpoint. + This function must be made concrete by generating a relevant function. + See below for examples. + """ + + pprint.pprint("api-key: %s" % api_key) + + headers = {'x-api-key': api_key, 'content-type': 'application/json'} + # check first if valid: + valid_coins = ['BTC', 'XMR'] + valid_keys = ['btc', 'md5', 'sha1', 'sha256'] + if coin not in valid_coins or key not in valid_keys: + logging.error("get_data_by_X(): not a valid key parameter. Must be a valid coin (i.e. from %r) and one of: %r" % (valid_coins, valid_keys)) + return None + try: + + url = urls[coin.upper()][key] + logging.debug("url = %s" % url) + if not url: + logging.error("Could not find a valid coin/key combination. Must be a valid coin (i.e. from %r) and one of: %r" % (valid_coins, valid_keys)) + return None + r = requests.get(url + "%s" % (value), headers=headers) + except Exception as ex: + logging.error("could not fetch from the service. Error: %s" % str(ex)) + + if r.status_code != 200: + logging.error("could not fetch from the service. Status code: %s" % + r.status_code) + return r.json() + + +def get_bin2btc_by_btc(btc_addr: str, api_key: str): + """ Function to fetch the data from the bin2btc/{btc} endpoint """ + return get_data_by('BTC', 'btc', btc_addr, api_key) + + +def get_bin2btc_by_md5(md5: str, api_key: str): + """ Function to fetch the data from the bin2btc/{md5} endpoint """ + return get_data_by('BTC', 'md5', md5, api_key) + + +def get_bin2btc_by_sha1(sha1: str, api_key: str): + """ Function to fetch the data from the bin2btc/{sha1} endpoint """ + return get_data_by('BTC', 'sha1', sha1, api_key) + + +def get_bin2btc_by_sha256(sha256: str, api_key: str): + """ Function to fetch the data from the bin2btc/{sha256} endpoint """ + return get_data_by('BTC', 'sha256', sha256, api_key) + + +if __name__ == "__main__": + """ Just for testing on the cmd line. """ + to_btc = "1KnuC7FdhGuHpvFNxtBpz299Q5QteUdNCq" + api_key = os.getenv('api_key') + r = get_bin2btc_by_btc(to_btc, api_key) + print(r) + r = get_bin2btc_by_md5("abc", api_key) + print(r) + r = get_data_by('XMR', 'md5', "452878CD7", api_key) + print(r) diff --git a/misp_modules/modules/expansion/ransomcoindb.py b/misp_modules/modules/expansion/ransomcoindb.py new file mode 100644 index 0000000..ed0e118 --- /dev/null +++ b/misp_modules/modules/expansion/ransomcoindb.py @@ -0,0 +1,62 @@ +import json +from _ransomcoindb import ransomcoindb +import pprint + +copyright = """ + Copyright 2019 (C) by Aaron Kaplan , all rights reserved. + This file is part of the ransomwarecoindDB project and licensed under the AGPL 3.0 license +""" + +__version__ = 0.1 + + +debug=False + +misperrors = {'error': 'Error'} +# mispattributes = {'input': ['sha1', 'sha256', 'md5', 'btc', 'xmr', 'dash' ], 'output': ['btc', 'sha1', 'sha256', 'md5', 'freetext']} +mispattributes = {'input': ['sha1', 'sha256', 'md5', 'btc'], 'output': ['btc', 'sha1', 'sha256', 'md5', 'freetext']} +moduleinfo = {'version': __version__, 'author': 'Aaron Kaplan', 'description': 'Module to access the ransomcoinDB (ransomcoindb.metadata.li)', 'module-type': ['expansion', 'hover']} +moduleconfig = ['api-key'] + + +def handler(q=False): + """ the main handler function which gets a JSON dict as input and returns a results dict """ + + if q is False: + return False + + q = json.loads(q) + api_key = q["config"]["api-key"] + r = {"results": []} + + """ the "q" query coming in should look something like this: + {'config': {'api-key': ''}, + 'md5': 'md5 or sha1 or sha256 or btc', + 'module': 'metadatali_ransomcoindb', + 'persistent': 1} + """ + + for key in ['md5', 'sha1', 'sha256', 'btc']: # later: xmr, dash + if key in q: + answer = ransomcoindb.get_data_by('BTC', key, q[key], api_key) + """ The results data type should be: + r = { 'results': [ {'types': 'md5', 'values': [ a list of all md5s or all binaries related to this btc address ] } ] } + """ + if key in ['md5', 'sha1', 'sha256']: + r['results'].append({'types': 'btc', 'values': [ a['btc'] for a in answer ]}) + elif key == 'btc': + # better: create a MISP object + r['results'].append({ 'types': 'sha1', 'values': [ a['sha1'] for a in answer ]}) + r['results'].append({ 'types': 'md5', 'values': [ a['md5'] for a in answer ]}) + r['results'].append({ 'types': 'sha256', 'values': [ a['sha256'] for a in answer ]}) + + return r + + +def introspection(): + return mispattributes + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo