Code Monkey home page Code Monkey logo

ransomwatch's Introduction

ransomwatch engine ransomwatch dockerimage builder ransomwatch codeql analysis

ransomwatch trails the extortion sites used by ransomware groups and surfaces an aggregated feed of claims

please use the issue template when submitting new groups


⚠️

content within ransomwatch.telemetry.ltd, posts.json, groups.json alongside the docs/ & source/ directories is dynamically generated based on hosting choices of real-world threat actors in near-real-time.

whilst sanitisation efforts have been taken, by viewing or accessing ransomwatch you acknowledge you are doing so at your own risk

if you leverage ransomwatch in commercial platforms, please consider becoming a sponsor πŸ’ž

key outputs

web:// ransomwatch.telemetry.ltd

json:// ransomwhat.telemetry.ltd/posts

json:// ransomwhat.telemetry.ltd/groups

  • groups.json contains hosts, nodes, relays and mirrors for a tracked group or actor
  • posts.json contains extracted posts, noted by their discovery time and accountable group

technicals

this is a live repository that utilizes a combination of GitHub actions and a service container. it visits, parses, and reports on monitored hosts in near-real-time in a self-contained manner

content fetching is done with psf/requests - if rendering is required mozilla/geckodriver and seleniumhq/selenium are leveraged.

The frontend is ultimately generated with markdown, using markdown.py and served with docsifyjs/docsify thanks to pages.github.com

graphs or visualisations are generated with plotting.py with the help of matplotlib/matplotlib

post indexing is done with a mix of grep, awk and sed within parsers.py - it's brittle and like any ̴̭́HΜΆΜ€Μ“TΜΈΜ™Μ…MΜΆΝ‡ΜΎLΜ·Ν‘Ν… ̴̙̏pΜΈΜ‘Ν†aΜ·Μ›Μ¦rΜ΅Μ¬ΜΏsΜ΄Μ™Ν›Δ©Μ΄ΜΊnΜΈΜ”Νœg̸̘̈, has a limited lifetime.

tools

rendered HTML for each page is viewable within the source directory

  • screenshotter.py a playwright script to generate high-resolution screenshots of online hosts
  • srcanalyser.py a basic extractor for emails, internal and external links found within page source
  • browse-hosts.sh a simple cURL based iterator for sweeping URL checks
  • sources.zsh an aggregator of various locations that surface new groups for ransomwatch
  • uptimekuma-importer.py a script to convert the group data into a uptime-kuma configuration file
  • parsers.sh a health-check script that provides details on parsers that are returning no fields

a flattened version of groups.json with each host as its own object can be found at assets/groups-kv.json. the structure is an array of objects, each representing a distinct entity/group with each containing all properties (like name, captcha, parser, etc.) at the same level, including potential repetition on elements such as profile and meta. some data analysis tools work with this structure in an easier manner requiring less transposing.

cli operations

fetching hidden services requires a tor circuit! establish one with;

docker run -p9050:9050 ghcr.io/joshhighet/torsocc:latest
usage: ransomwatch.py [-h] [--name NAME] [--location LOCATION] {add,scrape,parse,markdown}

positional arguments:
  {add,scrape,parse,markdown}
                        operation to execute

optional arguments:
  -h, --help            show this help message and exit
  --name NAME           provider name
  --location LOCATION   target web location (full URI)

       _______________                        |*\_/*|________
      |  ___________  |                      ||_/-\_|______  |
      | |           | |                      | |           | |
      | |   0   0   | |                      | |   0   0   | |
      | |     -     | |                      | |     -     | |
      | |   \___/   | |                      | |   \___/   | |
      | |___     ___| |                      | |___________| |
      |_____|\_/|_____|                      |_______________|
        _|__|/ \|_|_.............πŸ’”.............._|________|_
       / ********** \                          / ********** \
     /  ************  \   πŸ‘€ πŸ¦… ransomwatch  /  ************  \
    --------------------                    --------------------

newly indexed posts can be sent to discord by providing a DISCORD_WEBHOOK var when running parse.

DISCORD_WEBHOOK=https://discord.com/api/webhooks/xxxxx/xxx ./ransomwatch.py parse

datamap

erDiagram
    groups_json ||--|{ group : contains
    group {
        string name "group name"
        boolean captcha "captcha status"
        boolean parser "parser status"
        boolean javascript_render "javascript status"
        string meta "freeform text"
        string url "notable articles and references"
    }
    group ||--|{ locations : has
    locations {
        string fqdn "fully qualified domain name"
        string title "page title"
        int version "hidden service version"
        string slug "full URI"
        boolean available "availability status"
        datetime updated "timestamp of last update"
        datetime lastscrape "timestamp of last scrape"
        boolean enabled "status"
    }
    group ||--|{ post : references
    post {
        string post_title "post title"
        string group_name "associated group name"
        datetime discovered "timestamp of discovery"
    }
Loading

accessing data with cURL and JQ

print last 10 claims by group lockbit3
curl -sL ransomwhat.telemetry.ltd/posts \
| jq -r '.[] | select(.group_name == "lockbit3") | .post_title' \
| tail -n 10
print all online URL's
curl -sL ransomwhat.telemetry.ltd/groups \
| jq -r '.[] | .locations[] | select(.available == true) | .slug'
print group data for "lockbit3"
curl -sL ransomwhat.telemetry.ltd/groups \
| jq -r '.[] | select(.name == "lockbit3")'
print the last 20 claims
curl -sL ransomwhat.telemetry.ltd/posts \
| jq -r '.[] | [.group_name, .post_title] | @tsv' \
| sed 's/ /_/g' | column -t | tail -n 20

ransomwatch is licensed under unlicense.org

ransomwatch's People

Contributors

dependabot[bot] avatar github-actions[bot] avatar joshhighet avatar weddige avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ransomwatch's Issues

Alphabetize and categorize the group index

Alphabetizing the group index will make it much easier to navigate. Also having two sub-groups for active (green) link groups and dead (red) link\groups would be helpful to sort out what is recent.

Cuba data not populating

While comparing data collected in RW to data available on various leak sites, I noticed four entries since the latest addition to the RW data under the Cuba group.

image

update group: blackcat / alphV

host location

alphvmmm27o3abo3r2mlmjrpdmzle3rykajqc5xsj7j7ejksbpsa36ad.onion

group name

alphV, alreay exist in your base

group information

New parser 'cause they use (, ), | in the Topic... Perhaps should work on a more generic regex.

host

v3 (onion)

parser

egrep -o 'class="mat-h2">([[:alnum:]]|\ |\.|\||\(|\))+</h2' source/alphav-*.html | cut -d '>' -f 2 | cut -d '<' -f 1

new group: nightsky

host location

gg5ryfgogainisskdvh4y373ap3b2mxafcibeh2lvq5x7fx76ygcosad.onion

group name

nightsky

group information

https://t.me/arvin_club/5081

host

v3 (onion)

parser

grep 'class="mdui-card-primary-title"' nightsky.html | cut -d '>' -f 3 | cut -d '<' -f 1

Make screenshotter.py works with onion sites

Original version doesn't seem to work due to an error in the NS Lookup function (not using Tor tunnel).
I modified the original version being inspired by the version of RansomLook.
I'm sure the code could be lighter, I did not check if all import are still necessary.

Need playwrights :
pip3 -r install
playwright install

I cannot do a PR because I modified so many things at the same time, sorry πŸ‘ŽπŸ»

screenshotter.py.txt

replace parsers using alnum

when using alnum content can easily be missed. when using [0-9A-Za-z], the following would pass Advanced Micro Devices but with the added comma the following would fail to be picked up Advanced Micro Devices, Inc

ref grep/manual/bracketexpressions

./assets/parsers.sh -p | grep egrep
egrep -o 'class="title">([[:alnum:]]| |\.)+</a>' source/groove-*.html | cut -d '>' -f2 | cut -d '<' -f 1
egrep -o '<span style="font-size:20px;">([[:alnum:]]| |\.)+</span>' source/kelvinsecurity-*.html | cut -d '>' -f 2 | cut -d '<' -f 1
egrep -o 'fqd.onion/\?id=([[:alnum:]]| |\.)+"' source/blackbasta-*.html | cut -d = -f 2 | cut -d '"' -f 1 | sed -e 's/^ *//g' -e 's/[[:space:]]*$//'
egrep -o 'class="cls_recordTop"><p>([[:alnum:]]| |\.)+</p>' source/ransomhouse-*.html | cut -d '>' -f 3 | cut -d '<' -f 1

  • groove
  • kelvin
  • basta
  • house

