From fc817a5389e6ccd63f6685f10a72a27b4eea8dd4 Mon Sep 17 00:00:00 2001 From: TonyJabbour Date: Wed, 6 Oct 2021 11:12:43 +0200 Subject: [PATCH] New API Endpoint: Fixed get_item_content_encoded_text Added get_item_sources Added get_check_item_source Added get_default_yara_rule_content --- bin/lib/Tracker.py | 30 +++++++++++++--- bin/packages/Item.py | 44 ++++++++++++++++-------- var/www/modules/restApi/Flask_restApi.py | 30 +++++++++++++--- 3 files changed, 81 insertions(+), 23 deletions(-) diff --git a/bin/lib/Tracker.py b/bin/lib/Tracker.py index 5e929b8b..74543244 100755 --- a/bin/lib/Tracker.py +++ b/bin/lib/Tracker.py @@ -9,6 +9,7 @@ import redis import uuid import yara import datetime +import base64 from flask import escape @@ -683,17 +684,36 @@ def api_get_default_rule_content(default_yara_rule): yara_dir = get_yara_rules_default_dir() filename = os.path.join(yara_dir, default_yara_rule) filename = os.path.realpath(filename) - - # incorrect filename if not os.path.commonprefix([filename, yara_dir]) == yara_dir: - return ({'status': 'error', 'reason': 'file transversal detected'}, 400) + return {'status': 'error', 'reason': 'file traversal detected'}, 400 if not os.path.isfile(filename): - return ({'status': 'error', 'reason': 'yara rule not found'}, 400) + return {'status': 'error', 'reason': 'yara rule not found'}, 400 with open(filename, 'r') as f: rule_content = f.read() - return ({'rule_name': default_yara_rule, 'content': rule_content}, 200) + return {'rule_name': default_yara_rule, 'content': rule_content}, 200 + + +def get_yara_rule_content_restapi(request_dict): + rule_name = request_dict.get('rule_name', None) + if not request_dict: + return {'status': 'error', 'reason': 'Malformed JSON'}, 400 + if not rule_name: + return {'status': 'error', 'reason': 'Mandatory parameter(s) not provided'}, 400 + yara_dir = get_yara_rules_dir() + filename = os.path.join(yara_dir, rule_name) + filename = os.path.realpath(filename) + if not os.path.commonprefix([filename, yara_dir]) == yara_dir: + return {'status': 'error', 'reason': 'File Path Traversal'}, 400 + if not os.path.isfile(filename): + return {'status': 'error', 'reason': 'yara rule not found'}, 400 + with open(filename, 'r') as f: + rule_content = f.read() + rule_content = base64.b64encode((rule_content.encode('utf-8'))).decode('UTF-8') + return {'status': 'success', 'content': rule_content}, 200 + + ##-- YARA --## diff --git a/bin/packages/Item.py b/bin/packages/Item.py index 6e6e048e..b4d86a36 100755 --- a/bin/packages/Item.py +++ b/bin/packages/Item.py @@ -59,6 +59,9 @@ def get_item_date(item_id, add_separator=False): def get_source(item_id): return item_basic.get_source(item_id) +def get_all_sources(): + return item_basic.get_all_items_sources(r_list=True) + def get_item_basename(item_id): return os.path.basename(item_id) @@ -87,14 +90,12 @@ def get_item_metadata(item_id, item_content=None): # encoding # language # lines info - - item_metadata = {} - item_metadata['date'] = get_item_date(item_id, add_separator=True) - item_metadata['source'] = get_source(item_id) - item_metadata['size'] = get_item_size(item_id) - item_metadata['encoding'] = get_item_encoding(item_id) - item_metadata['lines'] = get_lines_info(item_id, item_content=item_content) - + item_metadata = {'date': get_item_date(item_id, add_separator=True), + 'source': get_source(item_id), + 'size': get_item_size(item_id), + 'encoding': get_item_encoding(item_id), + 'lines': get_lines_info(item_id, item_content=item_content) + } return item_metadata def get_item_parent(item_id): @@ -223,18 +224,33 @@ def get_item(request_dict): def get_item_content_encoded_text(request_dict): item_id = request_dict.get('id', None) if not request_dict: - return {'status': 'error', 'reason': 'Malformed JSON'}, 400, 1 + return {'status': 'error', 'reason': 'Malformed JSON'}, 400 if not item_id: - return {'status': 'error', 'reason': 'Mandatory parameter(s) not provided'}, 400, 1 + return {'status': 'error', 'reason': 'Mandatory parameter(s) not provided'}, 400 if not exist_item(item_id): - return {'status': 'error', 'reason': 'Item not found'}, 404, 1 + return {'status': 'error', 'reason': 'Item not found'}, 404 item_content = get_item_content(item_id) - base64_output = base64.b64encode((item_content.encode('utf-8'))) - - return base64_output, 200, 0 + item_content = base64.b64encode((item_content.encode('utf-8'))).decode('UTF-8') + return {'status': 'success', 'content': item_content}, 200 +def get_item_sources(): + item_content = {'sources': get_all_sources()} + return item_content, 200 + +def check_item_source(request_dict): + source = request_dict.get('source', None) + if not request_dict: + return {'status': 'error', 'reason': 'Malformed JSON'}, 400 + if not source: + return {'status': 'error', 'reason': 'Mandatory parameter(s) not provided'}, 400 + + all_sources = item_basic.get_all_items_sources() + + if source not in all_sources: + return {'status': 'error', 'reason': 'Invalid source', 'provide': source}, 400 + return {'status': 'success', 'reason': 'Valid source', 'provide': source}, 200 ### ### correlation ### diff --git a/var/www/modules/restApi/Flask_restApi.py b/var/www/modules/restApi/Flask_restApi.py index 0169526a..443e007f 100644 --- a/var/www/modules/restApi/Flask_restApi.py +++ b/var/www/modules/restApi/Flask_restApi.py @@ -23,6 +23,7 @@ import Item import Paste import Tag import Term +import Tracker sys.path.append(os.path.join(os.environ['AIL_BIN'], 'import')) import importer @@ -319,12 +320,25 @@ def get_item_content_encoded_text(): item_id = data.get('id', None) req_data = {'id': item_id} res = Item.get_item_content_encoded_text(req_data) - if res[2] == 1: - return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] - else: - return res[0], res[1] + return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] +@restApi.route("api/v1/get/item/sources", methods=['GET']) +@token_required('read_only') +def get_item_sources(): + res = Item.get_item_sources() + return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] + + + +@restApi.route("api/v1/get/item/source/check", methods=['POST']) +@token_required('read_only') +def get_check_item_source(): + data = request.get_json() + source = data.get('source', None) + req_data = {'source': source} + res = Item.check_item_source(req_data) + return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # TAGS # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @@ -376,6 +390,14 @@ def get_tracker_term_item(): return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] +@restApi.route("api/v1/get/tracker/yara/content", methods=['POST']) +@token_required('read_only') +def get_default_yara_rule_content(): + data = request.get_json() + rule_name = data.get('rule_name', None) + req_data = {'rule_name': rule_name} + res = Tracker.get_yara_rule_content_restapi(req_data) + return Response(json.dumps(res[0], indent=2, sort_keys=True), mimetype='application/json'), res[1] # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # CRYPTOCURRENCY # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #