diff --git a/assets/browse-hosts.sh b/assets/browse-hosts.sh index faf8491a99..264f6e24db 100755 --- a/assets/browse-hosts.sh +++ b/assets/browse-hosts.sh @@ -3,7 +3,7 @@ PROXY="localhost:9050" while IFS= read -r line; do hosts+=("$line") -done < <(curl -sL ransomwhat.telemetry.ltd/groups \ +done < <(curl -sL https://dataleak.hopeless99.top//groups \ | jq -r '.[].locations[] | select(.available==true) | .fqdn') hostcount=${#hosts[@]} diff --git a/assets/check-offline.sh b/assets/check-offline.sh index 640fae334f..787e92a9ec 100755 --- a/assets/check-offline.sh +++ b/assets/check-offline.sh @@ -2,7 +2,7 @@ # some hosts in groups.json are marked as inactive when they are assumed perma offline # this script checks if they are really offline -curl -sL ransomwhat.telemetry.ltd/groups \ +curl -sL https://dataleak.hopeless99.top//groups \ | jq -r '.[] | .locations[] | select(.enabled == false) | .fqdn' \ | awk 'length >= 62' \ | while read -r fqdn; do diff --git a/assets/groups-kv.py b/assets/groups-kv.py index 443251963e..e2729c038c 100755 --- a/assets/groups-kv.py +++ b/assets/groups-kv.py @@ -6,7 +6,7 @@ with open('groups.json', 'r') as f: groups = json.load(f) else: - groups = requests.get('https://ransomwhat.telemetry.ltd/groups').json() + groups = requests.get('https://dataleak.hopeless99.top//groups').json() eventdict = [] for group in groups: for loc in group['locations']: diff --git a/assets/iter_headers.sh b/assets/iter_headers.sh index dd61303686..f0bbbe1322 100755 --- a/assets/iter_headers.sh +++ b/assets/iter_headers.sh @@ -4,7 +4,7 @@ PROXY="telemetry.dark:9050" online_hosts=() while IFS= read -r host; do online_hosts+=("$host") -done < <(curl -sL ransomwhat.telemetry.ltd/groups \ +done < <(curl -sL https://dataleak.hopeless99.top//groups \ | jq -r '.[].locations[] | select(.available==true) | .slug') if [ ${#online_hosts[@]} -eq 0 ]; then diff --git a/assets/records.md b/assets/records.md index 9fb61d1f9b..1922c38293 100755 --- a/assets/records.md +++ b/assets/records.md @@ -1,7 +1,7 @@ ##### print online hosts that do not have an enabled parser ```shell -curl -sL ransomwhat.telemetry.ltd/groups \ +curl -sL https://dataleak.hopeless99.top//groups \ | jq -r '.[] | select( .parser == false and @@ -24,7 +24,7 @@ curl -sL ransomwhat.telemetry.ltd/groups \ > replace `telemetry.dark:9050` with your own proxy fqdn ```shell -curl -sL ransomwhat.telemetry.ltd/groups \ +curl -sL https://dataleak.hopeless99.top//groups \ | jq -r '.[].locations[] | select(.enabled == false) | .slug' \ | awk 'length >= 62' | xargs -I {} -P 10 \ curl --max-time 20 --socks5-hostname multisocks.dark:9050 -o /dev/null \ @@ -34,7 +34,7 @@ curl --max-time 20 --socks5-hostname multisocks.dark:9050 -o /dev/null \ ##### screenshot all online hosts tagged as lockbit3 ```shell -curl -sL ransomwhat.telemetry.ltd/groups \ +curl -sL https://dataleak.hopeless99.top//groups \ | jq -r '.[] | select(.name == "lockbit3") | .locations[] | select(.available == true) | .slug' \ | python3 assets/screenshotter.py --stdin ``` \ No newline at end of file diff --git a/assets/screenshotter.py b/assets/screenshotter.py index ffeba37a78..25ef28ca97 100755 --- a/assets/screenshotter.py +++ b/assets/screenshotter.py @@ -61,7 +61,7 @@ def main(): elif args.url: screenshot_single_url(browser, args.url) elif args.all: - groups = requests.get('https://ransomwhat.telemetry.ltd/groups').json() + groups = requests.get('https://dataleak.hopeless99.top//groups').json() for group in groups: print('group: {}'.format(group['name'])) for webpage in group['locations']: diff --git a/assets/sources.sh b/assets/sources.sh index 9dee17a808..53deb33d02 100755 --- a/assets/sources.sh +++ b/assets/sources.sh @@ -7,7 +7,7 @@ if [ ! -d tmp ]; then mkdir tmp fi -master_list=$(curl -sL ransomwhat.telemetry.ltd/groups | jq '.[].locations[].fqdn' -r) +master_list=$(curl -sL https://dataleak.hopeless99.top//groups | jq '.[].locations[].fqdn' -r) curl -s https://telemetr.io/en/channels/1232665535-dbforall/posts \ | awk 'BEGIN{RS=" "}{if($0 ~ /http[s]?:\/\/[a-zA-Z0-9]*\.onion/){print $0}}' \ @@ -83,7 +83,7 @@ curl -s https://godnotaba.ru \ | grep -oE '[a-z2-7]{56}\.onion' \ | sort | uniq > assets/tmp/godnotabaru.txt -ransomwatch_allfqdn=$(curl -sL "https://ransomwhat.telemetry.ltd/groups" | jq '.[].locations[].fqdn' -r) +ransomwatch_allfqdn=$(curl -sL "https://dataleak.hopeless99.top//groups" | jq '.[].locations[].fqdn' -r) is_excluded() { local address="$1" diff --git a/assets/tg_ransomwatcher.py b/assets/tg_ransomwatcher.py new file mode 100644 index 0000000000..29257da7e8 --- /dev/null +++ b/assets/tg_ransomwatcher.py @@ -0,0 +1,138 @@ +import requests +import json +import telegram +import logging +from time import sleep +import os + +# Configure logging +logging.basicConfig(filename='app.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') + +# Cisa Feed: +def fetch_and_compare_vulnerabilities(url, local_file='vulnerabilities.json'): + # Fetch the latest data from the URL + response = requests.get(url) + if response.status_code != 200: + raise Exception("Failed to fetch data from the URL") + latest_data = response.json() + # Load the local JSON file if it exists + if os.path.exists(local_file): + with open(local_file, 'r') as file: + local_data = json.load(file) + else: + local_data = {} + # Compare the new data with the local data + new_items = [] + for item in latest_data.get('vulnerabilities', []): + if item not in local_data.get('vulnerabilities', []): + new_items.append(item) + # Update the local JSON file + with open(local_file, 'w') as file: + json.dump(latest_data, file, indent=4) + return new_items + +class DataFetcher: + def __init__(self, url, local_file, chat_id, bot_token): + self.url = url + self.local_file = local_file + self.indexed_items = set() + self.chat_id = chat_id + self.bot_token = bot_token + self.bot = telegram.Bot(bot_token) + + def download_initial_data(self): + try: + response = requests.get(self.url) + response.raise_for_status() + initial_data = response.json() + self.indexed_items.update(item['post_title'] for item in initial_data) + with open(self.local_file, 'w') as file: + json.dump(initial_data, file) + except requests.RequestException as e: + logging.error(f"Error downloading initial data: {e}") + self.send_error_alert(f"Erro ao baixar a base inicial:\n{e}") + + def fetch_data(self): + try: + response = requests.get(self.url) + response.raise_for_status() + return response.json() + except requests.RequestException as e: + logging.error(f"Error fetching data: {e}") + self.send_error_alert(f"Falha na requisição do arquivo JSON:\n{e}") + return None + + def read_local_data(self): + if os.path.exists(self.local_file): + with open(self.local_file, 'r') as file: + return json.load(file) + return [] + + def index_data(self, data): + new_items = [] + for item in data: + item_id = item.get('post_title') + if item_id and item_id not in self.indexed_items: + self.indexed_items.add(item_id) + new_items.append(item) + return new_items + + def update_local_data(self, data): + with open(self.local_file, 'w') as file: + json.dump(data, file) + + def get_new_items(self): + web_data = self.fetch_data() + if web_data is None: + return [] + + local_data = self.read_local_data() + new_items = self.index_data(web_data) + if new_items: + self.update_local_data(local_data + new_items) + return new_items + + def send_error_alert(self, message): + self.bot.sendMessage(self.chat_id, f"❌ Erro na execução:\n{message}") + +# CISA url: +cisa_url = 'https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json' +# Define monitor: +monitor = DataFetcher( + url="https://raw.githubusercontent.com/joshhighet/ransomwatch/main/posts.json", + local_file="local_data.json", + chat_id="CHANNELID", + bot_token="TGTOKEN" +) + +# Run: +if __name__ == '__main__': + first_run = True + while True: + try: + if first_run: + monitor.download_initial_data() + first_run = False + #sleep(1800) # Wait for 30 minutes before the next run + continue + + # Fetch new items: + for i in monitor.get_new_items(): + msg = '❗️ Alerta de Ransomware ❗️\nPost: "{0}"\nGrupo: {1}\nIdentificado em: {2}'.format(i['post_title'], i['group_name'], i['discovered'].split(" ")[0]) + monitor.bot.sendMessage(monitor.chat_id, msg) + sleep(30) + logging.info("{0} cases indexed and reported.".format(len(monitor.indexed_items))) + + # Fetch new CISA Alerts: + for i in fetch_and_compare_vulnerabilities(cisa_url): + msg = '🚨 Exploitation in the Wild! 🚨\nID: {0}\n{1}\nSuggestion: {2}'.format(i['cveID'], i['shortDescription'], i['requiredAction']) + monitor.bot.sendMessage(monitor.chat_id, msg) + sleep(30) + logging.info("CISA alerts checked.") + sleep(1800) + continue + except Exception as error: + logging.error(f"An error occurred: {error}") + monitor.send_error_alert(f"Um erro não identificado ocorreu:\n{error}") + sleep(15) + continue diff --git a/dockerfile b/dockerfile index 80686cdf66..6525c797a4 100755 --- a/dockerfile +++ b/dockerfile @@ -1,6 +1,6 @@ FROM python:3 -LABEL org.opencontainers.image.source https://github.com/cyberiskvision/dls-monitor +LABEL org.opencontainers.image.source https://github.com/adminlove520 COPY *.py / COPY *.json / diff --git a/docs/README.md b/docs/README.md index 3d39a13a40..18d84c5e19 100755 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,6 @@ _⚙️ there are currently `85` online hosts & `112` custom parsers._ 🦕 ransomwatch has been running for `3 years, 2 months and 22 days` and indexed `12696` posts -_all data [(groups)](http://ransomwhat.telemetry.ltd/groups) and [(posts)](http://ransomwhat.telemetry.ltd/posts) is available in JSON (updated hourly)_ +_all data [(groups)](http://https://dataleak.hopeless99.top//groups) and [(posts)](http://https://dataleak.hopeless99.top//posts) is available in JSON (updated hourly)_ -> ransomwatch is fully [open source](https://github.com/joshhighet/ransomwatch#ransomwatch--). please consider [sponsoring](https://github.com/sponsors/joshhighet) if you find it useful! + diff --git a/markdown.py b/markdown.py index 10746a8d75..37470faae6 100755 --- a/markdown.py +++ b/markdown.py @@ -82,7 +82,7 @@ def mainpage(): writeline(uptime_sheet, '') writeline(uptime_sheet, '🦕 ransomwatch has been running for `' + howoldami() + '` and indexed `' + str(postcount()) + '` posts') writeline(uptime_sheet, '') - writeline(uptime_sheet, '_all data ' + ' [(groups)](http://ransomwhat.telemetry.ltd/groups) and [(posts)](http://ransomwhat.telemetry.ltd/posts) is available in JSON (updated hourly)_') + writeline(uptime_sheet, '_all data ' + ' [(groups)](http://https://dataleak.hopeless99.top//groups) and [(posts)](http://https://dataleak.hopeless99.top//posts) is available in JSON (updated hourly)_') writeline(uptime_sheet, '') writeline(uptime_sheet, "> ransomwatch is fully [open source](https://github.com/joshhighet/ransomwatch#ransomwatch--). please consider [sponsoring](https://github.com/sponsors/joshhighet) if you find it useful!")