new group: LockBit 3.0

host location

hxxp://lockbitapt2d73krlbewgv27tquljgxr33xbwwsp6rkyieto7u4ncead.onion

group name

lockbit3 / LockBit 3.0

group information

Mirror 1: hxxp://lockbitapt2d73krlbewgv27tquljgxr33xbwwsp6rkyieto7u4ncead.onion

Mirror 2: hxxp://lockbitapt2yfbt7lchxejug47kmqvqqxvvjpqkmevv4l3azl3gy6pyd.onion

Mirror 3: hxxp://lockbitapt34kvrip6xojylohhxrwsvpzdffgs5z4pbbsywnzsbdguqd.onion

Mirror 4: hxxp://lockbitapt5x4zkjbcqmz6frdhecqqgadevyiwqxukksspnlidyvd7qd.onion

Mirror 5: hxxp://lockbitapt6vx57t3eeqjofwgcglmutr3a35nygvokja5uuccip4ykyd.onion

Mirror 6: hxxp://lockbitapt72iw55njgnqpymggskg5yp75ry7rirtdg4m7i42artsbqd.onion

Mirror 7: hxxp://lockbitaptawjl6udhpd323uehekiyatj6ftcxmkwe5sezs4fqgpjpid.onion

Mirror 8: hxxp://lockbitaptbdiajqtplcrigzgdjprwugkkut63nbvy2d5r4w2agyekqd.onion

Mirror 9: hxxp://lockbitaptc2iq4atewz2ise62q63wfktyrl4qtwuk5qax262kgtzjqd.onion

(Remove hxxp with http, proceed with caution)

Note: has 3 seconds Anti-DDoS as does version 2.0

vic domain names are in div with class "post-title"

host

v3 (onion)

parser

No response

Update group: REvil

host location

hxxp://blogxxu75w63ujqarv476otld7cyjkq4yoswzt4ijadkjwvg3vrvd5yd[.]onion/Blog

group name

REvil

group information

Old REvil link now redirects to this one. Has posted new victims in past 24 hours

host

v3 (onion)

parser

I believe this is the same site as when it was taken down

new group: Bl00dy

host location

Bl00dy

group name

Bl00dy

group information

Bl00dy

host

v3 (onion)

parser

No response

new group: Crimson Walrus

host location

Crimson Walrus

group name

Crimson Walrus

group information

Crimson Walrus

host

v3 (onion)

parser

No response

new group: stormous

host location

http://h3reihqb2y7woqdary2g3bmk3apgtxuyhx4j2ftovbhe3l5svev7bdyd.onion/stm.html

group name

Stormous.X

group information

MESSAGE:
Did you get infected with STORMOUS ransomware? Are your company's server files encrypted? Is your computer encrypted? Are all your computer files encrypted? Read the decryption rules and all your files will be restored within an hour (Stormous.X can infect an entire network in less than an hour)

SHOP:
http://h3reihqb2y7woqdary2g3bmk3apgtxuyhx4j2ftovbhe3l5svev7bdyd.onion/shop.html

host

v3 (onion)

parser

No response

Adrastea

host location

Adrastea

group name

Adrastea

group information

No response

host

v3 (onion)

parser

No response

.onion geckodriver reqs failing: NS_BINDING_ABORTED

maybe, just maybe - related to SeleniumHQ/selenium#10840

something updated <?> - all fetches leveraging geckodriver for rendering broken

eg. fail within runner ransomwatch/runs/7330084972 step:5:1182 (local/runner agnostic)

➜  ransomwatch git:(main) βœ— python3 -c 'import selenium; print(selenium.__version__)'
4.0.0
➜  ransomwatch git:(main) βœ— geckodriver --version
geckodriver 0.31.0
➜  ransomwatch git:(main) βœ— /Applications/Firefox.app/Contents/MacOS/firefox-bin --full-version
Mozilla Firefox 102.0.1 20220705093820 20220705093820
{
    "value":{
        "error":"session not created",
        "message":"Error: NS_BINDING_ABORTED",
        "stacktrace":"#checkLoadingState@chrome://remote/content/shared/Navigate.jsm:209:28\nonStateChange@chrome://remote/content/shared/Navigate.jsm:254:28\n"
    }
}

