From 67330e40173b30b95d5272fe700c7e2eb70b12c3 Mon Sep 17 00:00:00 2001 From: brotoskyj Date: Tue, 29 Jul 2025 10:51:21 -0400 Subject: [PATCH] First Commit --- .gitignore | 3 + query.py | 49 ++++++++++++++ requirements.txt | 1 + utils/database.py | 25 +++++++ utils/teamsconnector.py | 145 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 223 insertions(+) create mode 100644 .gitignore create mode 100644 query.py create mode 100644 requirements.txt create mode 100644 utils/database.py create mode 100644 utils/teamsconnector.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79b3559 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +database.db +utils/__pycache__/ \ No newline at end of file diff --git a/query.py b/query.py new file mode 100644 index 0000000..3f1de91 --- /dev/null +++ b/query.py @@ -0,0 +1,49 @@ +import datetime +import dotenv +import json +import requests +import socket +import utils.database +import utils.teamsconnector + +def main(): + utils.database.createdatabasefile() + current_date = datetime.date.today() + month = current_date.month + year = current_date.year + try: + response = requests.get(f'https://api.ransomware.live/v2/victims/{year}/{month}') + except Exception as e: + print(e) + json_parse = json.loads(response.content) + format_date_string = "%Y-%m-%d %H:%M:%S.%f" + for vic in json_parse: + date_object = datetime.datetime.strptime(vic['discovered'], format_date_string) + date = date_object.date() + if current_date == date: + sqlresult = utils.database.checkdatabase(vic['victim'], vic['discovered']) + if sqlresult is False: + vendor = vic['victim'] + date_added = vic['discovered'] + domain = vic['domain'] + group = vic['group'] + try: + if domain != "" and " " not in domain: + ip_address = socket.getaddrinfo(domain, 0, 0, 0, 0) + unique_ips = list(set([addr[-1][0] for addr in ip_address])) + else: + unique_ips = "Unknown" + except: + unique_ips = "Unknown" + print("=== Victim Added ===") + print(f""" + Vendor: {vendor} + Date: {date_added} + Domain: {domain} + IP Addresses: {str(unique_ips).replace('[','').replace(']', '')} + Attack Group: {group} + """) + utils.teamsconnector.teamswebhook(vic['victim'], vic['discovered'], vic['domain'], vic['group'], unique_ips, vic['description']) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..40448e6 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +dotenv \ No newline at end of file diff --git a/utils/database.py b/utils/database.py new file mode 100644 index 0000000..1ff87f7 --- /dev/null +++ b/utils/database.py @@ -0,0 +1,25 @@ +import pathlib +import sqlite3 + +conn = sqlite3.connect('database.db') +cursor = conn.cursor() + +def createdatabasefile(): + pathlib.Path("database.db").touch(exist_ok=True) + cursor.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='active_attacks'") + result = cursor.fetchone() + if result is None: + cursor.execute('''CREATE TABLE active_attacks + (vendor_name text, date_accessed datetime) + ''') + conn.commit() + +def checkdatabase(victimname, date_discovered): + query = f"SELECT vendor_name FROM active_attacks WHERE vendor_name= ?" + cursor.execute(query, (victimname,)) + result = cursor.fetchone() + if result is None: + query = f"INSERT INTO active_attacks VALUES ('{victimname}', '{date_discovered}')" + cursor.execute(query) + conn.commit() + return False \ No newline at end of file diff --git a/utils/teamsconnector.py b/utils/teamsconnector.py new file mode 100644 index 0000000..08f14f5 --- /dev/null +++ b/utils/teamsconnector.py @@ -0,0 +1,145 @@ +import dotenv +import os +import requests +dotenv.load_dotenv() + +def teamswebhook(victimname, date_discovered, domain, group, ip_address, description): + webhook_url = os.getenv('WEBHOOK_URL') + + headers = {"Content-Type": "application/json"} + + adaptive_card = { + "type": "AdaptiveCard", + "body": [ + { + "type": "TextBlock", + "size": "Medium", + "weight": "Bolder", + "text": "Ransomware.live Alert!" + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "items": [ + { + "type": "TextBlock", + "weight": "Bolder", + "text": f"{victimname}", + "wrap": "true" + }, + { + "type": "TextBlock", + "spacing": "None", + "text": f"{date_discovered}", + "isSubtle": "true", + "wrap": "true" + } + ], + "width": "stretch" + } + ] + }, + { + "type": "TextBlock", + "text": f"{description}", + "wrap": "true" + }, + { + "type": "ColumnSet", + "separator": "true", + "columns": [ + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "Domain", + "wrap": "true" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": f"{domain}", + "wrap": "true" + } + ] + } + ] + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "IP Addresses", + "wrap": "true" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": f"{ip_address}", + "wrap": "true" + } + ] + } + ] + }, + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "Ransomware Group", + "wrap": "true" + } + ] + }, + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": f"{group}", + "wrap": "true" + } + ] + } + ] + } + ], + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.6" +} + + payload = { + "card": adaptive_card + } + + response = requests.post(webhook_url, headers=headers, json=payload) + + if response.ok: + print("✅ Card sent to Teams successfully!") + else: + print(f"❌ Failed to send card: {response.status_code} - {response.text}") \ No newline at end of file