Ransomware Industry Analysis w/Deepseek
I have built quite a few tools utilizing TI and ransomware feeds. Even built a bunch of scrapers to gather the information on my own.
One great site/project I keep checking out is Ransomlook (https://www.ransomlook.io/).
They sum it up pretty well “RansomLook is an open-source project aimed at assisting users in tracking ransomware-related posts and activities across various sites, forums, and Telegram channels.”
The data they provide is super valuable, you can see which companies got hit with Ransomware almost right away. However company names can only provide so much value. To the average person they won’t care which companies got hacked, what they may care about is industry and location.
I am going to take the information their API gives, and try to get Deepseek to identify which industry the victim is in.
The data
The first step is to get the posts from the Ransomlook API, they have a super simple GET route that returns JSON with each Ransomware Group as a key, and the value is an array of “Posts”
The code
It could not be easier to get this into our code (I am using bun so I have global await)
const allData = await fetch('https://www.ransomlook.io/api/export/2').then((data)=>data.json())
Each post looks like this:
{
post_title: "Browdy (bl.local)",
discovered: "2025-01-13 21:42:37.586562",
description: "Founded in 2002, FisherBroyles, LLP is a full-service law firm with offices acro...",
link: "/leaks/67856c6105a779c3d3ce311b",
magnet: null,
screen: "screenshots/lynx/Browdy (bllocal).png",
},
Next I went over to the Deepseek platform page, prepaid 20 bucks and got my API key: https://platform.deepseek.com
Whats really funny is that you can just use the OpenAI Library and change the base URL to be deepseek. LinkedIn went crazy for that but it’s been a very common practice for 3rd party AI tools.
Here is their boilerplate for Node.js and compatable runtimes, super simple:
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: 'https://api.deepseek.com',
apiKey: '<DeepSeek API Key>'
});
async function main() {
const completion = await openai.chat.completions.create({
messages: [{ role: "system", content: "You are a helpful assistant." }],
model: "deepseek-chat",
});
console.log(completion.choices[0].message.content);
}
main();
The Prompt
Now we need to write the prompt, its very important to be specific and restrictive to ensure you get the output you want.
One important note is if you are adding JSON into the prompt, make sure to JSON.stringify(YOURJSONOBJ), otherwise all that added is [object Object]
Something that I noticed is if I would try to get it to just output industry, it would get too specific and would change depending on the case.
You can see an example in its thought process here:
The victim, mulfordconstruction.com, with the description “Heavy Civil Contracting, Earthwork and Utilities,” belongs to the construction industry, specifically within the civil engineering and heavy construction sector. This includes activities related to infrastructure development, such as roads, bridges, utilities, and earthwork.
So I force it to distingish between general industry and niche
Which industry does the victim belong to?
Return the following JSON format/data:
{
general_industry: //The general overall industry,
niche_industry //The niche in the general industry the victim belongs too
}
{
"general_industry": "Construction",
"niche_industry": "Heavy Civil Contracting, Earthwork and Utilities"
}
Look at that ^!!! Its looking pretty good already.
Now I don’t need to use the chain-of-thought model as that costs more money and is probably overkill.
Persisting the data
At first I didn’t want to do any database, but then I figured why not do Sqlite. Its natively supported by Bun, and will also make sure I can insert one record at a time.
Ill save the analysis for next time but here is my full code for now:
import OpenAI from "openai";
import { Database } from "bun:sqlite";
const db = new Database("mydb.sqlite");
const openai = new OpenAI({
baseURL: 'https://api.deepseek.com',
apiKey: '<deepseek-api>'
});
const allData = await fetch('https://www.ransomlook.io/api/export/2').then((data) => data.json())
db.query(`CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_title TEXT NOT NULL,
description TEXT,
general_industry TEXT,
niche_industry TEXT,
group_name TEXT
);`).run()
const stmt = db.query(`INSERT INTO posts (post_title, description, general_industry, niche_industry, group_name)
VALUES ($post_title, $description, $general_industry, $niche_industry, $group_name);`)
for (const group of Object.keys(allData)) {
for (const post of allData[group]) {
const completion = await openai.chat.completions.create({
response_format: { type: 'json_object' },
messages: [{
role: "system", content: `You are a doing analysis on ransomware victims to identify which industry they belong in, you have the following details
${JSON.stringify({
post_title: post.post_title,
description: post.description
})
}
-------
Which industry does the victim belong to?
Return the following JSON format/data:
{
general_industry: //The general overall industry,
niche_industry //The niche in the general industry the victim belongs too
}
`
}],
model: "deepseek-chat",
});
try {
const thisOutput = JSON.parse(completion.choices[0].message.content)
console.log(post.post_title)
stmt.run(
{
$post_title: post.post_title,
$description: post.description,
$general_industry: thisOutput.general_industry,
$niche_industry: thisOutput.niche_industry,
$group_name: group
}
)
} catch (e) {
console.log("This one didnt work", post.post_title)
}
}
}