add options.log.level = "trace" to geckodriver.py to repro trace below against https://3f7nxkjway3d223j27lyad7v5cgmyaifesycvmwq7i7cbs23lb6llryd.onion/auction

➜  ransomwatch git:(main) βœ— tail -f geckodriver.log
1657752931184	geckodriver::marionette	DEBUG	Connection to Marionette established on 127.0.0.1:62149.
1657752931213	Marionette	DEBUG	0 -> [0,1,"WebDriver:NewSession",{"acceptInsecureCerts":true,"browserName":"firefox","pageLoadStrategy":"normal"}]
1657752931215	RemoteAgent	WARN	TLS certificate errors will be ignored for this session
1657752931226	Marionette	DEBUG	Waiting for initial application window
1657752931844	RemoteAgent	TRACE	Received DOM event load for [object HTMLDocument]
console.warn: SearchSettings: "get: No settings file exists, new profile?" (new NotFoundError("Could not open the file at [redacted]", (void 0)))
1657752932878	Marionette	TRACE	Received observer notification browser-idle-startup-tasks-finished
1657752932879	RemoteAgent	TRACE	Received observer notification browser-idle-startup-tasks-finished
DevTools listening on ws://localhost:62142/devtools/browser/[redacted]
1657752932882	RemoteAgent	TRACE	[22] ProgressListener state=start: http://start-maximized/
1657752947612	RemoteAgent	TRACE	[22] ProgressListener state=stop: error=0x804b0002 (NS_BINDING_ABORTED)
1657752947613	Marionette	DEBUG	0 <- [1,1,{"error":"session not created","message":"Error: NS_BINDING_ABORTED","stacktrace":"#checkLoadingState@chrome://remote/content/shared/Navigate.jsm:209:28\nonStateChange@chrome://remote/content/shared/Navigate.jsm:254:28\n"},null]
1657752947615	webdriver::server	DEBUG	Teardown session
1657752947615	mozrunner::runner	DEBUG	Killing process 86034
Exiting due to channel error.
Exiting due to channel error.
[GFX1-]: Receive IPC close with reason=AbnormalShutdown
Exiting due to channel error.
1657752947694	webdriver::server	DEBUG	<- 500 Internal Server Error {"value":{"error":"session not created","message":"Error: NS_BINDING_ABORTED","stacktrace":"#checkLoadingState@chrome://remote/content/shared/Navigate.jsm:209:28\nonStateChange@chrome://remote/content/shared/Navigate.jsm:254:28\n"}}

new group: Sangkancil

host location

Sangkancil

group name

Sangkancil

group information

Sangkancil

host

v3 (onion)

parser

No response

new node: alphav

host location

2cuqgeerjdba2rhdiviezodpu3lc4qz2sjf4qin6f7std2evleqlzjid.onion

group name

alphav

group information

No response

host

v3 (onion)

parser

No response

new group: Crypt0n

host location

Crypt0n

group name

Crypt0n

group information

Crypt0n

host

v3 (onion)

parser

No response

New parser for blackbytes

The blackbytes ransomware group has changed (again) their webpage.

The vicitims'names could be found in class=target-name h1 tag.

Here is a parser which seems to work fine (for now) :

grep --no-filename 'class="target-name"' source/blackbyte-*.html | cut -d '>' -f 2 | cut -d '<' -f 1 | sed -e 's/^ *//g' -e '/^$/d' -e 's/[[:space:]]*$//'

Monthly post count error

The monthly post count has an error, the function calculate all post for the month regardless of the year.

I suggest to check only for the current year :

in sharedutils.py (line 348)

def mounthlypostcount():
    '''
    returns the number of posts within the current month
    '''
    post_count = 0
    posts = openjson('posts.json')
    current_month = datetime.now().month
    current_year = datetime.now().year
    for post in posts:
        datetime_object = datetime.strptime(post['discovered'], '%Y-%m-%d %H:%M:%S.%f')
        if datetime_object.year == current_year and datetime_object.month == current_month:
                post_count += 1
    return post_count

Ps: there is a typo in the name of the function (monthly not mounthly) but not a big deal.

Optimize Bianlian parser

The last posts on Bianlian ransomware blog use * in the company name

I suggest to use this parser to avoid blank

sed -n '/<a href="\/companies\//,/<\/a>/p' source/bianlian-*.html | sed 's/&amp;/and/' | egrep -o "([A-Za-z0-9 ,*\'.-])+</a>" | cut -d '<' -f 1 | sed -e '/Contacts/d'

I also replace & by 'and' to get a better rendering.

Missing entry under blackbasta leak site

While conducting some data validation, I observed that the entry for ttdwest on the blackbasta leak site (hxxps://stniiomyjliimcgkvdszvgen3eaaoz55hreqqx6o77yvmpwt7gklffqd[.]onion/) does not show up in the ransomwatch post data. Other sources indicate this by its name from the post's description, Total Transportation & Distribution, Inc.

Blackbasta's a tough site to review, since it shows a good amount of info about the victim (site, address, description, etc), but does not include the date of the victimization.

Mostly posting this to see whether there's something I'm missing in reviewing the results.

Vicesociety latest entry not pulled

The vicesociety site appears to be correct in Ransomwatch, but it failed to pull the latest entry (Los Angeles USD) from their leak site.

vsociethok6sbprvevl4dlwbqrzyhxcxaqpvcqt5belwvsuxaxsutyad.onion

image

I'm not sure whether this is a parsing error, just wanted to point it out to try and help find a resolution.

Parser for Bailan Group

The parser for Bailan group doesn't work well with - (comma) or ' (single quote). Check the recent posts :

2022-09-03 | s
2022-08-30 | LLC
2022-08-30 | group

I suggest to replace the parse line with

sed -n '/<a href="\/companies\//,/<\/a>/p' source/bianlian-*.html | egrep -o "([A-Za-z0-9 ,\'.-])+</a>" | cut -d '<' -f 1 | sed -e '/Contacts/d'

Remove parser for part1/2/3... and add only new posts from Clop

Clop parser is monitoring all the new posts about part1/2/3... however it's not really monitoring when a new ransomware attack occurred. I think it makes more sense to get the list of companies from the top of the page and not the posts about parts being published.

Per example, last entry with the current parser was added 2023-03-16, but according to my other monitors, this attack was already listed two days ago, on 2023-03-14.

This issue is open to discussion, but having the new attacks monitored instead the files being published tend to make more sense (on all the other groups it's not monitoring the new files added, only the new victims added).

Regex for the parser:
grep 'g-menu-item-title' source/clop-*.html --no-filename | sed -e s/'<span class="g-menu-item-title">'// -e s/"<\/span>"// -e 's/^ *//g' -e 's/[[:space:]]*$//' -e 's/^ARCHIVE[[:digit:]]$//' -e s/'^HOW TO DOWNLOAD?$'// -e 's/^ARCHIVE$//' -e 's/^HOME$//' -e '/^$/d'

There was already a similar issue #18 and this parser above would solve the /stats too.

date count error on homepage

current date 24/3/23 but site shows

πŸͺ there have been 794 posts within the last 90 days

🏚 there have been 744 posts within the year of 2023

impossible!

new group: Horsemagyar

host location

Horsemagyar

group name

Horsemagyar

group information

Horsemagyar

host

v3 (onion)

parser

No response

new group: unsafeleak

host location

unsafeipw6wbkzzmj7yqp7bz6j7ivzynggmwxsm6u2wwfmfqrxqrrhyd.onion

group name

unsafeleak

group information

aggregation site / leak platform

host

v3 (onion)

parser

No response

new node: snatch

host location

snatch.press

group name

snatch

group information

No response

host

clearnet

parser

No response

Play

host location

http://mbrlkbtq5jonaqkurjwmxftytyn2ethqvbxfu4rgjbkkknndqwae6byd.onion

group name

Play

group information

On Jun 22, 2022, in the BleepingComputer forum, someone wrote that his files were encrypted with the extension β€œPlay.” Afterward, Trend Micro published an analysis article about the new ransomware variant, Play Ransomware.
Even though they seem like a new ransomware group, their identified TTPs look like Hive and Nokayawa ransomware families. One of the similar behaviors that make them look similar are they use AdFind, a command-line query tool capable of collecting information from Active Directory.

host

v3 (onion)

parser

grep -oP '(?<=\\"\\").*?(?=div)' source/play-*.html | tr -d '<>' | tr -d \\'  | grep -v \?\?

new group: monti

host location

mblogci3rudehaagbryjznltdp33ojwzkq6hn2pckvjq33rycmzczpid.onion

group name

monti

group information

No response

host

v3 (onion)

parser

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.